SVG遮罩和边界框

3
我需要将遮罩应用于不同的对象。遮罩应该覆盖整个对象(可见部分)。我将遮罩放在页面顶部的一个特定位置内,将maskContentUnits更改为objectBoundingBox,这样它就可以完美地工作了。
但是随之出现了一个问题。
我制作了一个fiddle来说明这个问题:http://jsfiddle.net/8qdt7vjr/1/
<body>
    <svg width="0" height="0">
        <defs>
            <mask id="mask1" maskContentUnits="objectBoundingBox">
                <ellipse cx=".5" cy=".5" rx=".5" ry=".5" fill="white" />
            </mask>
        </defs>
    </svg>
    <svg class="svg" width="200" height="150" overflow="visible">
        <rect x="-50" y="-50" width="350" height="250" fill="none" stroke="green" stroke-width="2" />
        <svg id="zzz" x="0" y="0" width="100%" height="100%" overflow="visible" mask="url(#mask1)">
            <rect x="-50" y="-50" width="350" height="250" fill="blue" fill-opacity=".3" />
        </svg>
        <rect width="100%" height="100%" fill="red" fill-opacity=".1" stroke="red" stroke-width="1" />
    </svg>
</body>

在这个fiddle中,我想将遮罩应用到具有id="zzz"的svg元素上。但在此元素内部有一个矩形元素,它增加了zzz的边界框大小。在fiddle中,它是矩形元素,但在我的项目中,它是一个图像标签。zzz的溢出设置为隐藏(在fiddle中我将其更改为可见,以便更容易看到问题),因此我只能看到zzz内的特定部分。
真正的问题是zzz的内部内容会增加zzz的边界框大小。在fiddle中,我希望椭圆形遮罩位于红色矩形内(可见的zzz区域),但实际上却位于绿色矩形内(zzz的边界框)。
因此,主要问题是:是否有任何方法可以实现这个目标?遮罩将被许多具有不同大小和内容的元素使用,我不想复制它。
有没有办法在不克隆每个元素中的遮罩的情况下完成此操作? 有没有办法缩小边界框以匹配可见区域? 有没有办法显示图像的一部分而不扩展父元素的边界框? 还有其他方法吗?

第二和第三部分的答案都是否定的。这使得回答第一和第四种情况变得相当困难。 - Robert Longson
1个回答

0

你是想要实现类似这样的功能吗?

<body>
    <svg width="0" height="0">
        <defs>
            <mask id="mask1" maskContentUnits="userSpaceOnUse">
                <ellipse cx="100" cy="75" rx="100" ry="75" fill="white" />
            </mask>
        </defs>
    </svg>
    <svg class="svg" width="200" height="150" overflow="visible">
        <rect x="-50" y="-50" width="350" height="250" fill="none" stroke="green" stroke-width="2" />
        <svg id="zzz" x="0" y="0" width="100%" height="100%" overflow="visible" mask="url(#mask1)">
            <rect x="-50" y="-50" width="350" height="250" fill="blue" fill-opacity=".3" />
        </svg>
        <rect width="100%" height="100%" fill="red" fill-opacity=".1" stroke="red" stroke-width="1" />
    </svg>
</body>

也许使用userSpaceOnUse而不是objectBoundingBox可以帮助您实现所需的效果...结合嵌套的SVG元素,您可以定义要使用的用户空间以及应用遮罩的部分...

这是我现在使用的方法。但在我的情况下,我不知道具有“mask”标记的“svg”的尺寸。实际上,有几个不同的元素具有相同的遮罩。我现在为每个元素使用原始遮罩的克隆,并且我想避免克隆。 - lazyeugene
userSpaceOnUse是应用遮罩的元素的坐标系,而不是它来自哪里的坐标系。在您的情况下,它将是zzz的父SVG元素。 也许您可以提供一个例子,其中userSpaceOnUse无法正常工作? - Holger Will
无法正确地将遮罩应用于两个元素:zzz1zzz2。使用maskContentUnits="objectBoundingBox"可以轻松完成,但是块内容扩展的边界框存在问题。 - lazyeugene
嗯,我在考虑使用userSpaceOnUse结合mask内的百分比值。据我的理解,这些百分比应该相对于引用<mask>元素的元素的用户坐标系,但不幸的是,这并没有像这样实现 :-( - Holger Will
1
是的,根据帮助文档,人们可能会认为在使用“mask”属性引用掩码的元素中,内部掩码使用坐标系。不幸的是,要么是我的英语太差了,无法正确理解帮助文档,要么是帮助文档本身有误。掩码内容使用定义掩码的位置的坐标系。可以很容易地进行测试:http://jsfiddle.net/lazyeugene/wq1gg29j/ 因此,要将单个掩码应用于许多不同的元素,我需要在这些元素内部克隆它,以便掩码将使用元素的坐标系来处理百分比值。 - lazyeugene

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接