Reputation: 192
I am wanting to know how could I animate SVG path with javascript instead of HTML. At the moment, I have found several overflow articles regarding the animation with javascript and have found many in jQuery with changing the attributes in javascript.
The links I found: Fill color SVG path with animation Animate SVG path via javascript
Does anyone might know how could I apply the techniques to the path below, as it works fine with HTML, but I would like to control the duration of the animation.
<svg width="300" height="300">
<defs>
<linearGradient id="left-to-right">
<stop offset="0" stop-color="#ff0000">
<animate dur="2s" attributeName="offset" opacity= 0.1 fill="freeze" from="0" to="1" />
</stop>
<stop offset="0" stop-color="#fff" stop-opacity= "0.1">
<animate dur="2s" attributeName="offset" opacity= 0.1 fill="freeze" from="0" to="1" />
</stop>
</linearGradient>
</defs>
<path id="myPath"
d="M 280 210 Q 237 144 180 140 Q 120 144 80 210 L 280 210 "
stroke="black" fill="url(#left-to-right)" />
</svg>
The thing is that the javascript is just not working
$(function(){
$(this).animate(
{
textIndent: 1,
}, {
duration: 3000,
step: function ( now, fx ) {
var from = 0,
to = 700,
r = from + to * ( now - fx.start ) / ( fx.end - fx.start );
$("#left-to-right").attr( "from", 0);
$("#left-to-right").attr( "from", 1);
},
complete: function () {
$("#myPath").attr("fill", "url(#left-to-right)");
}
}
);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg width="300" height="300">
<defs>
<linearGradient id="left-to-right">
<stop offset="0" stop-color="#ff0000">
<animate dur="2s" attributeName="offset" opacity= 0.1 fill="freeze" from="0" to="1" />
</stop>
</linearGradient>
</defs>
<path id="myPath"
d="M 280 210 Q 237 144 180 140 Q 120 144 80 210 L 280 210 "
stroke="black" fill="url(#left-to-right)" />
</svg>
How do I have to change the javascript now, fx and attributes, to make the animation work as it does with current HTML?
Upvotes: 3
Views: 1204
Reputation: 33062
If you want to use javascript to animate the gradient you don't need the <animate>
element any longer.
//all the stops
let ss = document.querySelectorAll("#left-to-right stop");
let start = null;
let progress = 0;//the progress of the animation
let duration = 2000; //2 seconds in millisecinds
let rid = null;//request animation id
function Frame(timestamp) {
rid = window.requestAnimationFrame(Frame);
if (!start) start = timestamp;
progress = timestamp - start;
if (progress <= duration) {
//for each stop reset the offset attribute
ss.forEach(s => {
s.setAttributeNS(null, "offset", progress / duration);
});
}
// if the animation is over cancel the animation
if (progress >= duration){window.cancelAnimationFrame(rid)}
}
Frame();
<svg width="300" height="300">
<defs>
<linearGradient id="left-to-right">
<stop offset="0" stop-color="#ff0000"></stop>
<stop offset="0" stop-color="#fff" ></stop>
</linearGradient>
</defs>
<path id="myPath" d="M 280 210 Q 237 144 180 140 Q 120 144 80 210 L 280 210" stroke="black" fill="url(#left-to-right)" />
</svg>
I hope you'll find this useful.
Upvotes: 5