Skip to content

Instantly share code, notes, and snippets.

@nosajio
Created September 26, 2016 14:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nosajio/a178eff8d8c545de674afb71ea582ada to your computer and use it in GitHub Desktop.
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.
(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