obnizのdisplayにp5jsを表示させる

# 環境
[obniz](https://obniz.io) ファームウェア2.2.0
[p5js](http://p5js.org/) v0.8.0

# 目標
どちらもプロトタイプなどで利用されていて，ビジュアルに強いp5jsとディスプレイが付いているobnizの相性は抜群なのではないか
そのobnizのディスプレイにp5jsを表示させたい！！
![obniz-p5js.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76572/1fb82f2b-9c4b-b9f5-6e34-69f25ae6769f.jpeg)


# 実装
サンプルでディスプレイ内を左右に跳ね返るボールを描きました
画面端で跳ね返るかobnizのスイッチを左右に動かしてボールを操作するものです

コードは２つありますが，共通してエラーになってしまう可能性があります
理想実行み順として．．．
1. obnizインスタンス化
2. p5jsのsetup関数実行(createCanvas実行)
3. obnizのonconnect，p5jsのcontextを取得

だいたいこの実行順になりますが，保証はされてなさそうなやつです
また，p5jsではobnizがクラウドに接続できてない場合もあるのでsetup関数では一部の機能が使えません
(例えばobniz.display.widthなどが使えない)

今回はこれらをobnizの開発者コンソール画面から実行しています
[obnizコンソール](https://obniz.io/ja/console)

## p5jsをそのまま利用できるパターン
参考：https://obniz.io/ja/doc/sdk/doc/display
このドキュメント内のdraw項目を参考にし，obnizのrepeatを利用し毎回p5jsのcanvasを描画しているものです
p5jsのcreateCanvasで作られるcanvasは自動的に「p5Canvas」というクラスが付与されるのでそれを利用し取得しています
利点
- p5jsのコードの変更ほぼなし
欠点
- obnizのrepeatのフレームレートが遅いのか，描画がガタつく

``` html:index.html
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.js"></script>
    <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
    <script src="https://unpkg.com/obniz@2.2.0/obniz.js" crossorigin="anonymous"></script>
  </head>
  <body>

    <div id="obniz-debug"></div>

    <script>
      var obniz = new Obniz("<YOUR_ID>");

      obniz.onconnect = async function () {

        //少しガタつく
         const ctx = $(".p5Canvas")[0].getContext('2d');
         obniz.repeat(function(){
           obniz.display.draw(ctx);
         });

        obniz.switch.onchange = function(state) {
          if (state === "right") {
            spx=1;
          }
          else if(state === "left") {
            spx=-1;
          }
        }
      }
      
      let x=0;
      let spx=1;
      async function setup() {
        createCanvas(64, 32);
      }

      function draw() {
        x+=spx;
        if(x < 0 || width < x)  spx = -spx;

        background(255);
        ellipse(x, 16, 5, 5);
      }
    </script>
  </body>
</html>
```

## 描画スムーズパターン
参考：https://github.com/processing/p5.js/wiki/p5.js-overview
今度はp5js側でcontextを取得し，draw関数内で描画を行っています
利点
- 描画がスムーズ
- 理想実行順の2,3が保証されている(obnizのonconnectでp5jsのcanvasを取得しているわけではないので)
- noCanvas()を利用すればPC画面上の表示を省略可能
欠点
- p5jsのコードに変更が必要
- drawの基本の60fpsで描画するとちょっと負荷がきついかも

``` html:index.html
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.js"></script>
    <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
    <script src="https://unpkg.com/obniz@2.2.0/obniz.js" crossorigin="anonymous"></script>
  </head>
  <body>

    <div id="obniz-debug"></div>

    <script>
      var obniz = new Obniz("<YOUR_ID>");

      obniz.onconnect = async function () {
        obniz.switch.onchange = function(state) {
          if (state === "right") {
            spx=1;
          }
          else if(state === "left") {
            spx=-1;
          }
        }
      }
      
      let p5ctx;
      let x=0;
      let spx=1;
      async function setup() {
        let p5 = createCanvas(64, 32);
        p5ctx = p5.canvas.getContext('2d');
        // noCanvas();  //PC画面上の描画を省略
      }

      function draw() {
        if(obniz.connectionState !== "connected") {
          return;
        }
        
        x+=spx;
        if(x < 0 || width < x)  spx = -spx;

        background(255);
        ellipse(x, 16, 5, 5);
        
        // obniz draw
        obniz.display.draw(p5ctx);
      }
    </script>
  </body>
</html>
```

# 実行してみた結果
それぞれ実行してみた動画をとろうとしたときに描画スムーズパターンの表示がバグってしまいました．．．
テストのときはよかったのですが．．．逆にその様子もあえて動画にしてみました
動画の後ろは自分が以前に作ったp5っぽいものを入れてあります
元はこれです
https://tkyk.net/#/garally
https://www.openprocessing.org/sketch/693238
https://www.openprocessing.org/sketch/699238

[![https://youtu.be/wPWSGlboP2o](http://img.youtube.com/vi/wPWSGlboP2o/0.jpg)](http://www.youtube.com/watch?v=wPWSGlboP2o)



さて，ビジュアルに強いと最初のことに言っていたp5jsを利用してみましたが，やはり
- 画面，解像度が小さすぎる
- 白黒
- 描画が60fps以下(60fpsでやると調子が悪い)
今まで作ったp5jsをそのまま表示ってのは違う用途ですね
obnizに合わせたものがよいという最初に考えれば当たり前なところに落ち着いたかもしれません