我有一个带有多个圆圈的画布,并且想像 1 一样抚摸它们。
如你所见,都是他们自己画的
context.beginPath();
context.fillStyle = "#F9F8F3";
context.arc(0, height/6*4, width/6, 0, Math.PI*2);
context.arc(width/6*1.9, height/6*4.45, width/6*1.25, 0, Math.PI*2);
context.arc(width/6*3.75, height, width/6, 0, Math.PI*2);
context.arc(width/6*5.5, height/6*4, width/5, 0, Math.PI*2);
context.stroke();
如果您只需要轮廓的视觉表示。
您可以画两次圆圈来获得轮廓,而不是进行所有复杂的数学运算。
第一次用笔划的颜色填充圆圈,并且半径半笔划宽度大于圆圈的半径。
然后设置全局复合操作来清除像素。
ctx.globalCompositeOperation = "destination-out";
然后用小于圆半径的描边宽度一半的半径填充每个圆(清除像素)。
记得将复合操作恢复为默认值。
绘制 10 个随机圆圈的轮廓。
;(()=>{
const TAU = Math.PI * 2;
const ctx = canvas.getContext("2d");
const rI32 = (min, max) => (max - min) * Math.random() + min | 0;
const Circle = (x, y, rad) => ({x, y, rad});
const circles = [];
const strokeWidth = 2;
const strokeStyle = "#000";
circles.push(
Circle(rI32(0, 512), rI32(0, 256), rI32(50, 90)),
Circle(rI32(0, 512), rI32(0, 256), rI32(50, 90)),
Circle(rI32(0, 512), rI32(0, 256), rI32(50, 90)),
Circle(rI32(0, 512), rI32(0, 256), rI32(50, 90)),
Circle(rI32(0, 512), rI32(0, 256), rI32(50, 90)),
Circle(rI32(0, 512), rI32(0, 256), rI32(50, 90)),
Circle(rI32(0, 512), rI32(0, 256), rI32(50, 90)),
Circle(rI32(0, 512), rI32(0, 256), rI32(50, 90)),
Circle(rI32(0, 512), rI32(0, 256), rI32(50, 90)),
Circle(rI32(0, 512), rI32(0, 256), rI32(50, 90)),
);
function draw(cirs, style, width) {
ctx.fillStyle = style;
ctx.beginPath();
for (const c of cirs) {
ctx.moveTo(c.x + c.rad + width * 0.5, c.y);
ctx.arc(c.x, c.y, c.rad + width * 0.5, 0, TAU);
}
ctx.fill();
ctx.globalCompositeOperation = "destination-out";
ctx.beginPath();
for (const c of cirs) {
ctx.moveTo(c.x + c.rad - width * 0.5, c.y);
ctx.arc(c.x, c.y, c.rad - width * 0.5, 0, TAU);
}
ctx.fill();
ctx.globalCompositeOperation = "source-over";
}
draw(circles, strokeStyle, strokeWidth);
})();
canvas { border: 2px solid black; }
<canvas id="canvas" width="512" height="256"></canvas>