-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Animation System: Making things move #4
Comments
This issues describes the Animation part of the core systems of a component library. |
I'll just quote my comment about Framer Motion on #3 (comment) here, but I would like to add that I totally agree with giving it a go. This is just my initial thoughts, but I don't have enough experience with the library. So I'm curious to see how this goes. 😊
|
Same! It'll be interesting to experiment with 🍿 |
I just tried implementing a drag sortable list with removable items. The solution involved combining react-sortable-hoc and react-spring. It okays... slightly less than okay. The bit I'm struggling with is automatically animating items in/out as they are added/removed from the list. React Spring's solution is to their useTransition hook to handle mounting/unmounting items. It does not know how to animate a "collapse" animation. Imagine removing an item, it's height collapses from starting (e.g. 35px) to 0px. I haven't tried Framer Motion, but it looks like we may have to do something similar to achieve this effect. (😅 This is what I'm talkin' about when I've mentioned that Animation libraries should be easy to use. That being said, I'm aware of the difficulties in auto-animating height transitions). Custom Solution?A couple of years ago, I created a tiny library to handle this very thing. Easily (and almost automatically) handle transitions of items mounting and unmounting: https://github.com/helpscout/motion It handled the mount cycle part of React rendering, using anime.js under the hood as it's animation engine. Creating a mount/unmount wrapper looked like this: (Forgive the verboseness. This was during React 15 times, before hooks and performant functional components) I may revisit this 🤔 |
I just revisited https://github.com/aholachek/react-flip-toolkit I remember poking at it when it was announced a couple of years ago. Maybe some to draw some ideas from :) |
Welp! It looks like Framer Motion handles this beautifully! Add I need to add for this to happen is <motion.div exit={{height: 0}}>...</motion.div> This implementation alone might make Framer Motion the winner library 😂 (Seriously. I'm ecstatic with how this works. Coming from someone who has spent many manyyy hours working on/with animation engines and frameworks) |
Drag sorting looks pretty simple to implement as well! ❤️ Update: Nevermind. It's broken in Framer Motion v2. It's using some APIs that are no longer supported: |
I'm feeling pretty good about Framer Motion. Perhaps we can use it for the most Animation use cases. However, drag sorting can be accomplished by another library (like |
The built-in FLIP support for Framer Motion is incredible. Absolutely incredible. The following was (basically) enabled by adding This is the code that's needed to create this experience: const App = () => {
const [items, setItems] = useState(itemSchema.make(10));
const remove = (id) => {
setItems(items.filter((item) => item.id !== id));
};
const add = () => {
setItems([...items, itemSchema.makeOne()]);
};
const shuffle = () => {
const next = items.sort(() => Math.random() - 0.5);
setItems([...next]);
};
return (
<View css={{ margin: '20px auto', maxWidth: 500 }}>
<Spacer>
<Flex>
<Button onClick={add}>Add User</Button>
<Button onClick={shuffle}>Shuffle</Button>
</Flex>
</Spacer>
<Grid columns={3}>
{items.map((item, index) => (
<Card
animate={{
opacity: 1,
y: 0,
}}
as={motion.div}
exit={{
opacity: 0,
}}
initial={{ opacity: 0, y: 10 }}
key={item.id}
layout
>
<View css={{ padding: 8 }}>
<Flex>
<Text>{item.name}</Text>
<Button
icon={<View>X</View>}
onClick={() => remove(item.id)}
size="small"
variant="tertiary"
/>
</Flex>
</View>
</Card>
))}
</Grid>
</View>
);
}; |
That's looking super nice! Could you put together a CodeSandbox with that code? I think that would be a great test case for the sorting functionality on the Reakit Composite that I'm working on. :) |
@diegohaz You bet!!! Here it is 😊 |
Closing this up as the Animation x Style systems are feeling pretty good! https://github.com/ItsJonQ/g2/tree/master/packages/animations |
This one is an interesting one. It's the most exciting one for me (I like making things move), but arguably, the most difficult. The web is severely lacking when it comes to sequencing animations within UI, especially if it needs to handle mounting/unmounting (and diffing!).
What makes a good animation system?
Animations are hard. Really hard. These complexities are often felt by developers when trying to wrestle various settings and states together. It's more difficult when outside state is involved.
Here are some things that I think make a good animation system:
What I've Used
Previously, I've examined and used several libraries and engines, including Anime.js, React Spring, Pose, and others.
There are aspects I like in all of them. However, I've always felt like I had to make considerable (undesirable) trade-offs in one form or another. This often takes the form of overly verbose animation setups.
One library that shows the most potential is Framer Motion.
The APIs for Frame Motion is beautiful. It's very minimal. The provided
motion.div
components are incredibly intelligent. They know how to respond in isolation and with other animated components in sequence and in context.The biggest downside (that I can see) is the library's size. It's approx 28-29KB gzipped. Ouch.
However, the feature-set may be worth it 🤞 .
I think when we're ready to experiment with animations, it would be interesting to give Framer Motion a go 👍
The text was updated successfully, but these errors were encountered: