Created
September 26, 2016 14:41
-
-
Save nosajio/a178eff8d8c545de674afb71ea582ada to your computer and use it in GitHub Desktop.
This little guy will output coordinates for animating svg <path>s into a percentage of a circle. Useful for pie charts and that kind of thing.
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
(function() { | |
'use strict'; | |
/** | |
* Radial Coordinates animation | |
* For use with <path d="{coords}"> | |
* | |
* | |
* Example | |
* | |
* const a = animatecircle({ | |
* duration: 1000, | |
* exponent: 0.8, | |
* radius: 110, | |
* x: 125, | |
* y: 125, | |
* percent: 25, | |
* callback: (d) => console.log(d) | |
* }); | |
* a.start(); | |
*/ | |
var animationOptions = {}; | |
window.radialCoordsAnimation = animatecircle; | |
function animatecircle(options) { | |
animationOptions = Object.assign({}, options); | |
const {percent} = options; | |
const angle = (359 / 100) * percent; | |
return { start } | |
function start() { | |
requestAnimationFrame( animateCoords.bind(this, 0, angle, options.callback) ); | |
} | |
}; | |
function polarToCoords({x, y}, radius, angle) { | |
const angleInRadians = (angle - 90) * Math.PI / 180.0; | |
return { | |
x: x + (radius * Math.cos(angleInRadians)), | |
y: y + (radius * Math.sin(angleInRadians)) | |
}; | |
} | |
function arc(x, y, radius, startAngle, endAngle) { | |
const start = polarToCoords({x, y}, radius, endAngle); | |
const end = polarToCoords({x, y}, radius, startAngle); | |
const largeArcFlag = endAngle - startAngle <= 180 ? '0' : '1'; | |
const d = [ | |
'M', start.x, start.y, | |
'A', radius, radius, 0, largeArcFlag, 0, end.x, end.y | |
]; | |
return d.join(' '); | |
} | |
function animateCoords(from, to, cb, timestamp) { | |
(! animationOptions.start) ? (animationOptions.start = timestamp) : null; | |
const progress = timestamp - animationOptions.start; | |
const progressRatio = progress / animationOptions.duration; | |
if (progressRatio >= 1) { | |
return; | |
} | |
let progressAngle = Math.pow(progressRatio, animationOptions.exponent) * to; | |
const fromAngle = (from < to) ? progressAngle : to; | |
const d = arc( | |
animationOptions.x, | |
animationOptions.y, | |
animationOptions.radius, | |
0, | |
progressAngle | |
); | |
cb(d); | |
requestAnimationFrame( animateCoords.bind(this, fromAngle, to, cb) ); | |
} | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment