diff --git a/client/src/components/donut.js b/client/src/components/donut.js new file mode 100644 index 0000000..a694f6d --- /dev/null +++ b/client/src/components/donut.js @@ -0,0 +1,65 @@ +import React from 'react'; +import Base from './base'; + +export default class Donut extends Base { + state = { + currentPercent: 0, + currentPercent2: 0, + }; + + constructor(props) { + super(props); + requestAnimationFrame(() => this.animate()); + } + + componentWillUnmount() { + this.unmounted = true; + } + + componentDidUpdate(prevProps) { + if (this.animationQueued) return; + + const {percent, percent2} = this.props; + if (prevProps.percent !== percent || prevProps.percent2 !== percent2) { + this.animate(); + } + } + + animate() { + this.animationQueued = false; + if (this.unmounted) return; + + const {percent = 0, percent2 = 0} = this.props; + const {currentPercent = 0, currentPercent2 = 0} = this.state; + + if (currentPercent === percent && currentPercent2 === percent2) return; + + const next1 = getNextStep(percent, currentPercent); + const next2 = getNextStep(percent2, currentPercent2); + this.setState({currentPercent: next1, currentPercent2: next2}); + + this.animationQueued = true; + requestAnimationFrame(() => this.animate()); + } + + render() { + const {currentPercent, currentPercent2} = this.state; + const percent = currentPercent * 100; + const percent2 = currentPercent2 * 100; + + return ( + + + + + + ); + } +} + +function getNextStep(target, current) { + const diff = current - target; + const absDiff = Math.abs(diff); + const change = Math.min(absDiff, 0.02); + return diff > 0 ? current - change : current + change; +}