Javascript 如何使用CSS剪辑路径剪辑画布?

Javascript 如何使用CSS剪辑路径剪辑画布?,javascript,css,html,canvas,webkit,Javascript,Css,Html,Canvas,Webkit,我知道我可以通过使用getContext('2d')创建路径并设置globalCompositeOperation来剪裁画布 我注意到,有时我可以用-webkit clip path或其他浏览器上的clip path剪裁画布(我在Chrome上),有时我无法: 使用此HTML: 和CSS: 画布{ -webkit剪辑路径:多边形(50%33%、75%10%、80%80%、60%75%、40%60%、20%10%、40%20%、50%33%); } 产生以下结果: 这似乎是正确的 但是,我注意

我知道我可以通过使用
getContext('2d')
创建路径并设置
globalCompositeOperation
来剪裁画布

我注意到,有时我可以用
-webkit clip path
或其他浏览器上的
clip path
剪裁画布(我在Chrome上),有时我无法:

使用此HTML:

和CSS:

画布{
-webkit剪辑路径:多边形(50%33%、75%10%、80%80%、60%75%、40%60%、20%10%、40%20%、50%33%);
}

产生以下结果:

这似乎是正确的

但是,我注意到,如果更改画布的高度,它将无法剪裁:

产生:

我的假设是,它在浮点上剪裁有问题(百分比在像素之间剪裁,而不是在像素上剪裁),但从百分比更改为像素坐标不会剪裁

*以下是分别指向其JSFIDLE页面的链接:

有人知道为什么一个有效而另一个无效吗

有没有一种稳定的方法可以用CSS剪裁画布元素,或者我需要使用画布上下文方法

我问这个问题的原因是我希望尽可能少使用js。我有一个坐标字符串,我可以很容易地将其放入css中;然而,要使用
ctx.beginPath()…ctx.moveTo()…ctx.lineTo()…ctx.lineTo()…
方法,我需要对点执行for循环


另外,如果有人能解释的话,我很好奇第一个例子为什么有效。谢谢!:)

剪辑路径相对较新,可能会出现错误(在极光中不适用于我)

为了获得稳定的结果,我建议只使用canvas'
clip()
方法(您不需要使用composite)

您可以通过以下方式提供分数(此处为百分比):

几乎和CSS中的定义一样简单。然后使用函数对其进行解析:

function addClip(context, path) {

    var w = context.canvas.width,
        h = context.canvas.height;

    context.beginPath();
    context.moveTo(path[0] * w / 100, path[1] * h / 100);
    for(var i = 2; i < path.length; i+=2) {
        context.lineTo(path[i] * w / 100, path[i+1] * h / 100);
    }
    context.closePath();
    context.clip();
}
函数addClip(上下文,路径){
var w=context.canvas.width,
h=context.canvas.height;
context.beginPath();
context.moveTo(路径[0]*w/100,路径[1]*h/100);
对于(变量i=2;i
结果:

(在进行绘图操作之前设置剪辑)

只需将绘图操作放入一个函数中,在重新调整窗口大小时也可以调用该函数(如上面的演示所示)

更新

至于反别名:图像实际上应用了反别名,但由于红色,根据屏幕类型和可能的浏览器,很难检测到它。放大版:


我从未使用过
-webkit clip path:
,但作为一种解决方法,我会尝试将剪辑路径应用于包含画布的元素,而不是画布本身

 <div class='canvas-wrapper'><canvas></canvas></div>

谢谢你,肯。这是一个很好的例子。实际上,我打算避免使用
clip()
方法,这样我就可以得到具有抗锯齿的多边形(更平滑的边,就像CSS所给出的):知道为什么我的第一个示例有效,而其他示例无效吗?@bozdoz我只能推测,但它似乎是一个bug。如果在应用剪辑后调整元素的大小,则剪辑似乎丢失。您可以使用JS重新应用css类进行测试:
document.getElementById('canvas')。className='canvas'
(当然,您需要更改CSS以使规则为类)。@bozdoz关于抗锯齿:尝试使用以下行:
context.translate(0.5,0.5)
Updated fiddle:(答案中的图像确实有抗锯齿功能,但根据屏幕类型的不同,红色的图像可能很难看到)。我认为浏览器会有所不同:
 <div class='canvas-wrapper'><canvas></canvas></div>
 .canvas-wrapper {
    display: table;   /* shrinkwrap around canvas */
    -webkit-clip-path: ...;
 }