Skip to content

Instantly share code, notes, and snippets.

@joshwcomeau
Created February 12, 2016 13:21
Show Gist options
  • Save joshwcomeau/237f3e737237cc359512 to your computer and use it in GitHub Desktop.
Save joshwcomeau/237f3e737237cc359512 to your computer and use it in GitHub Desktop.
Animating the Unanimatable
componentDidUpdate(previousProps) {
previousProps.children.forEach( child => {
let domNode = ReactDOM.findDOMNode( this.refs[child.key] );
const newBox = domNode.getBoundingClientRect();
const oldBox = this.state[key];
const deltaX = oldBox.left - newBox.left;
const deltaY = oldBox.top - newBox.top;
requestAnimationFrame( () => {
domNode.style.transform = `translate(${deltaX}px, ${deltaY}px)`;
domNode.style.transition = 'transform 0s';
requestAnimationFrame( () => {
// In order to get the animation to play, we'll need to wait for
// the 'invert' animation frame to finish, so that its inverted
// position has propagated to the DOM.
//
// Then, we just remove the transform, reverting it to its natural
// state, and apply a transition so it does so smoothly.
domNode.style.transform = '';
domNode.style.transition = 'transform 500ms';
});
});
});
}
@birtles
Copy link

birtles commented Jun 9, 2016

You shouldn't need to use requestAnimationFrame to trigger transitions. You just need to trigger a style flush.

e.g.

getComputedStyle(domNode).transform;

Will cause style to be flushed. So to trigger a transition, typically all you need is:

domNode.style.transform = '<initial transform>';
domNode.style.transition = 'transform 500ms';
getComputedStyle(domNode).transform;
domNode.style.transform = '<target transform>';

There's no "propagating to the DOM", it's just doing style resolution. The node is already in the DOM.

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