为什么用椭圆而不是圆弧
虽然您没有包含 CSS,但当使用 CSS 调整画布元素的大小时,画布绘图会变形。 html5 画布的默认大小为 300x150,因此使用 CSS 调整其大小会拉伸或挤压后续绘图,除非 CSS 将画布大小调整为与其原始 2:1 比例完全成比例。
因此,如果您想调整画布大小,请直接更改元素的大小:
var canvas3=document.getElementById("drawing3");
canvas3.width=400;
canvas3.height=300;
为什么beginPath 有用(必不可少!)
context.clip 始终作用于最后一组路径命令,一组路径命令应该以context.beginPath 开头。所以是的,剪辑应该总是以 context.beginPath 开头。
为什么beginPath 有用(总是使用它!): 如果您发出多组路径命令而不用 beginPath 开始每组,那么每个新组也将执行所有以前的组。您的路径将只是一张长图,而不是不同的图。
修复相互关联的圈子
context.arc 是画布路径绘制命令。
路径命令将始终连接(用一条线)出现在context.beginPath 和context.stroke or context.fill 之间的所有绘图。
但是您可以使用context.moveTo 命令“拿起铅笔并将其移动到下一个圆心”的路径。这将防止您的圈子相互连接。
// pick up the pencil and move it to the next arc's centerpoint
ct.moveTo(x,y);
// and draw the arc around the centerpoint
ct.arc(x,y,r,0,Math.PI*2,false);
以下是重构为在弧之间“拿起铅笔”的代码:
var canvas3=document.getElementById("drawing3");
var ct=canvas3.getContext("2d");
ct.beginPath();
arcAtXY(50,80,30);
arcAtXY(120,40,60);
arcAtXY(180,40,30);
arcAtXY(240,40,30);
ct.clip();
ct.fillStyle="yellow";
ct.fillRect(10,10,400,200);
ct.fillStyle="magenta";
ct.font = "40px sans-serif";
ct.fillText("what's this?",30,70);
function arcAtXY(x,y,r){
ct.moveTo(x,y);
ct.arc(x,y,r,0,Math.PI*2,false);
}
canvas{border:1px solid red;}
<canvas id="drawing3" width=300 height=300></canvas>
与您的设计没有直接关系的额外想法
如果您想描边圆而不是填充它们,您将移动到下一个圆的周长而不是它的中心点。移动到中心点会导致从中心点到周边绘制一条自动线。
function arcAtXY(x,y,r){
ct.moveTo(x+r,y);
ct.arc(x,y,r,0,Math.PI*2,false);
}