p5.js と reveal.js でブラウザで動くインタラクティブなプレゼンを作る

この記事は，[Processing Advent Calendar 2019](https://qiita.com/advent-calendar/2019/processing)の 20日目です
昨日の記事は， @reona396  さんの，[p5.jsとp5.speechで音声合成と音声認識](http://blog.livedoor.jp/reona396/archives/55812545.html)でした

# はじめに

p5.js は，ブラウザ上でインタラクティブな表現をすることができます．
reveal.jsは， お手軽にプレゼンを作ることのできるフレームワークです
どちらもjsで動作しているという点から，この2つを組み合わせればブラウザ上で動作するインタラクティブなプレゼンを作ることができるはずです．
そこで今回は，reveal.js，特にmarkdownでスライドを書きやすくした vscodeの拡張機能である [vscode-reveal](https://marketplace.visualstudio.com/items?itemName=evilz.vscode-reveal) で，p5.js を併用する方法を紹介します

# vscode-reveal でプレゼンを作ってみる

- 以下のようなmarkdownファイルを作ってみます

```slide.md
# Processing Advent Calander 2019

---

- reveal.js を使うと

--

- こんなスライドを作ることができます

```

VSCode でコマンドパレットを開いて， `Revealjs: Open presentation in browser` を選ぶと，ブラウザで表示できます

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170422/1286c04a-b955-146d-1ca8-8895d16b6866.gif)

# p5.js を埋め込む
htmlの iframe 機能を利用して，revealのスライド内にp5のキャンバスを埋め込みます

```slide.md
---

## p5.js を使う

---

- このようにスライドの中に p5 を埋め込むこともできます

<iframe src="1.html" class="canvas"></iframe>

```

```1.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <link rel="stylesheet" href="./p5style.css" />
    <script src="p5.min.js"></script>
    <script src="main.js"></script>
  </head>
</html>

```

```p5style.css
* {
  padding: 0;
  margin: 0;
  background: transparent;
}

canvas {
  display: block;
}
```

p5.jsのコードは省略します
([アドカレ9日目の記事](https://qiita.com/WGG_SH/items/e4c12fb6ff62d2502fbd) で作成した弾幕のコードを使いまわしています)

実行結果は次のようになります

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170422/dbac4004-680f-7756-ef57-e3bcb059361f.gif)


# キャンバスサイズを大きくする
今のままでは，p5のキャンバスサイズが小さくて扱いづらいので
サイズを大きくします．
しかし， iframe p5側の設定やp5を動かすhtmlファイルのスタイルではこの問題を解決できないので，revealに使用されているスタイルを変更していきます

## cssファイルを持ってくる
reveal.js でデフォルトで使用されているcssファイルは https://github.com/hakimel/reveal.js/blob/master/css/theme/ にあります
今回はこの中でデフォルト値とされている`black.css` を使用します

cssファイルをコピーして，名前を適当に変えます (変えなくても本当は大丈夫)
今回は `custom.css` としました

そして，markdownの先頭に以下を追記します

```slide.md
---
customTheme: 'custom' 
---
```

`custom` の部分にcssのファイル名を入れてください

これで，オリジナルのスタイルを適用できるようになります


## p5 のキャンバスサイズを変える

以下のスタイルを追加します
(`!important`) を使っているのは，reveal側にスタイルを強制的に書き換えられるため多少強引ですがこうしています

```custom.css
.canvas {
  max-width: 100% !important;
  max-height: 100% !important;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  padding: 0;
  margin: 0;
  position: fixed;
  background-color: transparent;
}

iframe {
  border: none;
}

.reveal .slides {
  height: auto !important;
  width: auto !important;
}


```

また，以下の部分に `height: 100%` も追加します

```custom.css
.reveal .slides section,
.reveal .slides section > section {
  line-height: 1.3;
  font-weight: inherit;
}
```

これで，以下のようになります

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170422/719e5b41-8dd2-7463-61bd-fe75332c59d1.gif)

## 文字が消えた
文字がp5キャンバスの後ろに隠れてしまったので見えなくなりました
文字とp5との共存をできるようにするには，p5の描画で背景色を透明にする必要があります (z-indexを書き換える方法は一度試したのですがうまくいきませんでした)

これを解決するためには，p5側のコードを少し弄ります

先のコードでは `update()` の中で `background(0)` を呼んでいたのですが， `clear()` に変えます

すると，下のようにp5とスライドの文字が両方表示できます

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170422/35b0b1ad-ecd2-7f51-98c3-9f75399aea8f.gif)


とはいえこの方法では背景が透明であることが前提になってしまうので，表現に制限がかかってしまいそうです...

また，文字の高さが変わった件については，元々中央揃えで上から描画するようになっていたものを，強引に`height: 100%` にしたためで，必要に応じて `top` などを弄ってください


# 終わりに

今回は，ブラウザで動くプレゼンを作る reveal.js でp5 を利用する話を書きました．
もしLTなど発表の機会がありましたら是非活用してみてください