Skip to content

Instantly share code, notes, and snippets.

@zebulonj
Last active August 29, 2015 14:23
Show Gist options
  • Save zebulonj/3a6f8519d9be5e12dcd1 to your computer and use it in GitHub Desktop.
Save zebulonj/3a6f8519d9be5e12dcd1 to your computer and use it in GitHub Desktop.
Flux + React Animation: Academic to Implementation
'use strict';
/**
* Convenience method to get current time.
*
* @returns {Integer} Current time in milliseconds since Epoch.
*/
function now() {
return ( new Date() ).getTime();
}
/**
* Abstract function to execute code on the next animation frame. In practice this method would likely be implemented
* using `window.requestAnimationFrame()` or its equivalent.
*
* @param fn {Function}
*/
function frame( fn ) {
// Execute `fn` on next animation frame.
}
/**
* Implements a generalized animation loop, on an individual property, "rendering" state changes from state `a` to
* state `b` over a specified duration.
*
* @param a {Number} Initial state.
* @param b {Number} Final state.
* @param duration {Integer} Animation duration in milliseconds.
*
* @returns {Function} Returns a function that, if called, will cancel the animation.
*/
function animate( a, b, duration ) {
const start = now();
let cancelled = false;
/**
* Abstract render method. In application, would be replaced with specific code to update display based
* on incremental state updates.
*
* @param state {Number} Current state.
*/
function render( state ) {
console.log( "Render:", state );
// Render current state to display.
}
/**
* Converts specified time to animation progress from 0.0 to 1.0.
*
* @param time {Integer} Current frame time in milliseconds since Epoch. See `now()`, above.
* @returns {number} Progress from 0.0 (start) to 1.0 (end).
*/
function progress( time ) {
return Math.min( 1, ( time - start ) / duration );
}
/**
* Uses animation parameters (`a`, `b`, and `duration`) to calculate the state for the current animation frame,
* and passes that value to the `render()` function. If the animation is not complete, schedules next update
* via `frame()`.
*/
function update() {
if ( cancelled ) return;
let p = progress( now() );
let state = a + ( p * ( b - a ) );
render( state );
if ( p < 1 ) {
frame( update );
}
}
// Start the animation loop.
frame( update );
return function cancel() {
return ( cancelled = true );
};
}
animate( 0, 1, 1000 );
// Render: 0.016
// Render: 0.032
// Render: 0.048
// ...
// Render: 1
@zebulonj
Copy link
Author

This is an examination of implementing animations that require incremental state changes, on top for Flux + React. This exercise assumes that the animation is not suitable for implementation via CSS. The initial code above is an abstract animation loop, which is to serve as a reference point for mapping functionality into a Flux + React architecture.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment