Closed alex-page closed 2 years ago
Great summary, Laura!
Recommendation:
--p-
+ duration-
+ value (Token name 1)--p-
+ easing-
+ css convention (Token name 1)Rationale: Descriptive, familiar, consistent – great base line. We can get creative with patterns and aliases later on top of this.
Recommendation:
Rationale:
*W3 CSS spec
Name | Equivalent to |
---|---|
ease | cubic-bezier(0.25, 0.1, 0.25, 1) |
ease-in | cubic-bezier(0.42, 0, 1, 1) |
ease-out | cubic-bezier(0, 0, 0.58, 1) |
ease-in-out | cubic-bezier(0.42, 0, 0.58, 1) |
linear | cubic-bezier(0, 0, 1, 1) |
Duration: Increments of 1/60 between 0 and 500ms [0, 16, 33, 50, 66, 83, 100, 116, ..., 450, 466, 483, 500] Duration: An increment based on the render budget of a frame at 60 fps gives us a true duration primitive and a base line for education and informed decisions making.
@johanstromqvist Can you expand on the rationale here? What do you mean by gives us true duration primitives and baseline education? I'm not used to thinking in FPS but rather delta time. For example, the first thing I do when starting a canvas project is setup frame independent delta time to counter act varying refresh rates between devices.
Additionally, I took a quick look around at other design systems and none seem to factor FPS in their tokens or educational content:
Also, I'm wondering how that will affect communication. Since every developer is already familiar with the concept of time (e.g. seconds and milliseconds). What benefit do we get from saying I want X
to animate from position A
to B
over 30 Frames
, rather than I want X
to animate from position A
to B
over half a second
?
Great questions @aaronccasanova – love that you're scrutinizing this!
First of all, why do we need so many values? Well, there are plenty of use cases that need values in between the 50 increments (and especially in between the 100s). If we don't provide them, animations will either need to conform to the system or be implemented off the system. So the question is – what are the most useful sub 50 values?
true duration primitives
What I referred to as a "primitive" here is what I think is "the smallest meaningful part", i.e. in the browser whether we specify 1ms
, 5ms
, 10ms
, or 15ms
, all those values round up to one frame (16.667ms). E.g. if you write transition-duration: 175ms
that's equivalent to 10.5 frames which means that 11 frames will render which is in fact 183ms
. This assumes a refresh rate 60 fps, but it's a useful framework at other frame rates too. Thinking out loud:
ms
and the device/browser will scale it to whatever it needs to be.baseline education
Frames connecting to fluid motion is the foundation of animation. Both designers and developers can make better decisions if they have a baseline understanding of the relationship between frames and UX, and frames and rendering.
From an Eng POV we need to understand concepts like frame budget, low performance and frame drops. And from a UX POV we need to understand why advanced animations need more frames to be clear, or that we sometimes need to simplify the animation concept to fit how many frames we can afford to spend. We have planned for a "smooth animations" project towards the end of 2022 where I think this narrative will be very helpful.
other design systems
Most systems do have values that fit this model as every increment of 50 equals 3 frames. Most of the time this is exactly what we need. 50ms
, 100ms
, 150ms
, 300ms
– check, check, great! The question is what we do between the 50s. Sometimes we need to tweak timing granularly. When we do, values like Adobe Spectrum's 190ms
and 220ms
are just inaccurate, as they will translate to 200ms
and 233ms
respectively. It's like fluff-specificity and adds a false sense of control. When you're looking for a visual result between the 50s, the only values that matter are 16, 33, 66 and 83.
Best case scenario, other systems look at ours and are inspired. Second best case, they look at ours point out why it's a total mess, and we learn and iterate. 😅
how it affects communication
We are definitely sticking to the concept of time. Durations are always expressed in ms
and we will almost always talk about milliseconds and seconds. The exception is physics based animation which I anticipate will be increasingly common.
For the sake of simplicity and approachability, our docs, patterns and default values should focus on the 50s and 100s. This will fit 90% of the use cases. The remaining 10% deals with the challenge of granular tweaking and should probably be an "advanced" sub section for those who need it. That's where the 16, 33, 66 and 83s will be valuable, and it's still all milliseconds. We're just using frame rate to find the most relevant ones. If the added complexity turns out to outweigh the benefits, we'll just scrap it. But I have yet to find a better tradeoff.
This work is complete. We can now create a new issue to iterate on the values and implementation. The tokens current tokens are in this file https://github.com/Shopify/polaris-react/blob/v8.0.0-major/src/tokens/_motion.ts
@alex-page Is there an issue for the value updates? Couldn't find one.
Feel free to make an issue in the backlog. It will need design guidance so if you have opinions it would be great to start there.
Created a follow up issue for the future easing and duration token value updates! 👆🏻
Audit Findings
I conducted a quick audit of all
duration()
andeasing()
instances in polaris-react.Below is a brief summary of those findings:
Duration
Easing
Proposed Token Values
Based on the values currently being used in the repo, here are some possible token names:
Duration
Easing
OR
cubic-bezier(0.4, 0.22, 0.28, 1)
OR
cubic-bezier(0.5, 0.1, 1, 1)
Questions
@johanstromqvist This was a quick and scrappy attempt at trying to bring together all the amazing work you've been doing on motion tokens. Please feel free to suggest other options than the ones I've provided!
Related Links