Open SPAHI4 opened 8 years ago
Can you please include the link to the Material spec that this demonstrates so we can know exactly what you're asking?
StaggeredMotion
lets you start animating item n + 1 after item n has crossed a particular threshold. That's probably what you want, but arranging the grid correctly to achieve this effect might be tricky.
I think it's from here - https://www.google.com/design/spec/animation/meaningful-transitions.html#meaningful-transitions-hierarchical-timing
I made a Delay
helper, and wrapped each box with a Delay
and Motion
. worked out nicely -
import React, {Component} from 'react';
import {render} from 'react-dom';
import {Motion, spring} from 'react-motion';
// helper to delay a prop being passed by `period` ms
class Delay extends Component{
static defaultProps = {
period: 0
};
state = {
value: this.props.initial
};
refresh(props){
let {value, period} = props;
setTimeout(() => this.setState({
value
}), period);
}
componentDidMount() {
this.refresh(this.props);
}
componentWillReceiveProps(next){
this.refresh(next);
}
render(){
// function-as-children
return this.props.children(this.state.value);
}
}
const boxes = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
const styles = {
wrap: {
width: 500
},
box: {
margin: 5,
width: 100,
height: 100,
float: 'left',
backgroundColor: 'blue',
transformOrigin: 'center center'
}
};
class App extends Component{
render() {
return (
<div style={styles.wrap}>
{boxes.map((box, i) =>
<Delay key={box} initial={0} value={1} period={i*80}>{ delayed =>
<Motion defaultStyle={{scale: 0}} style={{scale: spring(delayed)}}>{ val =>
<div style={{...styles.box, transform: `scale(${val.scale})`}}>
{box}
</div>
}</Motion>
}</Delay>)}
</div>
);
}
}
render(<App/>, document.getElementById('app'));
Here's your demo as a Pen:
http://codepen.io/anon/pen/eJrKKX?editors=001
StaggeredMotion works well for that same effect. The only potential wrinkle would be if you wanted to have row 2 start transitioning before row 1 is complete; it's doable, just more complicated. (You could nest StaggeredMotion instances, one for the rows and one for the columns, if you knew which item would end up in each.)
With the Delay approach, it seems like bad things would happen if you received new props before the transition had finished. One of the awesome things about ReactMotion (and by extension StaggeredMotion) is that it's reversible and cancelable by default.
yes agreed! Indeed, there's a class of animations that involve timing etc that isn't really suited for react-motion (at least directly) - these animations usually have their own state/sequencing logic. Fun to solve these on a case by case basis, but there's clearly a need for higher level constructs. I'm hoping the incoming atRest
api makes these easier.
Any way to get this to work with TransitionMotion? I have a slide system where some slides use React Motion internally, and others use a standard Transition (and mount/unmount with TransitionMotion), all driven by React Router. I'd like to simply chain from the slide's internal animation (if it has one) to the next slide (or use a default if it has none). I have everything working, except I need to delay the new slide's in transition until the parent slide's out is complete (and then in reverse the other way).
It doesn't look like there's a way to do that without an atRest API, but I'm hoping I'm wrong?
I ended up delaying the React Router change, which triggers the second animation to give the first a chance to finish. It's not the prettiest, but it'll work for now. :-)
You could use setTimeout
if you know the approximate duration of the animation to fake atRest
Here is my demo as a Pen , you can change the martix
and the custom
variables to view different effects.
Awesome work @devlee!!! That's super cool. I might have to try and get that in React Motion UI Pack :)
@souporserious :) I used to make a mistake and now I have used scale
instead of changing width
and height
~
thanks for the example! however, I havent tested it but shouldn't you cancel the timeout if the component is going to unmount. Something like:
class Delay extends Component{
static defaultProps = {
period: 0
};
state = {
value: this.props.initial
};
refresh(props){
let {value, period} = props;
this.timeout = setTimeout(() => this.setState({
value
}), period);
}
componentDidMount() {
this.refresh(this.props);
}
componentWillReceiveProps(next){
this.refresh(next);
}
componentWillUnmount(){
clearTimeout(this.timeout);
}
render(){
// function-as-children
return this.props.children(this.state.value);
}
}
That way if it unmount midway through an animation you wont have problems.
Hi guys, I read this thread before I wrote a demo piece for my not yet finished portfolio site.
TL:DR
GSAP, pre computed delay info, here's the demo:
Background
I was thinking a lot about how to solve this grid motion problem, and this thread was a good starting point for some inspiration.
I did some tests around using react-motion for a matrix of spring like behaviour (water ripple effect), but the performance and serial nature of the spring connections didn't lend itself well to the problem I was looking to solve, in the end I pre-computed a lookup table of delay data and used that with GSAP for it to run arbitrary motions that propagate through the tiles. you can have any number of waves running concurrently , (Click mutliple tiles)
Each time you click a tile, Its sent an animation with a specific delay based on distance from other tiles, wave shape / parameters. As you click more times, each tile stacks its animation, and adds them together, enabling waves that mix.
I used GSAPs custom bezier drawing function to draw my own set of wave shapes (four in total) which meant I could achieve the exact motion styles I was after.
For most purposes this is overkill, but the concept can be used in many different ways,
I built an interface using React to control the motion and colour of the tiles. The tiles are rendered with WebVR / Aframe. You can get some pretty crazy results by adjusting the settings.
Im pulling the inidividual RGBs out of PNGs and pushing them to the tiles.
I built a colour animation system by way of a json object that acts like a script telling GSAP how to animate the colours on the fly. Lending itself to the possibility of slide shows and sprite animations. See sonic !
Its very heavy on computation / memory, 32 x 32 matrix with potentially 5 / 6 separate motions running through them concurrently. is 6000 GSAP animations. lol.
Hope you like. And thanks for inspiration.
Is it possible to do hierarchical timing transitions like this? https://material-design.storage.googleapis.com/publish/material_v_4/material_ext_publish/0B08MbvYZK1iNTGRLb2Zud2RUNFE/animation-meaningfultransitions-hierarchicaltiming-4do_large_xhdpi.webm