【问题标题】:Chrome doesn’t work on the animation of the attribute offset for a linear gradientChrome 不适用于线性渐变的属性偏移动画
【发布时间】:2019-11-29 13:14:48
【问题描述】:

下面是在Firefox 中运行良好的代码,但是任何尝试在Chrome 中为线性渐变的偏移属性设置动画都没有结果。

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
	     width="50%" height="50%" viewBox="0 0 900 900" >  

 <defs>
<linearGradient id="bgg" x1="0" y1="0" x2="900" y2="900" gradientUnits="userSpaceOnUse"> 
  
	<stop offset="0%" stop-color="dodgerblue"/>
	<stop offset="52%" stop-color="white">
	    <animate 
            attributeName="offset" 
            values="100%;0%;100%" 
            dur="4s" 
            repeatCount="indefinite">
	    </animate> 
    </stop>  
    <stop offset="100%" stop-color="gold">
        <animate 
            attributeName="offset" 
            values="100%;50%;100%" 
            dur="4s" 
            repeatCount="indefinite">
		</animate> 
    </stop> 
</linearGradient>
</defs>

<rect x="50" y="50" width="50%" height="50%" rx="5%"  fill="url(#bgg)" />
</svg>	

也尝试使用gradientUnits =" objectBoundingBox "

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
	     width="50%" height="50%" viewBox="0 0 900 900" >  

 <defs>
<linearGradient id="bgg" x1="0%" y1="0%" x2="100%" y2="100%" gradientUnits="objectBoundingBox"> 
  
	<stop offset="0%" stop-color="dodgerblue"/>
	<stop offset="52%" stop-color="white">
	   <animate 
            attributeName="offset" 
            values="100%;0%;100%" 
            dur="4s" 
            repeatCount="indefinite">
	   </animate> 
    </stop>  
    <stop offset="100%" stop-color="gold">
        <animate 
            attributeName="offset" 
            values="100%;50%;100%" 
            dur="4s" 
            repeatCount="indefinite">
		</animate> 
    </stop> 
</linearGradient>
</defs>

<rect x="50" y="50" width="50%" height="50%" rx="5%"  fill="url(#bgg)" />
</svg>	

此问题的任何解决方案都可以使用:SVG,css,javascript

【问题讨论】:

  • 报告给 Chrome 的 bugtracker。
  • 对纯 CSS 动画感兴趣?
  • @Temani Afif 我期待你解决 CSS,但我对动画的确切属性很感兴趣 offset
  • 很难做到完全相同,但我们可以这样近似:jsfiddle.net/d6kbvx1n ...我很确定我们可以做得更好,但它需要更精确的值.
  • @Temani Afif 请在此处发布您的 CSS 解决方案。

标签: javascript css svg linear-gradients svg-animate


【解决方案1】:

对此的一种解决方案是使用浮点数而不是百分比,即values="1;0;1" 而不是values="100%;0%;100%"

svg{border:1px solid}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
	     width="50%" height="50%" viewBox="0 0 900 900" >  

 <defs>
<linearGradient id="bgg" x1="0" y1="0" x2="50%" y2="50%" gradientUnits="userSpaceOnUse"> 
  
	<stop offset="0" stop-color="dodgerblue"/>
	<stop offset=".52" stop-color="white">
	    <animate 
            attributeName="offset" 
            values="1;0;1" 
            dur="4s" 
            repeatCount="indefinite">
	    </animate>
    </stop>  
    <stop offset="1" stop-color="gold">
        <animate 
            attributeName="offset" 
            values="1;.5;1" 
            dur="4s" 
            repeatCount="indefinite">
		</animate>
    </stop> 
</linearGradient>
</defs>

<rect x="50" y="50" width="50%" height="50%" rx="5%"  fill="url(#bgg)" />
</svg>	

【讨论】:

  • 一个有趣的解决方案谢谢!令人惊讶的是,values =" 1; .5; 1 "gradientUnits =" userSpaceOnUse " 时有效
【解决方案2】:

您可以随时使用javascript

requestAnimationFrame(animateOffsets);

