#つぶやきProcessing で気になった作品を p5.js Web Editor で動かしてみる 【その2】

以前、以下のようなことをやりましたが、その第二弾です。

●#つぶやきProcessing で気になった作品を p5.js Web Editor で動かそうとしてみる【 #GWアドベントカレンダー 2021/5/2 】 - Qiita
　https://qiita.com/youtoy/items/0806ba53db59261da3f8

今回、動かすだけなら Processing用の処理を書いていたもの以外は何も書きかえる必要がなかったので、プログラムを短く書くために工夫された箇所をばらすような形で書きかえをしてみたのですが、 #つぶやきProcessing用の記法を知ることができました。

## つぶやきProcessing で見かけた作品
今回、p5.js　で実装してみるものは、以下の5つです。

### 1つ目
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/%E3%81%A4%E3%81%B6%E3%82%84%E3%81%8DProcessing?src=hash&amp;ref_src=twsrc%5Etfw">#つぶやきProcessing</a> 「はじめてのp4」<br><br>float f=9e3,n;<br>void setup(){<br>size(500,500);<br>}<br>void draw(){<br> clear();<br> noStroke();<br> for(n=0;n&lt;30;n++){<br> fill(255,int(128*(1+sin(f/40+n))));<br> circle(500/PI*acos(cos(f*noise(n)/30)),500-500*abs(sin(f*noise(n,9)/40)),40);<br> }<br> f++;<br>} <a href="https://t.co/tb4yq1PwqX">pic.twitter.com/tb4yq1PwqX</a></p>&mdash; Snow Esamosc (@SnowEsamosc) <a href="https://twitter.com/SnowEsamosc/status/1425809876186406918?ref_src=twsrc%5Etfw">August 12, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### 2つ目
<blockquote class="twitter-tweet"><p lang="fr" dir="ltr"><a href="https://twitter.com/hashtag/%E3%81%A4%E3%81%B6%E3%82%84%E3%81%8DProcessing?src=hash&amp;ref_src=twsrc%5Etfw">#つぶやきProcessing</a> 「噴水」<br><br>f=0<br>draw=_=&gt;{<br>f||createCanvas(500,500)<br>background(0)<br>colorMode(HSB,2)<br>noStroke()<br>for(n=0;n&lt;60;n++){<br>F=(f+n*23)%300<br>g=int(F/300)*9<br>fill(1+sin(n),2,2,1.5)<br>circle(250+F*(noise(n,g)-.5)*9,500-11*noise(n,g,9)*F+F*F/30,n*(1-g%2*.5))<br>}<br>f+=2<br>} <a href="https://t.co/KEIw7ymbyO">pic.twitter.com/KEIw7ymbyO</a></p>&mdash; Snow Esamosc (@SnowEsamosc) <a href="https://twitter.com/SnowEsamosc/status/1425436058032893959?ref_src=twsrc%5Etfw">August 11, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### 3つ目
ツイート埋め込みに失敗したので、画像とリンクで。

https://twitter.com/sh_sys_/status/1426180663112192003
![ああ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/1b120bae-7b38-349d-e642-b75279163716.jpeg)

### 4つ目
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">t=0<br>draw=_=&gt;{t++||createCanvas(W=600,W)<br>N=noise;B=blendMode;colorMode(HSB);B(BLEND);background(0,.1);B(ADD)<br>for(i=0;i&lt;300;i+=.5){n=t-i;x=N(1,n)*2-1;y=N(2,n)*3+2;<br>fill(N(3,n)*60,80,W/2-i,.5);rect(W/2+x*i*1,W-y*i*1+i**2*.01,4)}}<a href="https://twitter.com/hashtag/%E3%81%A4%E3%81%B6%E3%82%84%E3%81%8DProcessing?src=hash&amp;ref_src=twsrc%5Etfw">#つぶやきProcessing</a><a href="https://twitter.com/hashtag/p5js?src=hash&amp;ref_src=twsrc%5Etfw">#p5js</a> <a href="https://t.co/wAUDHxKEtH">pic.twitter.com/wAUDHxKEtH</a></p>&mdash; Akira (@akira2768922) <a href="https://twitter.com/akira2768922/status/1425826606182854671?ref_src=twsrc%5Etfw">August 12, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### 5つ目
<blockquote class="twitter-tweet" data-conversation="none"><p lang="en" dir="ltr">t=0<br>draw=_=&gt;{t||createCanvas(W=720,W)<br>t++<br>colorMode(HSB)<br>blendMode(BLEND)<br>background(0,.02)<br>blendMode(ADD)<br>noStroke()<br>for(y=0;y&lt;W;y+=180)for(x=-9;x&lt;W+9;x+=2)fill((x/4+y/2)%360,75,W,.1)+square(x+noise(x/99,t/9)*6-3,(t+y+noise(x/W,y,t/W)*W)%720,4)}<a href="https://twitter.com/hashtag/%E3%81%A4%E3%81%B6%E3%82%84%E3%81%8DProcessing?src=hash&amp;ref_src=twsrc%5Etfw">#つぶやきProcessing</a> <a href="https://t.co/1lGGSOp8mS">pic.twitter.com/1lGGSOp8mS</a></p>&mdash; はぅ君 (@Hau_kun) <a href="https://twitter.com/Hau_kun/status/1425086932296605700?ref_src=twsrc%5Etfw">August 10, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## p5.js で実装しなおしてみる
### 変更した内容
1つ目のもの（Processing用に書かれたもの）以外は、そもそも何も書きかえなくても p5.js Web Editor で動きました。
そのため、ツイート用に短く書くための工夫がされた部分を、少しばらして書きかえたりしてみました。

