为啥 javascript canvas2d 剪辑需要路径?
Posted
技术标签:
【中文标题】为啥 javascript canvas2d 剪辑需要路径?【英文标题】:Why does javascript canvas2d clipping require a path?为什么 javascript canvas2d 剪辑需要路径? 【发布时间】:2016-08-17 01:49:17 【问题描述】:我为这个虫子拉了一段时间的头发。我想在画布的三个部分中渲染图像,而不允许它们重叠。基本上,我想使用canvas.getContext('2d').clip()
将图像分开。但是,只有在我绘制图像后调用 canvas.getContext('2d').beginPath()
时,剪辑才有效。
所以这不起作用(没有应用剪辑):
this.draw=function(image, cx, cy, width, height, clip)
var ctx = this.canvas.getContext('2d');
ctx.save();
ctx.rect(clip.x, clip.y, clip.width, clip.height);
ctx.clip();
ctx.fillStyle = "black";
ctx.fillRect(clip.x, clip.y, clip.width, clip.height);
ctx.drawImage(image,cx-width/2,cy-height/2,width,height);
ctx.restore();
return this;
;
但这确实:
this.draw=function(image, cx, cy, width, height, clip)
var ctx = this.canvas.getContext('2d');
ctx.save();
ctx.rect(clip.x, clip.y, clip.width, clip.height);
ctx.clip();
ctx.fillStyle = "black";
ctx.fillRect(clip.x, clip.y, clip.width, clip.height);
ctx.drawImage(image,cx-width/2, cy-height/2,width,height);
ctx.beginPath();// <------WITCHCRAFT
ctx.restore();
return this;
;
我发现beginPath()
解决了这个问题完全是个意外,我不知道为什么。谁能给我解释一下?
【问题讨论】:
不是巫术,而是您告诉上下文您正在开始一条新路径并完成旧路径的方式。顺便说一句,beginPath 应该在您创建路径之前(就在您的代码中的ctx.save()
之后)。只是运气好,因为如果您使用 ctx.arc 而不是 fillRect 它会将弧添加到剪辑中。
我仍然很困惑,在rect() 的文档中,它说子路径被标记为关闭。此外,如果我用ctx.arc(256,256,512,0,3.1416*2, true);
替换 fillRect 行,剪裁仍然有效(512x512 画布)。公平地说,如果我将它移到 save(); 之后,它仍然有效。
在很大程度上我很困惑 beginPath() 似乎穿越了时间。它不能用于剪切路径,因为已经完成了。它不能用于图像,因为它也已完成。就好像clip指令只在路径启动后才应用,但是一旦启动,它可以追溯clip调用后已经绘制的图像。
已经测试了您提供的代码,无论有没有 beginPath,它在两种情况下都有效。如果功能中的所有事物都已消除,那么该原因必须在其他地方。您必须在画布上有一个现有路径。获取上下文不会重置路径,pahs 是画布的拍子而不是上下文,基本规则始终是使用 beginPath 开始设置剪辑区域,如果你不这样做,那么如果画布不是新的,行为就会变得不可预测。跨度>
用 beginPath 开始剪辑是个好习惯吗?是的,它看起来像you're right。我想说这就是我使用w3schools 得到的结果,但mozilla 也没有提到这一点。这些有点“陷阱”让我抓狂。感谢您的帮助。
【参考方案1】:
因为剪辑需要路径?也许您在文档中错过了它。以下是 MDN 文档所说的:
Canvas 2D API 的 CanvasRenderingContext2D.clip() 方法将当前正在构建的路径变成当前的剪辑路径。
(强调我的)
之所以需要路径是因为剪贴蒙版可以是任意形状,从矩形到圆形再到皮卡丘的轮廓。
为了完整起见,以下是 W3C 规范关于 .clip()
的内容:
https://www.w3.org/TR/2dcontext/#drawing-paths-to-the-canvas
上下文。夹子() 进一步将剪切区域约束到当前路径。
【讨论】:
不是已经有路径了吗?也许您在问题中错过了它。这是代码 sn-p 所说的内容:ctx.rect(clip.x, clip.y, clip.width, clip.height);ctx.clip();
这没有帮助的原因是因为路径代码在两种情况下都存在。为了完整起见,以下是 W3C 规范对 rect()
的说明:creates a path for a rectangle以上是关于为啥 javascript canvas2d 剪辑需要路径?的主要内容,如果未能解决你的问题,请参考以下文章
为啥带有 SVG 的 CSS 剪辑路径在 Safari 中不起作用?