interactionCanvas = {
const noise = noise2(params);
const img = perlinImage(noise);
const { width, height } = img;
const canvas = DOM.canvas(width, height);
const ctx = canvas.getContext("2d");
let circle = mutable sampleCircle;
const refresh = () => {
ctx.clearRect(0, 0, width, height);
ctx.drawImage(img, 0, 0);
ctx.beginPath();
const n = 500;
const [x0, y0] = circle.center;
const r = circle.radius;
mutable sampleCircle = circle;
for (let i = 0; i < n; i++) {
const ang = (i / n) * Math.PI * 2;
const [cos, sin] = [Math.cos(ang), Math.sin(ang)];
const R = (noise(cos * r + x0, sin * r + y0) + 1) * r;
ctx.lineTo(x0 + cos * R, y0 + sin * R);
}
ctx.closePath();
ctx.lineWidth = 2;
ctx.strokeStyle = "orange";
ctx.stroke();
ctx.strokeStyle = "black";
ctx.lineWidth = 1;
circle.draw(ctx);
};
refresh();
let mouse;
canvas.onmousedown = (e) => {
refresh();
mouse = [e.offsetX, e.offsetY];
if (vec2.dist(mouse, circle.center) < 4) {
canvas.onmousemove = (e) => {
let newmouse = [e.offsetX, e.offsetY];
circle.center = vec2.add(
[],
circle.center,
vec2.sub([], newmouse, mouse)
);
mouse = newmouse;
refresh();
};
} else if (vec2.dist(mouse, circle.borderPoint) < 4) {
canvas.onmousemove = (e) => {
let newmouse = [e.offsetX, e.offsetY];
circle.borderPoint = vec2.add(
[],
circle.borderPoint,
vec2.sub([], newmouse, mouse)
);
mouse = newmouse;
refresh();
};
}
};
canvas.onmouseup = () => {
canvas.onmousemove = null;
};
return canvas;
}