我试图使用context.clip()从其他弧中剪辑一个绘制弧,并填充剪裁的结果。但是当我剪辑并填充它时,它会给出像素化的填充。
var ctx = document.getElementById("canvas").getContext("2d");
var x = 150 ;
var y = 150 ;
var r = 100 ;
ctx.save() ;
ctx.translate(x,y) ;
ctx.beginPath() ;
ctx.arc(0,0,r,0,2*Math.PI);
ctx.closePath() ;
ctx.fillStyle = "cyan" ;
ctx.fill() ;
ctx.lineWidth = 10;
ctx.stroke();
ctx.restore() ;
ctx.save() ;
ctx.clip() ;
ctx.translate(x,y);
ctx.beginPath();
ctx.moveTo(r,-r-10);
ctx.arc(0,-r-10,r,0,Math.PI*2);
ctx.closePath();
ctx.fillStyle = "#f2f2f2";
ctx.fill();
ctx.lineWidth = 1;
ctx.stroke();
ctx.restore();发布于 2016-06-30 14:29:34
另一种消除对clip()/save()/restore()的需求的方法是使用几个合成步骤。
剪辑掩码在一些浏览器中是反别名的,而在另一些浏览器中则不是。为了获得一致性(在某些情况下也是性能,因为保存剪辑恢复是相对昂贵的操作),最好使用组合(如果可能)。
在这种情况下:
destination-out并填充(将剪切主)source-atop和笔画(将大纲剪裁)source-over和主圆笔画轮廓示例
Update:简化步骤(最后一步合并到流程中,参考)。(评论)。我还选择了演示Path2D的使用,因为我们可以重用对象而不干扰普通上下文上的路径-
var ctx = c.getContext("2d"),
p = new Path2D(), // this will store main shape for reuse
x = 75, y = 75, radius = 70;
// main arc
p.arc(x, y, radius, 0, 6.28); // store to path object
ctx.fillStyle = "cyan";
ctx.fill(p); // fill path object
// clip top arc
ctx.globalCompositeOperation = "source-atop";
ctx.arc(x, y - radius, radius, 0, 6.28);
ctx.fillStyle = "#09f";
ctx.fill();
ctx.lineWidth = 5;
ctx.stroke();
// stroke main arc
ctx.globalCompositeOperation = "source-over";
ctx.stroke(p); // stroke path objectbody {background:#e9e9e9}<canvas id=c></canvas>
旧版本:
var ctx = c.getContext("2d"),
x = 75, y = 75, radius = 70;
// main arc
ctx.arc(x, y, radius, 0, 6.28);
ctx.fillStyle = "cyan";
ctx.fill();
// clipping arc
ctx.beginPath();
ctx.arc(x, y - radius, radius, 0, 6.28);
// cut step
ctx.globalCompositeOperation = "destination-out";
ctx.fill();
// stroke gap step
ctx.globalCompositeOperation = "source-atop";
ctx.lineWidth = 10;
ctx.stroke();
// stroke whole outline
ctx.globalCompositeOperation = "source-over";
ctx.beginPath();
ctx.arc(x, y, radius, 0, 6.28);
ctx.lineWidth = 5;
ctx.stroke();
// if you want to color the clip then use this:
ctx.globalCompositeOperation = "destination-atop";
ctx.fillStyle = "#09f";
ctx.fill();body {background:#e9e9e9}<canvas id=c></canvas>
发布于 2016-06-30 12:59:13
问题是,剪辑边界没有被反制。
要解决这个问题,您可以不使用剪辑来呈现形状。ctx.arc方法允许您设置起始角和结束角,这样您就可以通过填充两个弧来获得嵌入。
你需要得到夹子圆和内嵌圆截取的角度。
在这种情况下,情况非常简单。首先得到圆圈之间的距离,以及从一个到另一个的角度。这只适用于两个半径相同的圆。
var c = {x:?,y:?}; // circle one location
var c1 = {x:?,y:?}; // circle two location
var radius = ?; // radius of both
var angle = Math.atan2(c1.y - c.y, c1.x - c.x); // get the angle from one to the next
var dist = Math.hypot(c1.x - c.x, c1.y - c.y); // get the distance. NOTE IE does not have hypot so do it the normal way with Math.sqrt....现在有角度和距离,拦截是距离和半径之间的一个简单的关系。
var iAngle = Math.acos(dist / 2 / radius); // the angle from the line between the circles
// to the intercepts现在你有了这个角度,你可以画出两个弧线
ctx.beginPath();
ctx.arc(c.x,c.y,radius,angle - iAngle , angle + iAngle); // first arc
ctx.arc(c1.x,c1.y, radius, angle + Math.PI - iAngle, angle + Math.PI + iAngle); // second arc
ctx.fill();
ctx.stroke();没有什么你可以做的,以防止锯齿影响剪辑区。另一种实现剪辑的方法是使用ctx.globalCompositeOperation来呈现掩码。你可以屏蔽进出,还有更多的选择。当裁剪区域变得更加复杂时,这将是一个更好的解决方案。
发布于 2016-06-30 13:10:26
我终于想出了纠正错误的正确方法。这是我想要的https://jsfiddle.net/x0d0n40z/6/的干净的结果
代码:
var ctx = document.getElementById("canvas").getContext("2d");
var r = 50
x = ctx.canvas.width/2;
y = ctx.canvas.height/2;
var offset = 60;
ctx.save();
ctx.setTransform(1,0,0,1.5,x,y);
ctx.beginPath();
ctx.arc(0,0,r,0,2*Math.PI);
ctx.stroke();
ctx.clip();
ctx.beginPath();
ctx.arc(0,0,r,0,2*Math.PI,false);
ctx.fillStyle = "cyan";
ctx.fill();
ctx.setTransform(1, 0, 0, 1, x, y);
ctx.beginPath();
ctx.arc(0,-offset,r,0,2*Math.PI,false);
ctx.fillStyle = "#f2f2f2";
ctx.fill();
ctx.lineWidth = 1 ;
ctx.stroke();
ctx.setTransform(1,0,0,1.5,x,y);
ctx.beginPath();
ctx.arc(0,0,r,0,2*Math.PI,false);
ctx.lineWidth = 3 ;
ctx.stroke();
ctx.restore();资料来源:我学会使用剪辑:http://www.html5canvastutorials.com/advanced/html5-canvas-clipping-region-tutorial/
https://stackoverflow.com/questions/38121679
复制相似问题