Processingで作った作品を，Processingで作ったプレゼンスライドで動かす

# はじめに
Processingで作った作品を，Processingで作ったプレゼンスライドに**そのまま**埋め込んでプレゼンしたくないですか？
本記事で実現したいと思います．
ここでいう**「プレゼンスライド」**は，記事[Processingで作るプレゼンスライド][1]で作ったものを指します．
[1]:https://qiita.com/ohayota/items/d79e0acb54f594eb2721

こんなのを作ります．
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Processingで作ったスライドに作品を埋め込むことができた（4ページ目） <a href="https://t.co/fFtBqLiINz">pic.twitter.com/fFtBqLiINz</a></p>&mdash; ohayota (@ohayoooota) <a href="https://twitter.com/ohayoooota/status/1205765667690958848?ref_src=twsrc%5Etfw">December 14, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# プレゼンスライドのソースコード
今回作ったプログラムをGitHubに上げています．
ご自由にお使いください．
[processing-slide][2]
[2]:https://github.com/ohayota/PresentationSlideProcessing

# 実装
[Processingで作るプレゼンスライド][1]のプログラムに，クラスを追加実装して実現しようと思います．
（全クラスに微変更を加えています．GitHubに上げているプログラムをご参照ください．）

## Canvasクラスの実装
作品のコードを実行する部分は，Canvasクラスとして実装します．
1作品1関数として実装したいと思います．

...そして作っておいたものがこちらです（唐突）（不親切）．

```java:Canvas.pde
class Canvas {
  
  int workNum; // 描画する作品を指定する番号
  float sizeX;
  float sizeY;
  float x;
  float y;
  color back;
  boolean isBaseDrew = false;
  
  // work1用の変数
  float[] r = {750, 750, 750};
  
  Canvas(int workNum, float sizeX, float sizeY, float x, float y, color back) {
    this.workNum = workNum;
    this.sizeX = sizeX;
    this.sizeY = sizeY;
    this.x = x;
    this.y = y;
    this.back = back;
  }
  
  void resetValues() {
    isBaseDrew = false;
    // work1用の変数初期化
    for(int i = 0; i < r.length; i++) r[i] = 750;
    // work2用の変数初期化...
  }
  
  // 透明な円を重ねていく
  void work1() {
    noStroke();
    if (r[0] > 0) {
      float randomX = random(-sizeX/6, sizeX/6);
      float randomY = random(-sizeY/6, sizeY/6);
      fill(255, 30);
      ellipse(randomX, randomY, r[0], r[0]);
      r[0] -= 75;
    }
    if (r[1] > 0) {
      float randomX = random(-sizeX/6, sizeX/6);
      float randomY = random(-sizeY/6, sizeY/6);
      fill(0, 0, 0, 10);
      ellipse(randomX, randomY, r[1], r[1]);
      r[1] -= 90;
    }
    if (r[2] > 0) {
      float randomX = random(-sizeX/6, sizeX/6);
      float randomY = random(-sizeY/6, sizeY/6);
      fill(228, 0, 127, 20);
      ellipse(randomX, randomY, r[2], r[2]);
      fill(0, 161, 233, 20);
      ellipse(-randomX, -randomY, r[2], r[2]);
      r[2] -= 50;
    }
  }
  
  //void work2() {
  //  // 作品のプログラムを移植する(置換: width->sizeX & height->sizeY)
  //}
  
  void drawBase() {
    fill(0);
    noStroke();
    rect(x-sizeX/2, y-sizeY/2, sizeX, sizeY);
  }
  
  void drawFrame() {
    noFill();
    strokeWeight(5);
    stroke(mainColor);
    rect(x-sizeX/2, y-sizeY/2, sizeX, sizeY);
  }
  
  void draw() {
    if (!isBaseDrew) {
      drawBase();
      isBaseDrew = true;
    }
    drawFrame();
    // 表示する作品をcaseで指定する
    pushMatrix();
    translate(x, y);
    switch(workNum) {
      case 1:
        work1();
        break;
      //case 2:
      //  work2();
      //  break;
      default:
    }
    popMatrix();
  }
  
}
```

`work1()`内に，自分で適当に書いたコードを入れておきました．
作品を1つの関数内に移植して，作品のグローバル変数を，Canvasクラスの変数として定義しました．
Canvasクラスのインスタンス生成時に指定した番号`workNum`をもとに対応する関数が呼ばれ，作品が描画されます．

## KeyEventに対応する関数の修正

従来の関数では，スライドを1回描画した直後にループを止めていました．
今回は描画を続ける必要があるので，Canvasクラスだけ描画を続けるようにしました．

```java:keyEvent.pde
void keyPressed() {
  if (!isKeyTyped) {
    // 表示していたスライドのCanvasをリセットする
    ArrayList<Canvas> canvases = slides.get(slideNum).textField.canvases;
    for (Canvas c: canvases) c.resetValues();
    switch (keyCode) {
      case LEFT:
        if (0 < slideNum) {
          loop();
          slideNum--;
        }
        break;
      case RIGHT:
        if (slideNum < slides.size()-1) {
          loop();
          slideNum++;
        }
        break;
      default:
    }
    isKeyTyped = true;
  }
  noLoop();
}

void keyReleased() {
  loop();
  isKeyTyped = false;
  isSlideDrew = false;
}
```

`isSlideDrew`でスライドが描画されたかを管理しています．

## 完成したスライド

こちらのツイートに載っている動画のように，4ページ目に作品を載せることができました（枠をオーバーしてますが）．
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Processingで作ったスライドに作品を埋め込むことができた（4ページ目） <a href="https://t.co/fFtBqLiINz">pic.twitter.com/fFtBqLiINz</a></p>&mdash; ohayota (@ohayoooota) <a href="https://twitter.com/ohayoooota/status/1205765667690958848?ref_src=twsrc%5Etfw">December 14, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 作品コード移植時の注意点

Canvasクラス内に作品のコードを元のまま移植すると，正しい位置に表示されません．
それは元のウィンドウサイズを`width`や`height`で取得しているためです．
Canvasクラス内では，`sizeX`と`sizeY`がウィンドウサイズとして対応します．

```java
// rect(0, 0, width, height);
rect(0, 0, sizeX, sizeY);
```

移植後には，移植コード内の`size()`や`background()`関数を削除してください．
`background()`の部分は`rect()`等で代用してください．

```java
// size(600, 600);
// background(0);
fill(0);
rect(0, 0, sizeX, sizeY);
```

## 現状の課題
スライドに作品を描画しましたが，枠を超えて描画された部分が隠せていません...
知見のある方にご教示いただきたいです！

# おわりに
Processingで作った作品を，Processingで作ったプレゼンスライドに埋め込んでみました．
ぜひ，プレゼンで使ってみてください！