JavaScriptで「同心円状の催眠画像」を描きます。
// 同心円状の催眠画像を描く。
const drawConcentricCircles = (ctx, x, y, width, height, count = 4, foreColor = "black", bgColor = "yellow") => {
ctx.save();
// クリッピングする
ctx.beginPath();
ctx.rect(x, y, width, height);
ctx.clip();
// 背景を塗りつぶす
ctx.beginPath();
ctx.fillStyle = bgColor;
ctx.fillRect(x, y, width, height);
// 中央に来るように座標変換する
let cx = x + width / 2, cy = y + height / 2;
ctx.translate(cx, cy);
// 画面の大きさを考慮する。
let minxy = Math.min(width, height), maxxy = Math.max(width, height);
let avexy = (minxy + maxxy) / 2;
let dr = minxy / 20;
let f = Math.abs(Math.sin(time / 800)) * (avexy / count);
for (let odd = -1; odd < 1; ++odd) {
ctx.save();
// 同心円状にクリッピングする
ctx.beginPath();
for (let i = odd; i < count; i += 2) {
let xy = (i / count) * avexy;
let r0 = f + xy;
if (r0 > 0)
ctx.arc(0, 0, r0, 0, 2 * Math.PI, false);
let r1 = f + xy + avexy / count;
if (r1 > 0)
ctx.arc(0, 0, r1, 0, 2 * Math.PI, true);
ctx.closePath();
}
ctx.clip();
// 同心円を描く
ctx.lineWidth = dr / 2;
ctx.strokeStyle = foreColor;
let r_start = (time / 10) % dr;
for (let r = r_start; r < maxxy; r += dr) {
ctx.beginPath();
ctx.arc(0, 0, odd ? r : (maxxy - r), 0, 2 * Math.PI, true);
ctx.stroke();
}
ctx.restore();
}
ctx.restore();
};![[スクリーンショット]](/katahiromz/concentric_circles/raw/main/img/screenshot.png)