我正在尝试使用 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();
最佳答案
无需使用 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>
关于javascript - 在 Canvas 中使用 Clip 会导致像素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38121679/