为什么我的SVG路径在Chrome、Edge和Firefox中意外地被截断了?
考虑以下SVG图像代码:为什么我的SVG路径在Chrome、Edge和Firefox中意外地被截断了?,svg,Svg,考虑以下SVG图像代码: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000"> <title>Clipped Path Problem Demo</title> <g id="group:image"> <defs> <mask id="mask"> <re
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000">
<title>Clipped Path Problem Demo</title>
<g id="group:image">
<defs>
<mask id="mask">
<rect id="rectangle:inset" x="250" y="134" width="500" height="732" fill="white"/>
</mask>
</defs>
<g id="group:curves" mask="url('#mask')">
<!-- <rect id="rectangle:filler.shape" width="1" height="1" fill="transparent"/> -->
<path id="path:curves" d="
M 441 327
c -85 88 -85 175 -85 175
c 0 88 85 175 85 175
s 90 103 90 103
c 85 88 85 175 85 175" fill="transparent" stroke="black" stroke-width="73"/>
</g>
</g>
<g id="group:guides">
<rect id="rectangle:guide.area:inset" x="250" y="134" width="500" height="732" fill="transparent" stroke="black" stroke-dasharray="20 10" stroke-width="1"/>
</g>
</svg>
裁剪路径问题演示
(CodePen:(我为画笔添加了一个height=“500px”
属性,使其更适合屏幕。)
弯曲路径的左侧被剪裁为垂直线,即使遮罩的大小远远超过包含该部分图像所需的大小
如果我在屏蔽的g
元素中插入任意大小的非零维形状,如XML注释中的1×1透明矩形,则剪裁的边将神奇地松开
我认为这是一个bug,除了它发生在Chrome(62)、Edge(41)和Firefox开发者版(58 Beta 4)中。我想知道的是,为什么会发生这种看似荒谬的剪辑
(注意:在弯曲路径的底部进行剪裁是有意的。)由于遮罩对颜色和alpha通道值起作用(这是一种潜在的昂贵操作),因此它不会延伸到无限远,但默认情况下,渲染会在遮罩元素的对象边界框处进行剪裁,每个方向加上10%(由边界框单位中的属性
x、y、width、height
定义)
对象边界框的定义不包括笔划宽度。您已经超过了这些限制,至少需要对遮罩的x
和width
属性进行调整
由于这似乎不直观,应用遮罩的一般算法如下所示:
元素的x,y,width,height
属性给出的矩形。如果默认情况下,maskUnits
属性给出为,则坐标由应用遮罩的元素的属性确定。遮罩的内容为未考虑。该坐标系中的0和1是遮罩元素及其所有子体的连接边界框的最小值和最大值maskContentUnits=“userSpaceOnUse”
,这意味着将遮罩元素绘制到同一坐标系中
解决了裁剪路径问题
谢谢。问题是路径的宽度是260个单位,遮罩只考虑其填充框。默认的-10%遮罩插入,遮罩在填充框外绘制26个单位,这不足以容纳填充框外36.5个单位(50%)的笔划。我需要一个-14.039%(0-36.5÷260)的遮罩插入宽度为128.078%(1+36.5÷260*2)以适应笔划。填充形状解决了这个问题,因为它在将左上角坐标设置为0,0时修改了对象边界框。这似乎是适应作为遮罩一部分的笔划的唯一策略(与遮罩内容相反)而不是位于掩码的外部边界(一个掩码似乎在其组成的形状上迭代,并将一个-10%插图分别应用于每个,因此可以在掩模的中间剪辑……)如果笔划位于由符号创建的复合形状上,填充形状显然需要放在符号内部。谈论非直观性…我不确定我是否完全理解了你的评论,但可能存在误解。我扩展了答案。我的第一个评论只是阐述了我对你的解决方案的理解在20%和140%中,你似乎已经选择了任意的数字,我更喜欢精确的,所以我计算了精确的最小掩码界限。我的第二个注释可以用另一个笔来解释:代码>遮罩元素有帮助,但添加填充形状的目的是调整对象边界框的大小。这似乎与您修改后的答案相矛盾,您在其中声明“遮罩的内容未被考虑”。显然,掩码会迭代应用于其每个内容形状,透明内容可用于修改行为。