【问题标题】:Cross browser gradient mask跨浏览器渐变蒙版
【发布时间】:2016-05-13 18:16:26
【问题描述】:

我有一个背景垂直滚动的 CSS3 动画。我希望背景的顶部逐渐淡出。我在 Chrome 中使用:

-webkit-mask-box-image: -webkit-linear-gradient(transparent, black);

是否有跨浏览器的方式来实现这一点?也许使用 SVG 蒙版?甚至是设置此动画的 JavaScript 解决方案?

请看下面的示例代码:

div {
  background-image: linear-gradient(rgba(24, 49, 67, .95), rgba(24, 49, 67, .88)), url(https://static.pexels.com/photos/96380/pexels-photo-96380.jpeg);
  background-size: cover;
  position: absolute;
  width: 500px;
  height: 500px;
}
div:before {
  background: url(https://dl.dropboxusercontent.com/u/3454522/shapes1.svg);
  content: '';
  display: block;
  position: absolute;
  right: 0;
  left: 0;
  bottom: 0;
  background-size: 100%;
  height: 500px;
  animation: bgscroll 100s infinite linear;
  -webkit-mask-box-image: linear-gradient(transparent, black);
}
@keyframes bgscroll {
  100% {
    background-position: 0px -3000px;
  }
}
<div>
</div>

【问题讨论】:

    标签: css animation svg gradient


    【解决方案1】:

    跨浏览器掩码:

    是的,我们可以使用 SVG 掩码实现跨浏览器掩码。为此,我们需要将背景图像(您的形状 SVG)和蒙版放在同一个 SVG 元素上,如下面的 sn-p 所示。这部分答案适用于 Chrome、Firefox、Opera(所有最新版本)、IE11 和 Edge。它也应该在 IE9 和 IE10 中工作,因为它们支持基本的 SVG、遮罩和剪辑。

    div {
      background-image: linear-gradient(rgba(24, 49, 67, .95), rgba(24, 49, 67, .88)), url(https://static.pexels.com/photos/96380/pexels-photo-96380.jpeg);
      background-size: cover;
      position: absolute;
      width: 500px;
      height: 500px;
    }
    svg {
      position: absolute;
      right: 0;
      left: 0;
      bottom: 0;
      height: 500px;
      width: 500px;
    }
    <div>
      <svg viewBox='0 0 500 500' id='svg1'>
        <defs>
          <pattern id='bg-img' patternUnits='userSpaceOnUse' width='500' height='500' patternTransform='translate(0 3000)'>
            <image xlink:href='https://dl.dropboxusercontent.com/u/3454522/shapes1.svg' x='0' y='0' width='500' height='500' />
          </pattern>
          <linearGradient id='grad' gradientTransform='rotate(90 250 250)'>
            <stop offset='0%' stop-color='black' />
            <stop offset='100%' stop-color='white' />
          </linearGradient>
          <mask id='msk'>
            <polygon points='0,0 0,500 500,500 500,0' fill='url(#grad)' />
          </mask>
        </defs>
        <polygon points='0,0 0,500 500,500 500,0' fill='url(#bg-img)' mask='url(#msk)' />
      </svg>
    </div>

    跨浏览器遮罩动画:

    理论上,动画也可以使用SVG的patternTransform属性来实现。我们可以为pattern 元素添加translate 变换,使其模仿background-position 动画。

    var y = 3000;
    var svg1 = document.getElementById('bg-img');
    setInterval(function() {
      y = (y <= 0) ? 3000 : y - 10;
      svg1.setAttribute('patternTransform', 'translate(0 ' + y + ')');
    }, 100);
    div {
      background-image: linear-gradient(rgba(24, 49, 67, .95), rgba(24, 49, 67, .88)), url(https://static.pexels.com/photos/96380/pexels-photo-96380.jpeg);
      background-size: cover;
      position: absolute;
      width: 500px;
      height: 500px;
    }
    svg {
      position: absolute;
      right: 0;
      left: 0;
      bottom: 0;
      height: 500px;
      width: 500px;
    }
    <div>
      <svg viewBox='0 0 500 500' id='svg1'>
        <defs>
          <pattern id='bg-img' patternUnits='userSpaceOnUse' width='500' height='500' patternTransform='translate(0 3000)'>
            <image xlink:href='https://dl.dropboxusercontent.com/u/3454522/shapes1.svg' x='0' y='0' width='500' height='500' />
          </pattern>
          <linearGradient id='grad' gradientTransform='rotate(90 250 250)'>
            <stop offset='0%' stop-color='black' />
            <stop offset='100%' stop-color='white' />
          </linearGradient>
          <mask id='msk'>
            <polygon points='0,0 0,500 500,500 500,0' fill='url(#grad)' />
          </mask>
        </defs>
        <polygon points='0,0 0,500 500,500 500,0' fill='url(#bg-img)' mask='url(#msk)' />
      </svg>
    </div>

    不幸的是,这似乎只适用于 Chrome、Firefox 和 Opera。像往常一样,即使patterTransform 被正确应用,IE 的行为也不同并且不会改变模式位置。


    如果我们为模式的y 属性设置动画使用 snap.svg 库

    ,它也适用于 IE强>。

    var s = Snap("#svg1");
    
    var polygon = s.polygon([0, 0, 0, 500, 500, 500, 500, 0]);
    var mask = s.polygon([0, 0, 0, 500, 500, 500, 500, 0]);
    var grad = s.gradient('L(0,0,500,500)#000-#fff').attr({
      gradientTransform: 'rotate(45,250,250)'
    });
    var pattern = s.image('https://dl.dropboxusercontent.com/u/3454522/shapes1.svg', 0, 0, 500, 500)
      .pattern(0, 0, 500, 500);
    mask.attr({
      fill: grad
    });
    polygon.attr({
      fill: pattern,
      mask: mask
    });
    
    function animIn() {
      this.animate({
        y: '0'
      }, 10000, mina.linear, animOut);
    }
    
    function animOut() {
      this.animate({
        y: '3000'
      }, 0, mina.linear, animIn);
    };
    pattern.animate({
      y: '3000'
    }, 0, mina.linear, animIn);
    div {
      background-image: linear-gradient(rgba(24, 49, 67, .95), rgba(24, 49, 67, .88)), url(https://static.pexels.com/photos/96380/pexels-photo-96380.jpeg);
      background-size: cover;
      position: absolute;
      width: 500px;
      height: 500px;
    }
    
    svg {
      position: absolute;
      right: 0;
      left: 0;
      bottom: 0;
      height: 500px;
      width: 500px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.4.1/snap.svg-min.js"></script>
    <div>
      <svg viewBox='0 0 500 500' id='svg1'>
      </svg>
    </div>

    非常感谢 web-tiki 帮助我找出使用 snap.svg 的选项。

    【讨论】:

    • 谢谢,非常有用的答案:)
    猜你喜欢
    • 2011-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-24
    • 2013-11-12
    • 1970-01-01
    相关资源
    最近更新 更多