Reputation: 4232
I want to animate the opacity of the items from number 1 to 4, but want to run it inverted (from 4 to 1) if the items are removed. I thought that the reverse
flag could help, but it doesn't do anything:
import React, { useState } from "react";
import { animated, config, useTransition } from "react-spring";
export default function App() {
const items = [1, 2, 3, 4];
const [isToggled, setToggled] = useState(false);
const transitions = useTransition(isToggled ? items : [], item => item, {
config: config.gentle,
unique: true,
trail: 250,
reverse: isToggled ? false : true,
from: { opacity: 0 },
enter: { opacity: 1 },
leave: { opacity: 0 }
});
return (
<div className="App">
<button onClick={() => setToggled(!isToggled)}>Toggle</button>
{transitions.map(({ item, key, props }) => (
<animated.div key={key} style={props}>
Issue #{item}
</animated.div>
))}
</div>
);
}
Upvotes: 1
Views: 2695
Reputation: 23
The problem with reverse
method is it reverse all the content inside the array.
You only need to reverse
the props
properties inside the result of your useTransition
.
With simple array modification like this (in typescript) :
// utils/animation.ts
// or js just modify the type
import { UseTransitionResult } from 'react-spring';
export function reverseTransition<T, Result extends UseTransitionResult<T, object>>(
arr: Result[],
): Result[] {
const result: Result[] = [];
for (let idx = 0; idx < arr.length; idx++) {
result.push({
...arr[idx],
props: arr[arr.length - 1 - idx].props,
});
}
return result;
}
and pass the result of useTransition hooks like this :
import React, { useState } from "react";
import { animated, config, useTransition } from "react-spring";
// import above code
import { reverseTransition } from "utils/animation";
export default function App() {
const items = [1, 2, 3, 4];
const [isToggled, setToggled] = useState(false);
const transitions = useTransition(isToggled ? items : [], item => item, {
config: config.gentle,
unique: true,
trail: 250,
reverse: isToggled ? false : true,
from: { opacity: 0 },
enter: { opacity: 1 },
leave: { opacity: 0 }
});
return (
<div className="App">
<button onClick={() => setToggled(!isToggled)}>Toggle</button>
{(isToggled ? transitions : reverseTransition(transitions)).map(({ item, key, props }) => (
<animated.div key={key} style={props}>
Issue #{item}
</animated.div>
))}
</div>
);
}
You will get the reversed animation with the same content. I hope it helps!
Notes: I am using React Spring v8, not v9 (the one that you use in your Codesandbox)
Regards
Upvotes: 2