p5.js でパターンの繰り返しを CanvasRenderingContext2D のメソッド「createPattern()」でシンプルに試す（drawingContext と createGraphics() を使って）

## はじめに
MDN の CanvasRenderingContext2D のメソッドを眺めていて気になった「[createPattern()](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/createPattern)」。
それを、p5.js で drawingContext を通して使えるかを試して、以下のような描画が行えたので、その手順をメモとして残してみます。

**アニメーションのキャプチャ**
![createPattern()での描画（静止画）](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/1cac6ac8-bd80-f755-df3c-5af5ad6db512.png)

**アニメーションの動画**
<iframe width="560" height="315" src="https://www.youtube.com/embed/IyYDpu29or8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

## createPattern() について
今回使った createPattern() は、[MDN のページ](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/createPattern)では、以下のサンプルが掲載されていました。
![createPattern()を使ったサンプル](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/1c0129c9-452b-7811-a68b-c178e3ae6b4d.png)

```javascript:JavaScript のプログラムの部分
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

const img = new Image();
img.src = "canvas_createpattern.png";
// Only use the image after it's loaded
img.onload = () => {
  const pattern = ctx.createPattern(img, "repeat");
  ctx.fillStyle = pattern;
  ctx.fillRect(0, 0, 300, 300);
};
```

繰り返しの元になっている画像は、以下のようです。
![繰り返しの元画像](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/81277075-a883-edcd-1e23-458a46645021.png)

これを見た時、CanvasRenderingContext2D のメソッドなどの部分を `drawingContext.createPattern(●●, "repeat")` とか、 `drawingContext.fillStyle` という記載にして、 ctx.fillRect() は p5.js の rect()　を使えばできてしまうかな、と思いました。

そして、実際にシンプルな内容で試してみたら、最終的に思った通りにできました！

### p5.js で使おうとしてみる：その1
ここから、試した手順について記載します。

#### エラーが出た話
その p5.js でのお試しをした時、最初に createPattern() の 1つ目の引数に指定するための画像を、適当なやり方で準備して指定していたらエラーが出ました。具体的には以下のエラーで、そのメッセージの中では 1つ目の引数に指定できるものが列挙されていました。

> TypeError: Failed to execute 'createPattern' on 'CanvasRenderingContext2D': The provided value is not of type '(CSSImageValue or HTMLCanvasElement or HTMLImageElement or HTMLVideoElement or ImageBitmap or OffscreenCanvas or SVGImageElement or VideoFrame)'.

- 指定できるもの
   - CSSImageValue
   - HTMLCanvasElement
   - HTMLImageElement
   - HTMLVideoElement
   - ImageBitmap
   - OffscreenCanvas
   - SVGImageElement
   - VideoFrame

#### エラーメッセージを見て思ったこと
当初用意した画像を使った描画をエラーを出さずに行えるよう修正をしようかとも思ったのですが、このリストに出てきている内容を見て「OffscreenCanvas」があるのが目にとまり、 **これは createGraphics() で作った p5.Renderer の canvas を指定できそうだし、それをやってみるのが面白そうでは？** と思いました（それで、パターンの元をアニメーションさせるように作れそう、と思い）。

### p5.js で使おうとしてみる：その2
そして、試してみて出来上がったのが冒頭のアニメーションです。

以下が実際のプログラムです。
繰り返しパターンの元にしているのは 50x50 のサイズのオフスクリーンキャンバスです。その背景は透明で、「左上 25x25 のサイズのエリアと、右下 25x25 のサイズのエリアには、それぞれ、白色と、黒から白へと時間変化する色の矩形」を描画しています。

```javascript:sketch.js
let pg;
let pattern;

function setup() {
  createCanvas(600, 500);

  pg = createGraphics(50, 50);
  pg.noStroke();
}

function draw() {
  background(220);

  pg.fill(255)
  pg.rect(0, 0, 25, 25);
  pg.fill(frameCount % 255);
  pg.rect(25, 25, 25, 25);

  pattern = drawingContext.createPattern(pg.canvas, "repeat");
  drawingContext.fillStyle = pattern;

  rect(0, 0, width, height);
}
```

その元になったオフスクリーンキャンバスを、以下の部分で繰り返し描画されるように指定しています。

```javascript
  pattern = drawingContext.createPattern(pg.canvas, "repeat");
  drawingContext.fillStyle = pattern;
```

そして、そのパターンを描画する範囲は `rect(0, 0, width, height)` として、画面全体となるようにしています。

## おわりに
今回、CanvasRenderingContext2D のメソッド「createPattern()」を p5.js で使い、繰り返しパターンの描画を行ってみました。

今回の「createPattern()」の第2引数は「repeat」にしてみましたが、「repeat-x」や「repeat-y」として一方向のみにすることもできるようなので、これも何か良い感じに使えないかなと思っています。
![第2引数の指定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/be28dc6d-a160-f0ec-244d-203522168fe7.png)