Are you a Bezier curve lover like I’m?
In addition to being elegant, Bezier curves have good mathematical properties as a consequence of their definition and building. No marvel they’re broadly utilized in so many areas:
As a drawing/design instrument: They’re usually refered to as “paths” in vector drawing software program.As a format of representing curves: They’re utilized in SVG, fonts and lots of different vector graphic codecs.As a mathematical operate: Usually used to regulate animation timing.
Now, how about utilizing Bezier curves as movement paths with CSS?
Fast Recap
Relying on the context, when referring to a “Bezier curve”, we frequently assume a 2D cubic Bezier curve.
Such a curve is outlined by 4 factors:
MarianSigler, Public area, through Wikimedia Commons
Word: On this article, we usually check with P0 and P3 as endpoints, P1 and P2 as management factors.
The phrase “cubic” means the underlying operate of the curve is a cubic polynomial. There are additionally “quadratic” Bezier curves, that are related, however with one fewer management level.
The Drawback
Say you’re given an arbitrary 2D cubic Beizer curve, how would you animate a component with pure CSS animation, such that it strikes exactly alongside the curve?
For example, how would you recreate this animation?
On this article we are going to discover three strategies with completely different flavors. For every answer we are going to current an interactive demo, then clarify the way it works. There are many mathematical calculations and proofs behind the scene, however don’t fear, we is not going to go very deep.
Let’s begin!
Technique 1: Time Warp
Right here’s the fundamental thought:
Arrange @keyframes to maneuver the aspect from one endpoint of the curve to the opposite.Distort the time for every coordinate individually, utilizing animation-timing-function.
Word: There are many examples and explanations in Temani Afif’s article (2021).
Utilizing the cubic-bezier() operate with right parameters, we will create a movement path of any cubic Bezier curve:
This demo reveals a pure CSS animation. But canvas and JavaScript are used, which serve two functions:
Visualize the underlying Bezier curve (crimson curve).Enable adjusting the curve with the everyday “path” UI.
You may drag the 2 endpoints (black dots) and the 2 management factors (black squares). The JavaScript code will replace the animation accordingly, by updating just a few CSS variables.
Word: Right here’s a pure CSS model for reference.
The way it works
Suppose the specified cubic Bezier curve is outlined by 4 factors: p0, p1, p2, and p3. We arrange CSS guidelines as following:
/* pseudo CSS code */
div {
animation-name: move-x, move-y;
/*
Outline:
f(x, a, b) = (x – a) / (b – a)
qx1 = f(p1.x, p0.x, p3.x)
qx2 = f(p2.x, p0.x, p3.x)
qy1 = f(p1.y, p0.y, p3.y)
qy2 = f(p2.y, p0.y, p3.y)
*/
animation-timing-function:
cubic-bezier(1/3, qx1, 2/3, qx1),
cubic-bezier(1/3, qy1, 2/3, qy2);
}
@keyframes move-x {
from {
left: p0.x;
}
to {
left: p3.x;
}
}
@keyframes move-y {
from {
high: p0.y;
}
to {
high: p3.y;
}
}
The @keyframes guidelines move-x and move-y decide the beginning and ending areas of the aspect. In animation-timing-function now we have two magical cubic-bezier() features, the parameters are calculated such that each high and left at all times have the right values at any time.
I’ll skip the maths, however I drafted a quick proof right here, in your curious math minds.
Discussions
This technique ought to work properly for many circumstances. You may even make a 3D cubic Bezier curve, by introducing one other animation for the z worth.
Nonetheless there are just a few minor caveats:
It doesn’t work when each endpoints lie on a horizontal or vertical line, due to the division-by-zero error.
Word: In follow, you possibly can simply add a tiny offset as a workaround.
It doesn’t help Bezier curves with an order increased than 3.Choices for animation timing are restricted.We use 1/3 and 2/3 above to attain a linear timing.You may tweak each values to regulate the timing, however it’s restricted in contrast with different strategies. Extra on this later.
Technique 2: Competing Animations
As a warm-up, think about a component with two animations:
div {
animation-name: move1, move2;
}
What’s the movement path of the aspect, if the animations are outlined as following:
@keyframes move1 {
to {
left: 256px;
}
}
@keyframes move2 {
to {
high: 256px;
}
}
As you might have guessed, it strikes diagonally:
Now, what if the animations are outlined like this as a substitute:
@keyframes move1 {
to {
rework: translateX(256px);
}
}
@keyframes move2 {
to {
rework: translateY(256px);
}
}
“Aha, you can not trick me!” you would possibly say, as you observed that each animations are altering the identical property, “move2 should override move1 like this:”
Properly, earlier I had thought so, too. However really we get this:
The trick is that move2 doesn’t have a from body, which implies the beginning place is animated by move1.
Within the following demo, the beginning place of move2 is visualized because the shifting blue dot:
Quadratic Bezier Curves
The demo proper above resembles the development of a quadratic Bezier curve:
Phil Tregoning, Public area, through Wikimedia Commons
However they give the impression of being completely different. The development has three linearly shifting dots (two inexperienced, one black), however our demo has solely two (the blue dot and the goal aspect).
Really the movement path within the demo is a quadratic Bezier curve, we simply have to tune the keyframes fastidiously. I’ll skip the maths and simply reveal the magic:
Suppose a quadratic Bezier curve is outlined by factors p0, p1, and p2. As a way to transfer a component alongside the curve, we do the next:
/* pseudo-CSS code */
div {
animation-name: move1, move2;
}
@keyframes move1 {
from {
rework: translate3d(p0.x, p0.y, p0.z);
}
/* outline q1 = (2 * p1 – p2) */
to {
rework: translate3d(q1.x, q1.y, q1.z);
}
}
@keyframes move2 {
to {
rework: translate3d(p2.x, p2.y, p2.z);
}
}
Just like the demo of Technique 1, you possibly can view or alter the curve. Moreover, the demo additionally reveals two extra items of knowledge:
The mathematical building (grey shifting elements)The CSS animations (blue elements)
Each will be toggled utilizing the checkboxes.
Cubic Bezier Curves
This technique works for cubic Bezier curves as properly. If the curve is outlined by factors p0, p1, p2, and p3. The animations needs to be outlined like this:
/* pseudo-CSS code */
div {
animation-name: move1, move2, move3;
}
@keyframes move1 {
from {
rework: translate3d(p0.x, p0.y, p0.z);
}
/* outline q1 = (3 * p1 – 3 * p2 + p3) */
to {
rework: translate3d(q1.x, q1.y, q1.z);
}
}
@keyframes move2 {
/* outline q2 = (3 * p2 – 2 * p3) */
to {
rework: translate3d(q2.x, q2.y, q2.z);
}
}
@keyframes move3 {
to {
rework: translate3d(p3.x, p3.y, p3.z);
}
}
Extensions
What about 3D Bezier Curves? Really, the reality is, all of the earlier examples have been 3D curves, we simply by no means bothered with the z values.
What about higher-order Bezier curves? I’m 90% positive that the tactic will be naturally prolonged to increased orders. Please let me know in case you have labored out the formulation for fourth-order Bezier curves, and even higher, a generic formulation for Bezier curves of order N.
Technique 3: Commonplace Bezier Curve Development
The mathematical building of Bezier Curves already provides us a very good trace.
Phil Tregoning, Public area, through Wikimedia Commons
Step-by-step, we will decide the coordinates of all shifting dots. First, we decide the placement of the inexperienced dot that’s shifting between p0 and p1:
@keyframes green0 {
from {
–green0x: var(–p0x);
–green0y: var(–p0y);
}
to {
–green0x: var(–p1x);
–green0y: var(–p1y);
}
}
Extra inexperienced dots will be constructed in an analogous approach.
Subsequent, we will decide the placement of a blue dot like this:
@keyframes blue0 {
from {
–blue0x: var(–green0x);
–blue0y: var(–green0y);
}
to {
–blue0x: var(–green1x);
–blue0y: var(–green1y);
}
}
Rinse and repeat, ultimately we are going to get the specified curve.
Just like Technique 2, with this technique we will simply construct a 3D Bezier Curve. It’s also intuitive to increase the tactic for higher-order Bezier curves.
The one draw back is the utilization of @property, which isn’t supported by all browsers.
Animation Timing
All of the examples to this point have the “linear” timing, what about easing or different timing features?
Word: By “linear” we imply the variable t of the curve linearly adjustments from 0 to 1. In different phrases, t is similar as animation progress.
animation-timing-function isn’t utilized in Technique 2 and Technique 3. Like different CSS animations, we will use any supported timing operate right here, however we have to apply the identical operate for all animations (move1, move2, and move3) on the identical time.
Right here’s an instance of animation-timing-function: cubic-bezier(1, 0.1, 0, 0.9):
And right here’s the way it appears like with animation-timing-function: steps(18, finish):
Then again, Technique 1 is trickier, as a result of it already makes use of a cubic-bezier(u1, v1, u2, v2) timing operate. Within the examples above now we have u1=1/3 and u2=2/3. In actual fact we will tweak the timing by altering each parameters. Once more, all animations (e.g., move-x and move-y) will need to have the identical values of u1 and u2.
Right here’s the way it appears like when u1=1 and u2=0:
With Technique 2, we will obtain precisely the identical impact by setting animation-timing-function to cubic-bezier(1, 0.333, 0, 0.667):
In actual fact, it really works in a extra common approach:
Suppose that we’re given a cubic Bezier curve, and we created two animations for the curve with Technique 1 and Technique 2 respectively. For any legitimate values of u1 and u2, the next two setups have the identical animation timing:
Technique 1 with animation-timing-function: cubic-bezier(u1, *, u2, *).Technique 2 with animation-timing-function: cubic-bezier(u1, 1/3, u2, 2/3).
Now we see why Technique 1 is “restricted”: with Technique 1 we will solely cubic-bezier() with two parameters, however with Technique 2 and Technique 3 we will use any CSS animation-timing-function.
Conclusions
On this article, we mentioned 3 completely different strategies of shifting parts exactly alongside a Bezier curve, utilizing solely CSS animations.
Whereas all 3 strategies are roughly sensible, they’ve their very own execs and cons:
Technique 1 is likely to be extra intuitive for these aware of the timing operate hack. However it’s much less versatile with animation timing.Technique 2 has quite simple CSS guidelines. Any CSS timing operate will be utilized immediately. Nonetheless, it could possibly be onerous to recollect the formulation.Technique 3 make extra sense for these aware of the maths building of Bezier curves. Animation timing can also be versatile. Then again, not all fashionable browsers are supported, due the utilization of @property.
That’s all! I hope you discover this text attention-grabbing. Please let me know your ideas!
Pure CSS Bezier Curve Movement Paths initially revealed on CSS-Methods, which is a part of the DigitalOcean household. You need to get the e-newsletter.
Subscribe to MarketingSolution.
Receive web development discounts & web design tutorials.
Now! Lets GROW Together!