Last active
April 15, 2019 16:06
-
-
Save joemaller/176dc5b994108c4388ffaacea6d9ecfa to your computer and use it in GitHub Desktop.
Vanilla JS SVG line animation helper, works in IE
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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