为什么我的SVG路径在Chrome、Edge和Firefox中意外地被截断了?

为什么我的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图像代码:

<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%中,你似乎已经选择了任意的数字,我更喜欢精确的,所以我计算了精确的最小掩码界限。我的第二个注释可以用另一个笔来解释:代码>遮罩元素有帮助,但添加填充形状的目的是调整对象边界框的大小。这似乎与您修改后的答案相矛盾,您在其中声明“遮罩的内容未被考虑”。显然,掩码会迭代应用于其每个内容形状,透明内容可用于修改行为。