はじめに
MDN の CanvasRenderingContext2D のメソッドを眺めていて気になった「createPattern()」。
それを、p5.js で drawingContext を通して使えるかを試して、以下のような描画が行えたので、その手順をメモとして残してみます。
アニメーションの動画
createPattern() について
今回使った createPattern() は、MDN のページでは、以下のサンプルが掲載されていました。
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);
};
これを見た時、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 のサイズのエリアには、それぞれ、白色と、黒から白へと時間変化する色の矩形」を描画しています。
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);
}
その元になったオフスクリーンキャンバスを、以下の部分で繰り返し描画されるように指定しています。
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」として一方向のみにすることもできるようなので、これも何か良い感じに使えないかなと思っています。