我可以不使用 id 给 svg 元素添加遮罩吗?

6

我想为一个SVG图片分配一个SVG掩码。我可以使用掩码上的ID来实现这一点,如下所示:

<svg id="svg1" width="5cm" height="5cm" viewBox="0 0 200 200"
     xmlns="http://www.w3.org/2000/svg" version="1.1">
     <defs>
       <mask id="mask">
         <circle cx="100" cy="100" r="100" fill="white"></circle>
       </mask>   
     </defs>
     <rect x="0" y="0" width="200" height="200" fill="red" mask="url(#mask)"></rect>
</svg>

但是我希望多次加载此SVG,并在SVG标签中使用不同的ID。因此,我将生成'#mask' ID的副本。使用多个ID是无效的代码。因此,我想使用类来引用适当的遮罩。这意味着我不能使用mask=url()技术。

<svg id="svg2" width="5cm" height="5cm" viewBox="0 0 200 200"
     xmlns="http://www.w3.org/2000/svg" version="1.1">
     <defs>
       <mask class="mask">
         <circle cx="100" cy="100" r="100" fill="white"></circle>
       </mask>   
     </defs>
     <rect x="0" y="0" width="200" height="200" fill="red" mask="url(can't use this)"></rect>
</svg>

有没有一种方法可以将一个类应用于矩形元素的遮罩,而不是使用id?也许可以使用javaScript或其他我没有想到的方式。
完整的故事/背景: 我实际上正在为Joomla制作一个SVG图像幻灯片模块。这个PHP生成了一个包含JavaScript、CSS和SVG的模块。我使用JavaScript来动画化遮罩。 实际上,我已经使用唯一的ID使其工作。我只是想知道是否有一种方法可以分配遮罩给一个元素,而不是引用ID。我可能想这样做是因为我的代码变得越来越难以阅读,因为我必须对每个唯一的ID在我的JavaScript/SVG和CSS中使用一些PHP。

1
口罩始终是相同的吗?如果是,那么单独加载一次。或者为每个生成并使用不同的ID(例如从SVG元素派生)。 - jcaron
@jcaron 不,蒙版并不总是相同的。有时候它们可能相同,但并不总是如此。目前我正在使用不同的ID方法。但我认为我可能更喜欢仅更改整个SVG中的一个ID来引用它。 - Rob Monhemius
2个回答

7
不行,你只能通过id引用图案。你不能以其他方式引用SVG遮罩。

我担心情况会是这样。我会等一个星期左右再接受答案,以防有人突然提供了奇迹般的解决方案:p。如果我忘记了,请随时提醒我xD。 - Rob Monhemius
不会有奇迹般的解决方案。你可以通过阅读SVG规范来自行验证。 :) - Paul LeBeau

6
根据您的描述,我了解到您有一个相同的图形实体,希望用不同的形式多次屏蔽。请DRY写下来:

<!-- start with an invisible svg that only contains mask definitions -->
<svg width="0" height="0"
     xmlns="http://www.w3.org/2000/svg">
    <defs>
        <!-- first, you have a circular mask -->
       <mask id="circle-mask">
         <circle cx="100" cy="100" r="80" fill="white" />
       </mask>   
        <!-- then, you have a different mask, lets say a diamond -->
       <mask id="diamond-mask">
         <polygon points="100,20 180,100 100,180 20,100" fill="white" />
       </mask>   
     </defs>
</svg>

<!-- further into your document, you want to mask a rectangle -->
<svg id="svg1" width="5cm" height="5cm" viewBox="0 0 200 200"
     xmlns="http://www.w3.org/2000/svg">
     <!-- reference the circle mask -->
     <rect x="0" y="0" width="200" height="200" fill="red" mask="url(#circle-mask)" />
</svg>

<!-- with the circle again, as often as you want, nothing changes -->
<svg id="svg2" width="5cm" height="5cm" viewBox="0 0 200 200"
     xmlns="http://www.w3.org/2000/svg">
     <!-- the mask is the same, so no difference to above -->
     <rect x="0" y="0" width="200" height="200" fill="red" mask="url(#circle-mask)" />
</svg>

<!-- and now with the diamond; that one is different -->
<svg id="svg3" width="5cm" height="5cm" viewBox="0 0 200 200"
     xmlns="http://www.w3.org/2000/svg">
     <!-- if the mask changes, you need to change the reference -->
     <rect x="0" y="0" width="200" height="200" fill="red" mask="url(#diamond-mask)" />
</svg>

您还可以在样式表中引用这些掩模,并根据掩模形状为引用元素指定一个类:

.masked.circular rect {
    mask: url(#circle-mask);
}
.masked.diamond rect {
    mask: url(#diamond-mask);
}
<svg width="0" height="0"
     xmlns="http://www.w3.org/2000/svg">
    <defs>
       <mask id="circle-mask">
         <circle cx="100" cy="100" r="80" fill="white" />
       </mask>   
       <mask id="diamond-mask">
         <polygon points="100,20 180,100 100,180 20,100" fill="white" />
       </mask>   
     </defs>
</svg>

<svg id="svg1" class="masked circular" width="5cm" height="5cm" viewBox="0 0 200 200"
     xmlns="http://www.w3.org/2000/svg">
     <rect x="0" y="0" width="200" height="200" fill="red" />
</svg>

<svg id="svg2" class="masked circular" width="5cm" height="5cm" viewBox="0 0 200 200"
     xmlns="http://www.w3.org/2000/svg">
     <rect x="0" y="0" width="200" height="200" fill="red" />
</svg>

<svg id="svg1" class="masked diamond" width="5cm" height="5cm" viewBox="0 0 200 200"
     xmlns="http://www.w3.org/2000/svg">
     <rect x="0" y="0" width="200" height="200" fill="red" />
</svg>


1
那对我来说行不通。我想我应该在问题中提供更多的背景信息(我试图让问题尽可能简单)。我已经将情况添加到问题中了。感谢您的努力回答;)。 - Rob Monhemius

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