【问题标题】:SVG: Apply fill color to "masked" image on hoverSVG:在悬停时将填充颜色应用于“蒙版”图像
【发布时间】:2014-01-20 03:32:28
【问题描述】:

我正在使用clipPath 对图像应用不同的“蒙版”效果。

如何在悬停时用颜色填充剪裁的图像?我尝试在 CSS 中使用 :hover,但这似乎不起作用,除非我定位到不正确的元素。

我在这个项目中使用的是 jQuery,所以如果需要 JS 解决方案,我可以依靠 jQuery。

这是我正在使用的 HTML:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100">
  <defs>
    <clipPath id="ellipse">
      <ellipse cx="50" cy="35.5" rx="49.5" ry="35" />
    </clipPath>
    <clipPath id="hexagon">
      <polygon points="25, 0  75, 0 100, 43.30127018922193 75, 86.60254037844386  25, 86.60254037844386  0, 43.30127018922193"/>
    </clipPath>
    <clipPath id="rectangle">
      <rect x="0" y="0" width="100" height="70"></rect>
    </clipPath>
  </defs>
  <g>
    <image preserveAspectRatio="none" x="0" y="0" width="100%" height="100%" xlink:href="http://upload.wikimedia.org/wikipedia/commons/thumb/b/bf/Bucephala-albeola-010.jpg/800px-Bucephala-albeola-010.jpg" id="clippy" clip-path="url(#hexagon)">
  </g>
</svg>

【问题讨论】:

    标签: javascript jquery css svg


    【解决方案1】:

    您可能希望使用滤镜效果在悬停时为图像添加一些颜色 (see Tinkerbin):

    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100">
      <style type="text/css">
        image:hover {
          filter:url(#Matrix);
        }
      </style>
      <defs>
        <clipPath id="ellipse">
          <ellipse cx="50" cy="35.5" rx="49.5" ry="35" />
        </clipPath>
        <clipPath id="hexagon">
          <polygon points="25, 0  75, 0 100, 43.30127018922193 75, 86.60254037844386  25, 86.60254037844386  0, 43.30127018922193"/>
        </clipPath>
        <clipPath id="rectangle">
          <rect x="0" y="0" width="100" height="70"></rect>
        </clipPath>
        <filter id="Matrix" filterUnits="objectBoundingBox" 
                x="0%" y="0%" width="100%" height="100%">
          <feColorMatrix type="matrix" in="SourceGraphic"
               values="1 0 0 0 .5 
                       .1 .9 0 0 0 
                       .1 0 .9 0 0 
                       0 0 0 1 0"/>
        </filter>
      </defs>
      <g>
        <image preserveAspectRatio="none" x="0" y="0" width="100%" height="100%" xlink:href="http://upload.wikimedia.org/wikipedia/commons/thumb/b/bf/Bucephala-albeola-010.jpg/800px-Bucephala-albeola-010.jpg" id="clippy" clip-path="url(#hexagon)">
      </g>
    </svg>
    

    编辑:关于过滤器的一些解释:

    应用的滤镜会改变每个光栅像素的颜色。它取其原始颜色值,将&lt;feColorMatrix&gt;指定的矩阵应用于颜色向量,得到的颜色向量成为显示颜色。

    矩阵是如何工作的?

    矩阵由四行组成。第一行计算新的红色分量,第二行计算绿色分量,第三行计算蓝色分量,第四行计算 alpha。

    每行的五个数字是什么意思?第一个数字乘以原始颜色的红色分量,第二个乘以绿色,第三个蓝色,第四个 alpha。将所有四个乘积相加,并将行中的第五个值也相加(作为不依赖于任何原始颜色分量的常数)。

    让我们看一下上面的例子:假设我们有一个灰色像素,其颜色值如下

    rgba(25%,25%,25%,1)
    

    产生的红色值是多少?计算红色值的第一行是

    1 0 0 0 .5
    

    我们计算如下:

      1*r   + 0*g   + 0*b   + 0*a + .5
    = 1*.25 + 0*.25 + 0*.25 + 0*1 + .5 = .75
    

    这意味着,生成的像素的红色分量为 75%。其他成分的计算方法类似。

    【讨论】:

    • Thomas W 干得好。我没有意识到你可以纯粹用 CSS 来做这件事。太棒了!
    • Thomas W,太好了。谢谢你。乍一看,计算&lt;feColorMatrix&gt; 值看起来有点复杂。您知道任何可以帮助解决此问题的工具吗?也许可以粘贴十六进制值或 rgb 值并生成矩阵?
    • @ctrlaltdel:为了自动生成feColorMatrix 的值,您实际上需要五个颜色对,每个颜色对由一个“原始”颜色和它映射到的颜色组成矩阵。 (至少这是我在相当疲倦时所确信的。也许我应该在更清醒的时候再考虑一下。)我编辑了这个问题以包含有关矩阵的更多信息。
    【解决方案2】:

    不确定这是否正是您想要的。鼠标事件不会发送到剪贴区之外的区域。又快又脏,在 IE9 中工作,例如在 FF 中没有测试过。

    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100">
        <script type="application/ecmascript">
            function fillit(evt) {
                document.getElementById('fillarea').setAttribute('display', 'visible');
            }
    
            function emptyit(evt) {
                document.getElementById('fillarea').setAttribute('display', 'none');
            }
        </script>
        <defs>
            <clipPath id="ellipse">
                <ellipse cx="50" cy="35.5" rx="49.5" ry="35" />
            </clipPath>
            <clipPath id="hexagon">
                <polygon points="25, 0  75, 0 100, 43.30127018922193 75, 86.60254037844386  25, 86.60254037844386  0, 43.30127018922193" />
            </clipPath>
            <clipPath id="rectangle">
                <rect x="0" y="0" width="100" height="70"></rect>
            </clipPath>
        </defs>
        <g>
            <image preserveAspectRatio="none" x="0" y="0" width="100%" height="100%" 
                   xlink:href="http://upload.wikimedia.org/wikipedia/commons/thumb/b/bf/Bucephala-albeola-010.jpg/800px-Bucephala-albeola-010.jpg" 
                   id="clippy" clip-path="url(#hexagon)" onmouseover="fillit(evt)" />
            <rect x="0" y="0" width="100%" height="100%" fill="red" display="none" 
                  id="fillarea" clip-path="url(#hexagon)" onmouseout="emptyit(evt)" />
        </g>
    </svg>
    

    【讨论】:

      猜你喜欢
      • 2015-01-12
      • 2015-08-16
      • 2021-03-13
      • 1970-01-01
      • 2023-03-04
      • 2015-11-24
      • 2021-11-24
      • 1970-01-01
      • 2019-05-30
      相关资源
      最近更新 更多