ANIMATION
In the world of states
(has comments to each slide)

Durability
Usefulness
Beauty
Is it really important?

Browser animation
Ideal one,
has a smooth animation, works at regular intervals

Misconception #1
setTimeout, may not be finished in time
requestAnimationFrame, will be called at the optimal redrawing time


// Or use a polyfill:
// import requestAnimationFrame from 'raf';
const { requestAnimationFrame } = window;
const animate = () => {
requestAnimationFrame(animate);
// Perform an animation step
x += velocity;
}
// Fire it up
requestAnimationFrame(animate);
Pattern
Misconception #2
(permanent speed)
requestAnimationFrame(timestamp => {
// DOMHighResTimeStamp
// timestamp ~> 30485.84100000153
});

const animate = timestamp => {
const delta = timestamp - prevTimestamp;
// Note, it's a function now!
x += velocity(delta);
requestAnimationFrame(animate);
};
Let's reuse the timestamp

The result w/ Delta
Example

const redraw = _ => {
points.forEach(point => {
// make sure `will-change: transform` is set
point.element.style.transform = `
translate3d(${point.x}px, ${point.y}px, 0.0px)
rotate(${point.angle}rad)`
});
};
const tick = ts => {
_lastRaf = requestAnimationFrame(tick);
physicsStep(delta);
redraw(delta);
}
‘will-change: transform’
Stateful applications

Immutable UI is an essentials for the up-to-date web-applications. DOM visualizes the current state.
Immutable UI
Application is a chain of states


// CSS property
// transition: transform is ease;
// Conditional state change
<div className ={isVisible ? 'is-visible' : 'is-hidden'} />
// Direct style manipulation
<div style={{ transform: `translate(${scale})` }} />
Because it's simple

Good, but not enough
Much better

React-Motion


"Dirty" animations
class Dialog extends Component{
componentDidMount(){
const node = findDOMNode(this);
// Or $.animate, anime.js, GSAP, D3 ...
Velocity(node, {scale: 1.5},
{duration: 1000});
}
render(){ ... };
};
class Dialog extends Component{
componentDidMount(){
const node = findDOMNode(this);
// animate returns a cancellable
// promise-like object
this._anim = animate(node, { ... });
}
componentWillUnmount(){
this._anim && this._anim.cancel();
}
};

Modal window
<Animated>
{ this.state.showDialog && <Dialog /> }
</Animated>
<div>
{ this.state.showDialog && <Dialog /> }
</div>
vs.
States map

const element = <Dialog size="medium" />
// => { type: Dialog, props: { size: 'medium' }, ... }
const element = React.createElement(Dialog, { size: 'medium'});
What's hidden in JSX?
componentWillReceiveProps(nextProps){
// Exit transition
if(this.props.children && !nextProps.children){
return this.transitionState(st.EXITING,
{children: this.props.children})
};
}
transitionState(transitionTo, opt = {}){
// .. FSM logic ..
// Wait for `this._content.animateExit()`
}

Modal window v2.0

import Transition from 'react-transition-group/Transition';
// `state` is 'entered', 'entering', 'exited' etc.
<Transition in={isVisible} timeout={duration}>
{state => <ModalDialog animationState={state} />}
</Transition>
Interception of responsibility
render(){
return <canvas />
}
// Render only once!
shouldComponentUpdate() {
return false;
}
componentWillReceiveProps(nextProps){
if(this.props.color != nextProps.color){
// Animate on canvas...
}
}

Cool, but not enough
Much better

// Limit delta to avoid divergence
const delta = Math.min(100.0, ts - prevTs);
const P = 0.001 + delta;
this.x = P + (this.target - x);
P-controller

The End
ANIMATION
By Serge Zdobnov
ANIMATION
- 627