同名主题不适合,因为它不是一个选项:SVG遮罩的实际应用
我有兴趣将某个掩码应用于常规 html img标签,并且对掩码动画和其他不适用于问题主体的内容不感兴趣
我想将 SVG 蒙版应用于未知数量的图像,但我不明白,图像不可见,我附上代码
img {
display: block;
max-width: 100%;
}
.grid {
width: 480px;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 20px;
margin: auto;
}
.grid-item img {
mask: url(#mask);
}
<svg viewBox="0 0 155 219" width="155" height="219" style="display: none;">
<defs>
<mask id="mask" maskUnits="objectBoundingBox" maskContentUnits="objectBoundingBox">
<rect width="100%" height="100%" fill="#000" />
<circle cx="90" cy="90" r="60" fill="#fff" stroke="red" stroke-width="10"/>
<circle cx="50" cy="50" r="40" fill="#fff" stroke="red" stroke-width="10"/>
</mask>
</defs>
</svg>
<div class="grid">
<div class="grid-item">
<img src="https://images.unsplash.com/photo-1619732802548-bfa614fef77b?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=334&q=80" alt="">
</div>
<div class="grid-item">
<img src="https://images.unsplash.com/photo-1619782472846-eba4e6fb2275?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=334&q=80" alt="">
</div>
<div class="grid-item">
<img src="https://images.unsplash.com/photo-1619641046270-29a0b73d7a9f?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=334&q=80" alt="">
</div>
<div class="grid-item">
<img src="https://images.unsplash.com/photo-1619787942043-99ae128ca5c1?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=375&q=80" alt="">
</div>
<div class="grid-item">
<img src="https://images.unsplash.com/photo-1619785938189-264b15dc1694?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=334&q=80" alt="">
</div>
</div>
需要做什么才能使 CSS 中的掩码起作用?
这是我想要实现的行为
let svg = document.querySelectorAll(".grid svg");
let svgImage = document.querySelectorAll(".grid svg image");
svg.forEach(function(el) {
el.setAttribute("viewBox", "0 0 155 219");
el.setAttribute("xmlns", "http://www.w3.org/2000/svg");
});
svgImage.forEach(function(el) {
el.setAttribute("x", 0);
el.setAttribute("y", 0);
el.setAttribute("width", "100%");
el.setAttribute("height", "100%");
el.setAttribute("preserveAspectRatio", "none");
el.setAttribute("mask", "url(#mask)");
});
.mask {
position: fixed;
top: 0;
left: 0;
opacity: 0;
}
.grid {
width: 480px;
margin: 30px auto;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-gap: 20px;
}
<svg viewBox="0 0 155 219" xmlns="http://www.w3.org/2000/svg" width="155" height="219" class="mask">
<defs>
<mask id="mask">
<rect width="100%" height="100%" fill="black"></rect>
<circle cx="80" cy="120" r="60" fill="white" stroke="#c00" stroke-width="10" />
<circle cx="50" cy="60" r="40" fill="white" stroke="#c00" stroke-width="10" />
</mask>
</defs>
</svg>
<div class="grid">
<div class="grid-item">
<svg>
<image href="https://images.unsplash.com/photo-1619783534896-ae45ba5c78d8?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=334&q=80" />
</svg>
</div>
<div class="grid-item">
<svg>
<image href="https://images.unsplash.com/photo-1619732514485-2f6896f9e34c?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=334&q=80" />
</svg>
</div>
<div class="grid-item">
<svg>
<image href="https://images.unsplash.com/photo-1619732802548-bfa614fef77b?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=334&q=80" />
</svg>
</div>
<div class="grid-item">
<svg>
<image href="https://images.unsplash.com/photo-1619782472846-eba4e6fb2275?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=334&q=80" />
</svg>
</div>
</div>
我唯一想到的就是用 svg > image 替换 img 标签,这个想法是我的,但他们帮助我实现了,看起来像这样
遮罩是一种流行的操作(与剪裁一起),用于隐藏在遮罩下部分或完全不透明的元素部分。有多种方法可以进行遮罩,使用
CSS和SVG。但是,您需要了解这里存在差异。并不总是可以获得预期的结果,就像使用SVG,应用 的属性一样CSS。CSS问题的作者使用一个属性进行 maskingmask: url(#mask);,其值是指 SVG 元素。并得到以下结果:并且这个结果是意料之中的,因为该
CSS属性mask并不能完全像在 中那样工作SVG,导致<rect width="100%" height="100%" fill="#000" />SVG 元素的内容对象与图像完全重叠,所以我们看不到它。为了得到接近预期的结果,让我们创建一个包含以下内容的外部 SVG 文件:
我们将使用它作为掩码。例子:
结果与预期略有不同,因为 SVG 文件的内容元素是分开的。
如果我们使用问题作者使用的相同掩码,我们会得到以下结果:
可以看到,这里的结果又和预想的略有出入,因为SVG文件的内容元素相互重叠,从而和图片相互重叠,导致哪一部分的半透明边框变小了圆圈被切断。
结论
在这种情况下,要获得作者想要的结果,即由具有相互重叠且顶部保持可见的半透明边框的元素组成的形状,使用 SVG 遮罩更容易(及时)。然而,如果你正确地创建了一个 SVG 文件,使用任意形状而不是圆形作为元素
<circle>,那么得到想要的结果一点也不难。UPD /问题作者期望的结果:
您可以将 SVG 用作蒙版并轻松调整其大小和位置(就像使用背景图像一样)。只需确保为视图框设置正确的值:
Temani Afif 的答案的翻译