如何使用 CSS 剪辑路径剪辑画布?
Posted
技术标签:
【中文标题】如何使用 CSS 剪辑路径剪辑画布?【英文标题】:How to clip canvas with CSS clip-path? 【发布时间】:2013-07-09 18:58:47 【问题描述】:我知道我可以通过使用getContext('2d')
创建路径并设置globalCompositeOperation
来剪辑画布。
我注意到,有时我可以在其他浏览器(我使用的是 Chrome)上使用 -webkit-clip-path
或 clip-path
剪辑画布,但有时我无法:
使用此 html:
<canvas width="300" height="60"></canvas>
和 CSS:
canvas
-webkit-clip-path: polygon(50% 33%, 75% 10%, 80% 80%, 60% 75%, 40% 60%, 20% 10%, 40% 20%, 50% 33%);
产生这个:
这似乎是正确的。
但是,我注意到,如果我改变画布的高度,它就无法剪辑:
<canvas width="300" height="250"></canvas>
产生:
我的假设 是,它在浮点上裁剪(百分比在像素之间而不是像素上裁剪)有问题,但是从百分比更改为像素坐标不会裁剪。
*这里分别是他们的jsfiddle页面的链接:
http://jsfiddle.net/bozdoz/hMTgc/ http://jsfiddle.net/bozdoz/5H2Y2/有谁知道为什么一个有效而另一个无效?
是否有一种稳定 的方式来使用 CSS 剪辑画布元素,或者我是否需要使用画布上下文方法?
我问的原因是我想尽可能少用js。我有一串坐标,可以很容易地放入 css;而要使用 ctx.beginPath()...ctx.moveTo()...ctx.lineTo()...ctx.lineTo()...
方法,我需要对这些点执行 for 循环。
另外,我很好奇为什么第一个示例有效,如果有人可以解释的话。谢谢! :)
【问题讨论】:
【参考方案1】:剪辑路径相对较新,可能容易出错(在 Aurora 中对我不起作用)。
为了获得稳定的结果,我建议只使用画布的clip()
方法(您不需要为此合成)。
您可以通过这种方式提供分数(此处为百分比):
var path = [50, 33, 75, 10, 80, 80, 60, 75, 40, 60, 20, 10, 40, 20, 50, 33];
几乎就像在 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();
结果:
DEMO HERE
(剪辑是在绘制操作发生之前设置的)。
只需将您的绘图操作放在一个函数中,您也可以在调整窗口大小时调用该函数(如上面的演示所示)。
更新
至于抗锯齿:实际上对图像应用了抗锯齿,但由于红色,很难检测到它,具体取决于屏幕类型,也许浏览器。放大版:
【讨论】:
谢谢肯。这是一个很好的工作示例。我实际上打算避免使用clip()
方法,以便我可以获得具有抗锯齿的多边形(更平滑的边缘,就像 CSS 会给出的那样):jsfiddle.net/bozdoz/TB9rX 知道为什么我的第一个示例有效但其他示例没有?
@bozdoz 我只能推测,但这似乎是一个错误。如果在应用剪辑后调整元素大小,则剪辑似乎丢失了。您可以通过使用 JS 重新应用 css-class 来进行测试:document.getElementById('canvas').className = 'canvas';
(当然您需要更改 CSS 以便规则为 class)。
@bozdoz 关于抗锯齿:试试这条线:context.translate(0.5, 0.5);
更新小提琴:jsfiddle.net/AbdiasSoftware/CmaUy/2(答案中的图像确实有抗锯齿,但红色可能很难根据屏幕类型查看)。
我认为它因浏览器而异:***.com/questions/9536257/…【参考方案2】:
我从未使用过-webkit-clip-path:
,但作为一种解决方法,我会尝试将剪辑路径应用于包含画布而不是画布本身的元素。
<div class='canvas-wrapper'><canvas></canvas></div>
.canvas-wrapper
display: table; /* shrinkwrap around canvas */
-webkit-clip-path: ...;
【讨论】:
以上是关于如何使用 CSS 剪辑路径剪辑画布?的主要内容,如果未能解决你的问题,请参考以下文章
javascript - 如何使用 drawImage/putImageData 进行剪辑
css 剪辑路径形状不适用于 ie 或者我如何使用 css 创建它