Skip to content

Instantly share code, notes, and snippets.

@joemaller
Last active April 15, 2019 16:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joemaller/176dc5b994108c4388ffaacea6d9ecfa to your computer and use it in GitHub Desktop.
Save joemaller/176dc5b994108c4388ffaacea6d9ecfa to your computer and use it in GitHub Desktop.
Vanilla JS SVG line animation helper, works in IE
/**
* Initialize animation on an SVG path or set of paths, this returns a controller
* object
*
* var lines = animate({
* parent: "#someElement",
* selector: ".theActualLines",
* duration: 2500
* })
*
* Then kick off the animation by calling play() on the controller:
*
* lines.play()
*
* animate accepts the following options:
*
* @param {String} paths A selector describing a set of SVG path elements
* @param {Number} duration Duration of the animation in milliseconds
* @param {Object} args - An object containing the following
* @param {String} args.selector - A selector string describing a set of SVG path elements
* @param {Number} [args.duration=1500] - Duration of the animation in milliseconds
* @param {Boolean|String} [args.loop=false] - Loop the animation or not
* @return {Object}
*/
var animate = function(args) {
var duration =
args.duration !== undefined ? parseInt(args.duration, 10) : 1500,
parent = args.parent !== undefined ? args.parent : "body",
pathNodes = $(parent).find(args.selector),
easing = 1.8;
/**
* QuerySelectorAll returns a nodeList, which doesn't support forEach/map/filter/reduce iteration
*/
for (var n = 0; n < pathNodes.length; n++) {
var len = pathNodes[n].getTotalLength();
pathNodes[n].style.strokeDasharray = len - 1 + " " + len;
pathNodes[n].style.strokeDashoffset = len;
pathNodes[n].setAttribute("data-length", len);
}
var getEndTime = function() {
return new Date().getTime() + duration;
};
var controller = {
endTime: false
};
controller.play = function() {
var ratio, offset;
if (controller.endTime === false) {
controller.endTime = getEndTime();
}
ratio = Math.max(0, controller.endTime - new Date().getTime()) / duration;
for (var n = 0; n < pathNodes.length; n++) {
var len = pathNodes[n].getAttribute("data-length");
offset = len * Math.pow(ratio, easing);
pathNodes[n].style.strokeDashoffset = offset;
}
if (args.loop && ratio <= 0) {
ratio = 1;
controller.endTime = getEndTime();
}
if (ratio > 0) {
window.requestAnimationFrame(controller.play);
}
};
return controller;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment