These docs are in progress!
Animations in Reapp are powered by our Animated mixin. This mixin provides an API that allows you to easily animate React elements.
Animations are defined in a specific format. When you pass props to a component, you use animations
as the key. The value is an object that describes the animations you want:
var animations = {
self: ['fade', 'moveLeft'],
button: 'moveRight'
};
<Component animations={animations}>
In the above example we are defining a more complex animation, where the component is being told to animate its outermost div (self
) with two animations: 'fade' and 'moveLeft'. Meanwhile, we assign the 'moveRight' animation to its button.
In reapp-ui, we have a helper that automatically handles these props. The keys in the animation object merely map to DOM nodes within the component. We expose a function componentProps()
that returns props for our components in a structured way. For example, within our above Component we would write:
Note: The componentsProps helper is only used internally within reapp-ui to enforce consistency and save writing code, but you can still use animations by just using a "ref" on your props. We'll explain this more below
Component({
name: 'MyButton',
render() {
return
<div {...componentProps()}>
<button {...componentProps('button')} />
</div>
}
})
The componentProps would end up applying attributes on those nodes like this:
<div ref="self" className="MyButton">
<button ref="button" className="MyButton-button" />
</div>
The ref
attribute is the same as the string we pass to componentProps, but it defaults to 'self', which we use for all top DOM nodes.
Now, going back to how we defined our animation props we can see how they apply. The <div ref="self">
gets 'fade' and 'moveLeft', while the <button ref="button">
gets 'moveRight'.
A simple mixin to run animations through context or within a component.
The Animated mixin uses the this.context.theme.animations : object
to search for animations. Animations are functions that take an object,
like so: { index, state, ...extraProps }
and return an object with
the following options:
{
transform: { x: num, y: num, z: num },
rotate: num,
rotate3d: { x: num, y: num, z: num },
scale: num,
(opacity, or any other prop): any
}
Extra props can be passed down from a parent Animator by defining
this.animationContext (func : object) -> object
on their class.
The object returned by animationContext is merged into extraProps.
Within an animated component you can get the current animation state
with this.getAnimationState() -> object
or the current animation
styles with this.getAnimationStyle() -> object
.
In a parent component you define a "step" (props or state), which is
the current position of the animation. Then on children, you define
an "index" (property). This mixin then allows you to run
this.getAnimationStyle()
on the children, which will use the state
set in the parents.
Parents pass down context through this.context.animations : object
.
This object should contain a key (the name/source of the animation)
to the value (an object with at least { step }).
To ease setting this context, check out the Animator mixin.
Animation state consists always of two things: index
and step
.
You can also add extra information to your animation state by defining
animationContext
on your class, which can be an object or function:
animationContext: {
extra: 'values',
go: 'here'
}
// or...
animationContext() {
return {
width: this.state.width
};
}
The getAnimationState function will do a search through your component in the following order to find these properties:
The return value is an object with at least index and step, and potentially extra
information as passed down through this.animationContext
.
Call this to disable animations on the current component.
Call this to enable animations on the current component.
Returns if the animations are currently disabled.
Check if an animation is running. This uses getAnimationState
and then checks if the step isn't a whole number.
Checks if a given ref has animations set.
Because we can either pass in our animations
object through props, or define it in state, this is a helper function that checks both props and state for active animations.
Given a ref and optionally a source, returns an object of styles at the current animation state.
If no source is given, it will check the current components this.props.animationSource
value.
You can define transforms using our syntax, such that transforms will return a string that handles:
You can load animations into your Theme using the following syntax:
import UI from 'reapp-ui';
UI.addAnimations({
slideLeft({ index, step }) {
return {
translate: {
x: index - step * 100
}
}
}
})
All animations take in two properties: index and step.
You could imagine a list of items like this:
<Parent>
<Child index={0} />
<Child index={1} />
<Child index={2} />
</Parent>
Now, let's animate through the list of Child elements. First we'll set up the Parent class to do a tween.
In your Parent class import react-animate-state, and set up a tween from 0 to 2 that lasts a second:
import Animated from 'reapp-ui/mixins/Animated';
import tweenState from 'react-tween-state';
var Parent = React.createClass({
getInitialState() {
return {
step: 0
};
},
componentDidMount() {
this.animate({ step: 1 }, 1000, 'ease-in-out-quad');
},
render() {
return React.children.map(this.props.children, (child, i) =>
React.cloneElement(child, {
index: i,
step: this.state.step
})
));
}
});
Notice we clone the children elements and pass down the index and step to them. Let's make our Child elements:
var animations = { self: 'slideLeft' };
<Child animations={animations}>