// if this function called as callback of requestAnimationFrame, 
// so there are first argument is the time from beginning from scene start
function animateOffsets(t) { 
  requestAnimationFrame(animateOffsets);
  t = t%5000/5000; // will change from 0 to 1 (5 sec) 
  t = Math.sin(t*Math.PI*2); // will change from -1 to 1 
  stop1.setAttribute('offset', `${50 + t*50}%`);
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink"
	   width="50%" height="50%" viewBox="0 0 900 900" >  
 <defs>
  <linearGradient id="bgg" x1="0" y1="0" x2="60%" y2="60%" gradientUnits="userSpaceOnUse"> 
    <stop offset="0%" stop-color="dodgerblue"/>
    <stop offset="50%" stop-color="white" id="stop1"/> 
    <stop offset="100%" stop-color="gold"/> 
  </linearGradient>
</defs>

<rect x="50" y="50" width="50%" height="50%" rx="5%"  fill="url(#bgg)" />
</svg>

【讨论】:

  • 我喜欢你使用Math.sin()这一事实。它使动画更流畅。
  • @enxaneta 我也喜欢在这里使用缓动函数gist.github.com/gre/1650294
【解决方案3】:

这是一个仅使用 CSS 的想法,您可以依靠两个渐变和一个平移/不透明度动画来近似它。我还考虑了一点模糊效果,以便在渐变之间有更好的过渡。

.box {
  border-radius:20px;
  width:200px;
  height:200px;
  position:relative;
  z-index:0;
  overflow:hidden;
}
.box:before,
.box:after{
  content:"";
  position:absolute;
  bottom:0;
  right:0;
  width:220%;
  height:220%;
  animation:translate 2s infinite linear alternate;
}
.box:after {
  background:
    linear-gradient(to bottom right,dodgerblue 0%,white 40%,gold 60%);
  animation-name:translate,show;
  opacity:0;
}
.box:before {
  background:
    linear-gradient(to bottom right,dodgerblue,white 50%,gold 50%);
  animation-name:translate,fade;
}

@keyframes translate{
  from {
    transform:translate(48%,48%);
  }
}
@keyframes show{
  30%,85% {
    opacity:1;
  }
}
@keyframes fade{
  30%,85% {
    filter:blur(8px);
  }
}
<div class="box">

</div>

【讨论】:

    【解决方案4】:

    渐变属性offset动画作为背景图片

    <svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
        xmlns:xlink="http://www.w3.org/1999/xlink"
    	width="50%" height="50%"      viewBox="0 0 900 900" >  
    
     
    <linearGradient id="bgg" x1="479" y1="-345" x2="479" y2="853" gradientUnits="userSpaceOnUse"> 
        <stop offset="0%" stop-color="#fff">
            <animate 
                attributeName="offset" 
                values="0;1;1;0;0" 
                dur="5s" 
                repeatCount="indefinite"
            ></animate>
        </stop>
        <stop offset="100%" stop-color="gold">
            <animate 
                attributeName="offset" 
                values="0;1;1;0;0" 
                dur="5s" 
                repeatCount="indefinite"
            ></animate> 
        </stop>
    </linearGradient>
    <rect x="-45" y="0" width="70%" height="70%" rx="5%"  fill="#ACA900" />
    
    <rect x="65" y="80" width="50%" height="50%" rx="5%"  fill="url(#bgg)" /> 
    <image x="30" y="100" xlink:href="https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg" width="50%" height="50%" />
    
    </svg>

    径向渐变效果

    <svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
        xmlns:xlink="http://www.w3.org/1999/xlink"
    	width="50%" height="50%"      viewBox="0 0 900 900" >  
     
    <radialGradient id="myRadial"
               fx="50%" fy="50%" r="80%">
              
            
        <stop offset="0%" stop-color="gold">
            <animate 
                attributeName="offset" 
                values="0;1.3;0" 
                dur="5s" 
                repeatCount="indefinite"
            ></animate>
        </stop>
        <stop offset="100%" stop-color="#EDEDED">
            <animate 
                attributeName="offset" 
                values="0;1.3;1.3;0;0" 
                dur="5s" 
                repeatCount="indefinite"
            ></animate> 
        </stop>
    </radialGradient> 
    <rect x="0" y="0" width="70%" height="70%" rx="5%"  fill="#ACC400" />
    
    
    <rect x="85" y="80" width="50%" height="50%" rx="5%"  fill="url(#myRadial)" /> 
    
    
    </svg>

    【讨论】:

      猜你喜欢
      • 2011-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-14
      • 2018-09-11
      • 1970-01-01
      相关资源
      最近更新 更多