← Back to Blog

Creating a Roll Style Number Counter that Mimics a Slot Machine

coding
web

By Kevin Hou

2 minute read

I found a really cool way of making a number counter engaging. A co-worker at Salesforce, named Amy Lee, created a simple React component designed to mimic a slot machine. Instead of simply changing the number, the function "animates" the change and rolls up to that number. The cool thing about this is that it works for any number and it requires no CSS3 animation. It looks neat, especially with huge numbers!

Usage:

1<!-- The total time will be 300ms with one frame every 20ms. --> 2<AnimatedNumber number="{this.state.number}" time="{300}" frameRate="{20}" /> 3

Component source:

1const AnimatedNumber = React.createClass({ 2 getInitialState() { 3 return { 4 number: this.props.number, 5 }; 6 }, 7 componentWillReceiveProps(props) { 8 if (this.state.number !== props.number) { 9 // If different number 10 if (this._interval) { 11 //If theres an interval 12 clearInterval(this._interval); // Clear the existing interval 13 } 14 let framesLeft = this.props.time / this.props.frameRate; //Determine frame rate 15 let increment = (props.number - this.state.number) / (framesLeft + 1); //Determine increment per frame 16 this._interval = setInterval(() => { 17 if (framesLeft > 0) { 18 //If there are frames 19 this.setState({ number: this.state.number + increment }); //Set new number 20 framesLeft--; //Subtract a frame 21 } else { 22 //If done 23 clearInterval(this._interval); //Clear the interval 24 this._interval = null; //Set to null 25 this.setState({ number: props.number }); //Set the final value to the exact value just in case 26 } 27 }, this.props.frameRate); //How often it repeats 28 } 29 }, 30 render() { 31 return ( 32 <span> 33 {Math.round(this.state.number)} //Round if you don't want a decimal 34 </span> 35 ); 36 }, 37}); 38