javascript - 在 Canvas 中使用 Clip 会导致像素

标签 javascript canvas html5-canvas

我正在尝试使用 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();

https://jsfiddle.net/x0d0n40z/1/

最佳答案

无需使用 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/

相关文章:

javascript - HTML Canvas 意外改变颜色

javascript - HTML5 Canvas 文本编辑

javascript - 如何在 javaScript 中使用特定键对对象进行分组

javascript - 具有异步初始化的单例

javascript - JS Canvas 动画,我的效果是加速和累加,但是效果的速度在控制台是一样的吗?

android - ViewFlipper:在 View 上绘制 Canvas

math - 如何在平面上随机但均匀地分布节点

javascript - chrome.browserAction.setIcon - 下载的图像

javascript - 如何在不同的 url angularjs 上更改类名

javascript - 在数据表初始化方法中访问数据属性的最简洁方法是什么