RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1276979
Accepted
Monkey Mutant
Monkey Mutant
Asked:2022-05-01 15:06:50 +0000 UTC2022-05-01 15:06:50 +0000 UTC 2022-05-01 15:06:50 +0000 UTC

在 CSS 规则中应用 SVG 掩码

  • 772

同名主题不适合,因为它不是一个选项: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>

javascript
  • 4 4 个回答
  • 10 Views

4 个回答

  • Voted
  1. Monkey Mutant
    2022-05-07T07:32:47Z2022-05-07T07:32:47Z

    我唯一想到的就是用 svg > image 替换 img 标签,这个想法是我的,但他们帮助我实现了,看起来像这样

    let images = document.querySelectorAll(".grid .item img");
    
    images.forEach(function(it) {
      it.parentNode.innerHTML = `
    <svg viewBox="0 0 155 219"  xmlns="http://www.w3.org/2000/svg">
     <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>
      <image href=" ${it.src} " width="100%" height="100%" x="0" y="0" 
      preserveAspectRatio="none" mask="url(#mask)"/>
    </svg>
      `;
    });
    .grid {
      max-width: 980px;
      display: grid;
      grid-template-columns: 1fr 1fr 1fr 1fr;
      grid-gap: 10px;
      margin: 30px auto;
    }
    <div class="grid">
      <div class="item">
        <img src="https://images.unsplash.com/photo-1619871172071-47964353b0d5?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=401&q=80" alt="">
      </div>
      <div class="item">
        <img src="https://images.unsplash.com/photo-1616425839183-c60d8f310fec?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=334&q=80" alt="">
      </div>
      <div class="item">
        <img src="https://images.unsplash.com/photo-1619059356114-b744d212faa2?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=334&q=80" alt="">
      </div>
      <div class="item">
        <img src="https://images.unsplash.com/photo-1611948018782-2a6e9c1d5ce6?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=333&q=80" alt="">
      </div>
    </div>

    • 4
  2. Best Answer
    Sevastopol'
    2022-05-09T02:43:45Z2022-05-09T02:43:45Z

    遮罩是一种流行的操作(与剪裁一起),用于隐藏在遮罩下部分或完全不透明的元素部分。有多种方法可以进行遮罩,使用CSS和SVG。但是,您需要了解这里存在差异。并不总是可以获得预期的结果,就像使用SVG,应用 的属性一样CSS。

    CSS问题的作者使用一个属性进行 masking mask: url(#mask);,其值是指 SVG 元素。并得到以下结果:

    我想将 SVG 蒙版应用于未知数量的图像,但我不明白,图像不可见

    并且这个结果是意料之中的,因为该CSS属性mask并不能完全像在 中那样工作SVG,导致<rect width="100%" height="100%" fill="#000" />SVG 元素的内容对象与图像完全重叠,所以我们看不到它。

    为了得到接近预期的结果,让我们创建一个包含以下内容的外部 SVG 文件:

    <?xml version="1.0" ?><svg role="img" viewBox="0 0 155 219" width="155" height="219" xmlns="http://www.w3.org/2000/svg">
    <circle cx="90" cy="153" r="60" fill="#fff" stroke="red" stroke-width="10" stroke-opacity="0.5" />
    <circle cx="45" cy="45" r="40" fill="#fff" stroke="red" stroke-width="10" stroke-opacity="0.5"/>
    </svg>
    

    我们将使用它作为掩码。例子:

    img {
      width: 155px;
      height: 219px;
      mask: url(https://upload.wikimedia.org/wikipedia/commons/thumb/e/e7/SVG_Mask_Circles.svg/155px-SVG_Mask_Circles.svg.png);
      -webkit-mask: url(https://upload.wikimedia.org/wikipedia/commons/thumb/e/e7/SVG_Mask_Circles.svg/155px-SVG_Mask_Circles.svg.png);
    }
    <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="">
    
    <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="">
    
    <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="">

    结果与预期略有不同,因为 SVG 文件的内容元素是分开的。

    如果我们使用问题作者使用的相同掩码,我们会得到以下结果:

    img {
      width: 155px;
      height: 219px;
      mask: url(https://upload.wikimedia.org/wikipedia/commons/e/e8/SVG_Mask_100.svg);
      -webkit-mask: url(https://upload.wikimedia.org/wikipedia/commons/e/e8/SVG_Mask_100.svg);
    }
    <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="">
    
    <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="">
    
    <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="">

    可以看到,这里的结果又和预想的略有出入,因为SVG文件的内容元素相互重叠,从而和图片相互重叠,导致哪一部分的半透明边框变小了圆圈被切断。

    结论

    在这种情况下,要获得作者想要的结果,即由具有相互重叠且顶部保持可见的半透明边框的元素组成的形状,使用 SVG 遮罩更容易(及时)。然而,如果你正确地创建了一个 SVG 文件,使用任意形状而不是圆形作为元素<circle>,那么得到想要的结果一点也不难。


    UPD /问题作者期望的结果:

    img {
      width: 155px;
      height: 219px;
      mask: url(https://upload.wikimedia.org/wikipedia/commons/0/0f/SVG_Mask_Redict.svg);
      -webkit-mask: url(https://upload.wikimedia.org/wikipedia/commons/0/0f/SVG_Mask_Redict.svg);
    }
    <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="">
    
    <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="">
    
    <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="">

    • 3
  3. Monkey Mutant
    2022-05-08T20:53:07Z2022-05-08T20:53:07Z

    您可以将 SVG 用作蒙版并轻松调整其大小和位置(就像使用背景图像一样)。只需确保为视图框设置正确的值:

    .img-container {
      width: 300px;
      height: 300px;
      background-color: lightgreen;
      margin: 5px;
    }
    
    .clipped-img {
      width: 100%;
      height: 100%;
      display: block;
      object-fit: cover;
      -webkit-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 207 167"><path d="M199.6,18.9c-4.3-8.9-12.5-16.4-22.3-17.8c-11.9-1.7-23.1,5.4-32.2,13.2c-9.1,7.8-17.8,16.8-29.3,20.3c-20.5,6.2-41.7-7.4-63.1-7.5C38.7,27,24.8,33,15.2,43.3c-35.5,38.2-0.1,99.4,40.6,116.2c32.8,13.6,72.1,5.9,100.9-15c27.4-19.9,44.3-54.9,47.4-88.6c0.2-2.7,0.4-5.3,0.5-7.9C204.8,38,203.9,27.8,199.6,18.9z"></path></svg>') center/contain no-repeat;
      mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 207 167"><path d="M199.6,18.9c-4.3-8.9-12.5-16.4-22.3-17.8c-11.9-1.7-23.1,5.4-32.2,13.2c-9.1,7.8-17.8,16.8-29.3,20.3c-20.5,6.2-41.7-7.4-63.1-7.5C38.7,27,24.8,33,15.2,43.3c-35.5,38.2-0.1,99.4,40.6,116.2c32.8,13.6,72.1,5.9,100.9-15c27.4-19.9,44.3-54.9,47.4-88.6c0.2-2.7,0.4-5.3,0.5-7.9C204.8,38,203.9,27.8,199.6,18.9z"></path></svg>') center/contain no-repeat;
    }
    <div class="img-container">
      <img class="clipped-img" src="https://picsum.photos/id/1074/800/800.jpg">
    </div>
    
    <div class="img-container" style="width:500px;">
      <img class="clipped-img" src="https://picsum.photos/id/1074/800/800.jpg">
    </div>
    
    <div class="img-container" style="width:150px;">
      <img class="clipped-img" src="https://picsum.photos/id/1074/800/800.jpg">
    </div>

    Temani Afif 的答案的翻译

    • 2
  4. Monkey Mutant
    2022-05-08T21:02:26Z2022-05-08T21:02:26Z

    img {
      display: block;
      width: 100%;
      height: 100%;
      mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 450 450"><circle cx="170" cy="140" r="80" stroke="black" stroke-width="20"/> <circle cx="250" cy="280" r="150" stroke="black" stroke-width="20"/></svg>');
      -webkit-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 450 450"><circle cx="170" cy="140" r="80"/> <circle cx="250" cy="280" r="150"/></svg>');
      --c: radial-gradient(farthest-side, #000 calc(100% - 20px), #0002 calc(100% - 8px) 99%, #0000);
      -webkit-mask: var(--c) 100% 100%/80% 80%, var(--c) 20% 20% /40% 40%;
      -webkit-mask-repeat: no-repeat;
    }
    
    html,
    body {
      margin: 0;
    }
    
    .item {
      width: 450px;
      position: fixed;
      top: 0;
      left: 0;
      z-index: -1;
    }
    
    svg {
      border: 1px solid red;
    }
    
    circle {
      fill: #fff;
      stroke: red;
      stroke-width: 30px;
    }
    <div class="item">
      <img src="https://images.pexels.com/photos/2111143/pexels-photo-2111143.jpeg?cs=srgb&dl=pexels-oratto-oficial-2111143.jpg&fm=jpg" alt="">
    </div>

    • 2

相关问题

  • 第二个 Instagram 按钮的 CSS 属性

  • 由于模糊,内容不可见

  • 弹出队列。消息显示不正确

  • 是否可以在 for 循环中插入提示?

  • 如何将 JSON 请求中的信息输出到数据表 Vuetify vue.js?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    表格填充不起作用

    • 2 个回答
  • Marko Smith

    提示 50/50,有两个,其中一个是正确的

    • 1 个回答
  • Marko Smith

    在 PyQt5 中停止进程

    • 1 个回答
  • Marko Smith

    我的脚本不工作

    • 1 个回答
  • Marko Smith

    在文本文件中写入和读取列表

    • 2 个回答
  • Marko Smith

    如何像屏幕截图中那样并排排列这些块?

    • 1 个回答
  • Marko Smith

    确定文本文件中每一行的字符数

    • 2 个回答
  • Marko Smith

    将接口对象传递给 JAVA 构造函数

    • 1 个回答
  • Marko Smith

    正确更新数据库中的数据

    • 1 个回答
  • Marko Smith

    Python解析不是css

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5