跨浏览器渐变掩码

时间:2016-05-13 18:16:27

标签: css css3 animation svg gradient

我有一个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>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:3)

跨浏览器掩码:

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

&#13;
&#13;
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;
}
&#13;
<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>
&#13;
&#13;
&#13;

跨浏览器蒙版动画:

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

&#13;
&#13;
var y = 3000;
var svg1 = document.getElementById('bg-img');
setInterval(function() {
  y = (y <= 0) ? 3000 : y - 10;
  svg1.setAttribute('patternTransform', 'translate(0 ' + y + ')');
}, 100);
&#13;
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;
}
&#13;
<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>
&#13;
&#13;
&#13;

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

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

&#13;
&#13;
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);
&#13;
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;
}
&#13;
<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>
&#13;
&#13;
&#13;

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