以下に書きかえた部分について、主なものを箇条書きで記載します。

- 1つ目のもの： 
   - `void setup()` と `void draw()` という Processing用の関数を `function setup()` と `function draw()` という p5.js用の関数に書きかえ、
   - 変数の指定を `float` から `let` に変更し、
   - `clear();` の後に `background(0);` を追加
- 4つ目：
   - 変数 t を `frameCount` に変更
- 1つ目・2つ目： 
   - フレームレートのデフォルト値が元の作品と異なっていそうだったため、 `frameRate(30);` という指定を追加（※ `function setup()` 内）。
- 複数のものに共通： 
   - `colorMode();` や `noStroke();` などで、動的な変更が行われないものは、 `function setup()` 内に記載
   - キャンバスのサイズ指定で W という変数を使っていた部分を、数値での指定と `width` を利用する形に変更

上記の書き換えをやっていく中で、 #つぶやきProcessing のために工夫された部分が見られて、とても興味深かったです！

### 1つ目の書き換え版

```javascript
let f = 9e3,
  n;

function setup() {
  createCanvas(500, 500);
  frameRate(30);
  noStroke();
}

function draw() {
  clear();
  background(0);
  for (n = 0; n < 30; n++) {
    fill(255, int(128 * (1 + sin(f / 40 + n))));
    circle(
      (500 / PI) * acos(cos((f * noise(n)) / 30)),
      500 - 500 * abs(sin((f * noise(n, 9)) / 40)),
      40
    );
  }
  f++;
}
```

![1つ目.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/858510e1-8ede-0f1a-fc4d-2bc49b24e867.jpeg)

### 2つ目の書き換え版

```javascript
f = 0;

function setup() {
  createCanvas(500, 500);
  frameRate(30);
  colorMode(HSB, 2);
  noStroke();
}

function draw() {
  background(0);
  for (n = 0; n < 60; n++) {
    F = (f + n * 23) % 300;
    g = int(F / 300) * 9;
    fill(1 + sin(n), 2, 2, 1.5);
    circle(
      250 + F * (noise(n, g) - 0.5) * 9,
      500 - 11 * noise(n, g, 9) * F + (F * F) / 30,
      n * (1 - (g % 2) * 0.5)
    );
  }
  f += 2;
}
```

![2つ目.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/080022eb-b651-3688-b677-a56d09704baf.jpeg)

### 3つ目の書き換え版

```javascript
t = 0;

function setup() {
  createCanvas(640, 640)
  noFill();
  strokeWeight(5);
}

function draw() {
  background((sin(t) + 1) * 128);
  stroke((cos(t) + 1) * 128);
  translate(width / 2, width / 2);
  for (r = 0; r < 90; r += 9) {
    arc(20, 20, r * 6, r * 9, asin(cos((u = (PI / 180) * r + t))), sin(u));
    rotate(asin(cos(t)));
  }
  t += PI / 180;
}
```

![3つ目.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/7c05311e-dd9a-e9af-49cc-d46fc663a607.jpeg)

### 4つ目の書き換え版

```javascript
function setup() {
  createCanvas(600, 600);
}

function draw() {
  colorMode(HSB);
  blendMode(BLEND);
  background(0, 0.1);
  blendMode(ADD);
  for (i = 0; i < 300; i += 0.5) {
    n = frameCount - i;
    x = noise(1, n) * 2 - 1;
    y = noise(2, n) * 3 + 2;
    fill(noise(3, n) * 60, 80, width / 2 - i, 0.5);
    rect(width / 2 + x * i * 1, width - y * i * 1 + i ** 2 * 0.01, 4);
  }
}
```

![4つ目.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/ac00abc2-4656-6175-b298-6c5114243235.jpeg)

### 5つ目の書き換え版

```javascript
t = 0;

function setup() {
  createCanvas(720, 720);
  colorMode(HSB);
}

function draw() {
  t++;
  blendMode(BLEND);
  background(0, 0.02);
  blendMode(ADD);
  noStroke();
  for (y = 0; y < width; y += 180)
    for (x = -9; x < width + 9; x += 2)
      fill((x / 4 + y / 2) % 360, 75, width, 0.1) +
        square(
          x + noise(x / 99, t / 9) * 6 - 3,
          (t + y + noise(x / width, y, t / width) * width) % 720,
          4
        );
}
```

![5つ目.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/b325d2d0-0836-6558-54c6-14f8047206ce.jpeg)

## まとめ
p5.js Web Editor上で動かすだけなら、Processing用に書かれた 1つ目以外は、全く変更なく動かすことができました。

そこで、プログラムを短く書くために工夫された箇所をばらすような形で書きかえてみましたが、例えば以下のような工夫があるということを知ることができました。

- サイズ指定と変数の加算の短縮の合わせ技： `t||createCanvas(W=720,W)`
- 複数回登場する関数名の短縮： `N=noise; B=blendMode;` と `B(BLEND);background(0,.1);B(ADD)` や `N(2,n)*3+2;` など
- アロー関数と引数指定による短縮： `draw=_=>{...}`

短いプログラムで、素敵な作品ができているのもビックリですが、上記のような工夫を駆使してツイート内にプログラムをおさめてしまうというのも驚かされました（それも、ハッシュタグの分は少なくなる文字数で）。