Skip to content

Instantly share code, notes, and snippets.

@jdmorlan
Created December 1, 2016 03:43
Show Gist options
  • Save jdmorlan/e14e0db931ab607dcee74725e01f56cb to your computer and use it in GitHub Desktop.
Save jdmorlan/e14e0db931ab607dcee74725e01f56cb to your computer and use it in GitHub Desktop.
Transition Animations - React/Rebound
import React, { Component } from 'react';
import { spring } from './spring.js';
class TheComponent extends Component {
componentWillEnter() {
spring(this.renderPosition, 0);
}
componentWillLeave() {
spring(this.renderPosition, 1);
}
componentWillUpdate(nextProps) {
// Do something to the components that are neither entering or leaving!
}
// On line 10, you told the spring to execute this function
// everytime the value updates!
renderPosition(value) {
this.container.style.transform = `rotate(${value}%)`
}
render() {
return (
<div ref={ r => this.container = r }></div>
);
}
}

component.js needs to be rendered in a <ReactTransitionGroup /> component.

If the component is connected to Redux, then you need a special connect function that recognizes the componentWillAppear, componentDidAppear, componentWillEnter, componentDidEnter, componentWillLeave and componentDidLeave.

This is because the normal connect function swallows your original component, so it hides those lifecycle functions unless you explicitly write a new version of connect that looks for them! Example component below (soon)!

Make sure that renderPosition does not do anything with React. You only want to manipulate the direct DOM. If you were to try and put the styles in state, either component level or Redux level, it would would be really expensive!

TODO - Make notes about the connect function that allows you to use spring animations based on direct state changes! Something like animating a button to scale when pressed!. This is only if you want to allow the animation to be called from outside the component!

import rebound from 'rebound';
const springSystem = new rebound.SpringSystem();
function spring(setter, value, opts = {}) {
const defaultOptions = {
tension: 50,
friction: 9,
}
const tension = opts.tension || defaultOptions.tension;
const friction = opts.friction || defaultOptions.friction;
const spring = springSystem.createSpring(tension, friction);
// Promise
let resolve = null;
let promise = Promise.resolve();
let resolved = true;
// Rebound Spring Listeners
internalSpring.addListener({
onSpringUpdate(spring) {
const val = spring.getCurrentValue();
setter(val);
},
onSpringAtRest() {
const val = spring.getCurrentValue();
setter(Math.floor(val));
resolve();
promise = Promise.resolve();
resolved = true;
},
});
if (value) spring.setCurrentValue(value).setAtRest();
return function(value) {
if (resolved) {
promise = new Proimse(_resolve => resolve = _resolve);
resolved = false;
}
spring.setEndValue(value);
return promise;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment