最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Chrome doesn’t work on the animation of the attribute offset for a linear gradient - Stack Overflow

programmeradmin4浏览0评论

Below is the code that works great in Firefox, but any attempts to animate the linear gradient's offset attribute in Chrome ended in nothing.

<svg version="1.1" xmlns="" 
    xmlns: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>	

Below is the code that works great in Firefox, but any attempts to animate the linear gradient's offset attribute in Chrome ended in nothing.

<svg version="1.1" xmlns="http://www.w3/2000/svg" 
    xmlns:xlink="http://www.w3/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>	

Also tried using gradientUnits =" objectBoundingBox "

<svg version="1.1" xmlns="http://www.w3/2000/svg" 
    xmlns:xlink="http://www.w3/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>	

Any solution to this problem will do with: SVG,css, javascript

Share Improve this question edited Jul 21, 2019 at 11:07 Temani Afif 275k28 gold badges365 silver badges486 bronze badges asked Jul 21, 2019 at 7:19 Alexandr_TTAlexandr_TT 14.6k3 gold badges31 silver badges58 bronze badges 5
  • 1 Report it to Chrome's bugtracker. – Robert Longson Commented Jul 21, 2019 at 7:21
  • 1 Intrested in a pure CSS animation? – Temani Afif Commented Jul 21, 2019 at 8:28
  • @Temani Afif I look forward to solving CSS from you, but I’m interested in the animation exactly attribute offset – Alexandr_TT Commented Jul 21, 2019 at 8:33
  • it's difficult to have exactly the same but we can approximate it like this: jsfiddle/d6kbvx1n ... I am pretty sure we can do better but it need more precise values. – Temani Afif Commented Jul 21, 2019 at 10:01
  • @Temani Afif Please post your CSS solution here. – Alexandr_TT Commented Jul 21, 2019 at 10:14
Add a ment  | 

4 Answers 4

Reset to default 8

One solution to this would be using floating numbers instead of percentages, i.e values="1;0;1" instead of values="100%;0%;100%"

svg{border:1px solid}
<svg version="1.1" xmlns="http://www.w3/2000/svg" 
    xmlns:xlink="http://www.w3/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>	

Here is an idea with CSS only where you can rely on two gradients and a translation/opacity animation to approximate it. I also considered a little blur effect to have a better transition between gradient.

.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>

You can always use javascript for that:

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/2000/svg" 
     xmlns:xlink="http://www.w3/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>

Gradient attribute offset animation as background image

<svg version="1.1" xmlns="http://www.w3/2000/svg" 
    xmlns:xlink="http://www.w3/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/wikipedia/mons/f/fd/Ghostscript_Tiger.svg" width="50%" height="50%" />

</svg>

Radial gradient effects

<svg version="1.1" xmlns="http://www.w3/2000/svg" 
    xmlns:xlink="http://www.w3/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>

发布评论

评论列表(0)

  1. 暂无评论