我正在尝试使用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();
答案 0 :(得分:2)
无需clip()
/ save()
/ restore()
的替代方法是使用合成的几个步骤。
在某些浏览器中,剪切蒙版是消除锯齿的,而在其他浏览器中则没有。为了获得一致性(在某些情况下还有性能,因为保存 - 剪辑 - 恢复是相对昂贵的操作),如果可能的话,首选使用合成。
在这种情况下:
destination-out
并填充(将剪切主要)source-atop
和笔划(将轮廓切割)source-over
并描绘主圆的轮廓 更新:简化步骤(最后一步合并到流程中,参考评论)。我还选择演示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 object
body {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>
答案 1 :(得分:0)
问题是剪辑边界没有被反对。
要解决此问题,您可以在不使用剪辑的情况下渲染形状。 ctx.arc方法允许您设置开始和结束角度,以便通过填充两个弧来获取插入。
您需要获取剪辑圆和插入圆截取的角度。
对于这种情况,它非常简单。首先得到圆之间的距离,以及从一个到另一个的角度。这仅适用于两个半径相同的圆。
http://getbootstrap.com/customize/
现在你有了角度和距离,截距是距离和半径之间的简单关系
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.globalCompositeOperation渲染蒙版。您可以屏蔽进出,以及更多选项。当裁剪区域变得更复杂时,这将是更好的解决方案。
答案 2 :(得分:0)
我终于找到了纠正错误的正确方法。 继承了我想要的清晰结果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/