Skip to content
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

docs(motion-presets): Motion Refresh / Presets RFC 2024 #2336

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 161 additions & 0 deletions rfcs/2024-08-21-motion-presets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
---
Start Date: 21-08-2024
RFC PR: (leave this empty if no PR yet)
Blade Issue: (leave this empty if no issue yet)
---

# Motion Presets RFC <!-- omit in toc -->

### Table Of Contents <!-- omit in toc -->

- [Summary](#summary)
- [Basic Example](#basic-example)
- [Motivation](#motivation)
- [Detailed Design](#detailed-design)
- [Drawbacks/Constraints](#drawbacksconstraints)
- [Alternatives](#alternatives)
- [Adoption strategy](#adoption-strategy)
- [How do we educate people?](#how-do-we-educate-people)
- [Open Questions](#open-questions)
- [References](#references)

# Summary

# Basic Example

Include a basic code example. Omit this section if it's not applicable.

# Motivation

- Why are we doing this?
- What use cases does it support?
- What is the expected outcome?

Try to focus on explaining the motivation so that if this RFC is not accepted, the motivation could be used to develop alternative solutions. In other words, try to list down the constraints you are trying to solve without coupling them too closely to the solution you have in mind.

# Detailed Design

## Library Comparison

### Goals of Ideal Library
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our goals should also tie in with design goals... evaluate libraries to see if something we want to do on design whether or not we can do it on dev. Good example you've added is morph animations... do we want to do morph now or later as per design?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup I've added morph and page transitions based on design expectations. We're doing morph now only.

Other things that are on design are simple opacity, slide, fade, etc transitions which are possible in every library


1. License (Preferrably free to use)
2. Hardware Accelarated Animations (Using CSS or [WAAPI](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API))
3. Easy to implement complex animations
4. React Router page transition support
5. Morph Animations / Layout Animations
6. Small bundle-size
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add Cross Platform as a goal as well? even though we might implement it later but we need to evaluate for RN as well. Eg: Vanilla CSS might not work on RN and we might as well use a diff lib for RN like ReAnimated

Copy link
Member Author

@saurabhdaware saurabhdaware Sep 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I can add as a note for react native here. Not sure if it'll make sense to add it as a factor in the library comparison table because no web animation library really supports react native so the library exploration for web and native will be different.

I can add a note saying how we use react-native-reanimated already and some of these presets can be built there. I saw that react-native-reanimated already supports a good amount of these presets. So we can re-export some of these with similar API in future - https://docs.swmansion.com/react-native-reanimated/docs/layout-animations/entering-exiting-animations


Lets compare some libraries over these ideals-

### Comparison Table

| **Goal** | **Framer Motion** | **Motion One** | **GSAP** | **Vanilla CSS Animations** |
| ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | -------------------------------------- | --------------------------------------------- |
| **License** (Preferrably free to use) | ✅ MIT | ✅ MIT | ❌ (Commercial License + Paid Plugins) | ✅ No License |
| **Hardware Accelarated Animations** | ✅ (Hybrid - WAAPI for some transformations with fallback to JS) [Hardware Accelarated POC](#hardware-accelarated-motion-using-framer-motion) | ✅ (Built on WAAPI) | ❌ | ✅ |
| **Easy to implement complex animations** | ✅ (Declarative API) | ❌ | ❌ | ❌ |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Motion one seems super light-weight. What is the difficulty in implementing animations with it? Can you add an example of an animation with framer vs with motion one?

Since we will be exposing presets to our end consumers won't it make sense to use a light-weight library within blade and abstract out complex animations within the presets?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will add more details here. Majority of things come from this article https://motion.dev/blog/should-i-use-framer-motion-or-motion-one (Find "Design goals" heading)

Overall its a low-level imperative API so requires us to call animate() function in vanilla JS and write react wrappers on top of it (which is something that we can do with CSS as well)

It lacks support for some important features like layout animations, page transitions, which we're expecting to do. So that will require custom implementation from scratch. It would've worked if we only had opacity, fade, transform transitions but we're doing more than that . If we implement such things from scratch, we'll anyway reach closer to framer-motion minified bundle.

There are projects like modular onboarding, frontend-website which are already using framer-motion and we have't seen load-time issues there. frontend-website had runtime laggy animation issues which are solved in their new update.

| **React Router Page Transition** | ✅ | ❌ (No native support but can be implemented) | ✅ | ❌ (No native support but can be implemented) |
| **Morph Animations / Layout Animations** | ✅ [Framer Motion POC](#morph-animations-with-framer-motion) | ❌ | ✅ | ❌ |
| **Small bundle size** | ❌ (4.6kb core + 40kb features that can be lazy loaded) | ✅ (4kb ) | ❌ (26kb core + features) | ✅ (0kb) |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets detail out the bundle size for framer motion. How will we load the core module only? In which cases will we need rest of the bundles?


There is also detailed comparison of these libraries at [Motion One Docs - Feature Comparisons](https://motion.dev/docs/feature-comparison#comparison-table)

## POCs

### Hardware Accelarated Motion using Framer Motion

https://github.com/user-attachments/assets/5aa7ba3f-666e-449c-ae1d-821f93c12962

<p align="right">
<a href="https://codesandbox.io/p/sandbox/framer-motion-enter-animation-forked-rk3tvd?file=%2Fsrc%2FApp.tsx%3A27%2C28"><img src="https://codesandbox.io/static/img/play-codesandbox.svg" /></a>
</p>

### Hardware Accelarated Motion using GSAP

> [!NOTE]
>
> While GSAP does offload some work to hardware using CSS, it still requires javascript to work and stops working if JS thread is blocked

https://github.com/user-attachments/assets/57593b19-3a19-4713-b768-9bcbf69097ee

<p align="right">
<a href="https://codesandbox.io/p/sandbox/framer-motion-hardware-accelarated-animations-forked-7qjyg9">
<img alt="Edit GSAP: Hardware Accelarated Animations " src="https://codesandbox.io/static/img/play-codesandbox.svg">
</a>
</p>

### Morph / Layout Animations with Framer Motion

https://github.com/user-attachments/assets/ad3d4a23-c3b9-4980-a051-a0f44e7224dc
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try doing the morph animation with blade components?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup will do that POC with API decision now

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should try to replicate the Switch animation and see how our primitives plays out.

Switch has a 2 stage animation

Click Hold (Elongate the circle) -> Release (De-elongate the circle + move to the opposite side)

Scale, transformX both will have to animate at once.


<p align="right">
<a href="https://codesandbox.io/p/sandbox/framer-motion-hardware-accelarated-animations-forked-q674t5">
<img alt="Edit Framer Motion: Morph Animations" src="https://codesandbox.io/static/img/play-codesandbox.svg">
</a>
</p>

## Goals

This is the bulk of the RFC. Explain the design in enough detail for somebody familiar with the Design System to understand, and for somebody familiar with the implementation to implement. This should get into specifics and corner-cases, and include examples of how the feature is used. Any new terminology should be defined here.

# Drawbacks/Constraints

Why should we _not_ do this? Maybe try to consider the following constraints

- Implementation cost, both in terms of code size and complexity.
- The impact of it on new as well as existing consumer projects.
- Cost of migration.

There are tradeoffs to choosing any path. Attempt to identify them here.

# Alternatives

What other designs/patterns/strategies have been considered?

# Adoption strategy

If we implement this proposal, how will existing consumer projects adopt it?

- Is this a breaking change?
- Can we write a codemod?
- How do we prioritise this with business and product folks?
- How do we communicate with other teams? Will updating docs suffice or do we need a dedicated interaction with them?

# How do we educate people?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets add how will we get this implemented on Figma for easing the hand-off as well here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup I'll update it here. We're still figuring out the right approach. We discussed few things yesterday, RK will just confirm it once if things are working fine or not


- How should this be taught to other folks?
- What names and terminology work best for these concepts and why?
- How is this idea best presented?

# Open Questions

- React Native support for presets?
- Should motion components be imported from `@razorpay/blade/components` like other components or `@razorpay/blade/motion`

# References

- ### Libraries

- [Framer Motion](https://www.framer.com/motion/)
- [Motion One](https://motion.dev/docs)
- [GSAP](https://gsap.com/)

- ### Design Systems with Motion Presets

- [Material UI - Transitions](https://mui.com/material-ui/transitions/)
- [Carbon - Motion (Only export easing curves to consumers)](https://carbondesignsystem.com/elements/motion/code)
- [Fluent UI - Motion APIs](https://react.fluentui.dev/?path=/docs/motion-apis-createmotioncomponent--docs)
- [Atlaskit by Atlassian - Motion Components](https://atlassian.design/components/motion/entering-motions/examples)

- ### Other Motion References

- [Framer Motion vs Motion One by Matt Perry (Creator of both libraries)](https://motion.dev/blog/should-i-use-framer-motion-or-motion-one)
- [Motion One vs Other Libraries - Feature Comparison](https://motion.dev/docs/feature-comparison)
- [Motion One & Browser Performance Guide](https://motion.dev/docs/performance)
- [Framer Motion - Hardware Accelarated Animations](https://www.framer.com/motion/animation/#hardware-accelerated-animations)
- [Release Date](https://github.com/framer/motion/blob/main/CHANGELOG.md#910-2023-02-23)
- [Framer Motion Hardware Accelearated Animations POC](https://codesandbox.io/p/sandbox/framer-motion-hardware-accelarated-animations-rk3tvd?file=%2Fsrc%2FApp.tsx%3A17%2C24)
- [View Transitions API - MDN](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API)
- [Web Animations API - MDN](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API/Using_the_Web_Animations_API)
- [CSS Triggers - What CSS property triggers which type of render](https://csstriggers.com/)
Binary file not shown.
Loading