15
头图

There is a very interesting module in CSS Motion Path Module Level 1 , which translates to motion path. This article will take a closer look at the motion path. Through this article, you can learn:

  • What is CSS motion path
  • Use CSS motion path to make simple path animation
  • Use CSS motion path to make complex path animations

What is CSS Motion Path?

What is CSS Motion Path? Using the attributes specified in this specification, we can control the animation of the element's position transformation according to a specific path. Moreover, this path can be a very complicated path.

Before we further introduce CSS Motion Path, let's take a look at the ability of using traditional CSS and how we can achieve path animation.

CSS traditional way to achieve linear path animation

Before, we wanted to move an object from point A to point B in a straight line. Generally speaking, transform: translate() , top | left | bottom | right or margin can be used to change the position of the object.

A simple Demo:

<div>
div {
    width: 60px;
    height: 60px;
    background: #000;
    animation: move infinite 1s alternate linear;
}
@keyframes move {
    100% {
        transform: translate(100px, 100px);
    }
}

The effect of a simple linear movement from point A to point B is as follows:

CSS traditional way to achieve curve path animation

Of course, CSS can also implement some simple curve path animations. What if we want to move from point A to point B instead of a straight line, but a curve?

For some simple arc curve paths, you can still use some clever ways to achieve, take a look at the following example.

This time, we used two elements. The child element is a small ball that wants to be moved by a curve, but in fact, we set the parent element's transform-origin to make the parent element perform a transform: rotate() to drive the small ball of the child element. ball:

<div class="g-container">
    <div class="g-ball"></div>
</div>
.g-container {
    position: relative;
    width: 10vmin;
    height: 70vmin;
    transform-origin: center 0;
    animation: rotate 1.5s infinite alternate;
}
.g-ball {
    position: absolute;
    width: 10vmin;
    height: 10vmin;
    border-radius: 50%;
    background: radial-gradient(circle, #fff, #000);
    bottom: 0;
    left: 0;
}
@keyframes rotate {
    100% {
        transform: rotate(90deg);
    }
}

In order to facilitate understanding, during the movement, I let the outline of the parent element appear:

In this way, we can barely get a non-straight path motion animation, and its actual motion trajectory is a curve.

However, this is basically the limit that CSS can do before. Using pure CSS, there is no way to achieve more complex path animations, such as the following path animation:

Till now, we have a more powerful specification for doing this, which is the protagonist of this article- CSS Motion Path .

CSS Motion Path realizes linear path animation

The CSS Motion Path specification mainly includes the following properties:

  • offset-path : Receive an SVG path (similar to SVG path and clip-path in CSS), and specify the geometric path of motion
  • offset-distance : Control the distance of the current element based on the offset-path
  • offset-position : Specify the initial position of offset-path
  • offset-anchor : Define the anchor point of the element positioned offset-path This is easy to understand. The element of motion may not be a point, so you need to specify which point of the element is attached to the path to move.
  • offset-rotate : Define the direction offset-path . Human words are the angular orientation of the element during movement

Next, we use Motion Path to implement a simple linear displacement animation.

<div>
div {
    width: 60px;
    height: 60px;
    background: linear-gradient(#fc0, #f0c);
    offset-path: path("M 0 0 L 100 100");
    offset-rotate: 0deg;
    animation: move 2000ms infinite alternate ease-in-out;
}
@keyframes move {
    0% {
        offset-distance: 0%;
    }
    100% {
        offset-distance: 100%;
    }
}

offset-path receives an SVG path path, where our path content is a custom path path("M 0 0 L 100 100") , which translates to moving 0 0 100px 100px .

offset-path receives an SVG path and specifies the geometric path of the movement. Similar to the SVG path and the clip-path in CSS, if you don’t know much about this SVG Path, you can here to understand the content of the SVG path: 1608abbebeb1e9 SVG path

We will get the following result:

By controlling element offset-distance from 0% changes to 100% path animation elements.

Of course, the above animation is the most basic. I can make full use of the characteristics of path, add multiple intermediate key frames, and slightly modify the above code:

div {
    // 只改变运动路径,其他保持一致
    offset-path: path("M 0 0 L 100 0 L 200 0 L 300 100 L 400 0 L 500 100 L 600 0 L 700 100 L 800 0");
    animation: move 2000ms infinite alternate linear;
}
@keyframes move {
    0% {
        offset-distance: 0%;
    }
    100% {
        offset-distance: 100%;
    }
}

L here is to use the 0608abbebeb254 instruction in path to get a straight path like the following figure:

image

The final effect is as follows, similar to using transform: translate() add multiple key frames:

The complete Demo you can here: 1608abbebeb299 CodePen Demo - CSS Motion Path Demo

CSS Motion Path realizes curve path animation

The above motion trajectories are all composed of straight lines, let's see how to use CSS Motion Path to achieve curve path animation.

In fact, the principle is exactly the same, just add the curve-related path offset-path: path()

In the SVG Path, we take one of the methods of drawing curves-Bezier curve, such as the following path, where the path is d="M 10 80 C 80 10, 130 10, 190 80 S 300 150, 360 80" :

<svg width="400" height="160" xmlns="http://www.w3.org/2000/svg">
  <path d="M 10 80 C 80 10, 130 10, 190 80 S 300 150, 360 80" stroke="black" fill="transparent"/>
</svg>

Corresponding to such a continuous Bezier curve:

Apply the corresponding path in offset-path: path :

<div>
div:nth-child(2) {
    width: 40px;
    height: 40px;
    background: linear-gradient(#fc0, #f0c);
    offset-path: path('M 10 80 C 80 10, 130 10, 190 80 S 300 150, 360 80');
}
@keyframes move {
    0% {
        offset-distance: 0%;
    }
    100% {
        offset-distance: 100%;
    }
}

The following exercise effects can be obtained:

It can be seen that the element is moving along the path of the Bezier curve, and since there is no limit offset-rotate this time, the orientation of the element also keeps changing with the orientation of the path. (It can be thought of as when driving, the front of the car will always follow the road and will change, driving the angle of the entire body to change)

The complete Demo you can here: 1608abbebeb3a4 CodePen Demo - CSS Motion Path Demo

Understand the offset-anchor motion anchor point

OK, so next, let's take a look at how offset-anchor understands.

Still the above DEMO, we replace the small square with a triangle, and draw the curve of motion on the page, like this:

Among them, the triangle is realized by clip-path :

    width: 40px;
    height: 40px;
    clip-path: polygon(0 0, 100% 50%, 0 100%);
    background: linear-gradient(#fc0, #f0c);

Generally speaking, what moves along the curve is the center point of the object (analogous to transform-origin ). Here, we can offset-anchor . For example, we want the bottom of the triangle to move along the curve:

.ball {
    width: 40px;
    height: 40px;
    clip-path: polygon(0 0, 100% 50%, 0 100%);
    offset-path: path('M 10 80 C 80 10, 130 10, 190 80 S 300 150, 360 80');
    offset-anchor: 0 100%;
    background: linear-gradient(#fc0, #f0c);
    animation: move 3000ms infinite alternate linear;
}
@keyframes move {
    0% {
        offset-distance: 0%;
    }
    100% {
        offset-distance: 100%;
    }
}

After actual measurement, Can i use says offset-anchor is Chrome 79+ and Firefox 72+, but it is actually only supported by Firefox, and it cannot take effect temporarily under Chrome~

here for the complete Demo: 1608abbebeb4a4 CodePen Demo - CSS Motion Path offset-anthor Demo

Use Motion Path to make animation effects

OK, we have basically given the principle above, let's take a look at how to use Motion Path in practice.

Use Motion Path to make button effects

Using the motion path, we can make some simple button click effects. Before, I have seen such a button click effect on CodePen:

The principle is to use background-radial to generate each small dot, and control background-position . You can click here for the detailed Demo code:

CodePen Demo -- Bubbly button (Design by Gal Shir)

However, the motion path of the small dots is basically a straight line. Using the Motion Path of this article, we can also achieve some similar effects. The core code is as follows. Here we use the Pug template, and the CSS uses SASS :

.btn
  -for(var i=0; i<60; i++)
    span.dot
.btn {
  position: relative;
  padding: 1.5rem 4.5rem;
}
.btn .dot {
  position: absolute;
  width: 4px;
  height: 4px;
  
  @for $i from 1 through $count { 
    &:nth-child(#{$i}) {
        top: 50%;
        left: 50%;
        transform: translate3d(-50%, -50%, 0) rotate(#{360 / $count * $i}deg);
      }
  }
  
  &::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    offset-path: path("M0 1c7.1 0 10.7 2 14.3 4s7.1 4 14.3 4 10.7-2 14.3-4 7.2-4 14.3-4 10.7 2 14.3 4 7.1 4 14.3 4 10.7-2 14.3-4 7.1-4 14.3-4 10.7 2 14.3 4 7.1 4 14.3 4 10.7-2 14.3-4 7.1-4 14.3-4 10.7 2 14.3 4 7.1 4 14.3 4");
    offset-distance: 0;
  }
}

.btn.is-animating:active .dot:nth-child(4n+1)::before {
  animation: dot var(--animation-time) var(--animation-timging-function);
}
.btn.is-animating:active .dot:nth-child(4n+2)::before {
  border: 1px solid var(--color-primary);
  background: transparent;
  animation: dot var(--animation-time) var(--animation-timging-function) 0.1s;
}
.btn.is-animating:active .dot:nth-child(4n+3)::before {
  animation: dot var(--animation-time) var(--animation-timging-function) 0.2s;
}
.btn.is-animating:active .dot:nth-child(4n)::before {
  border: 1px solid var(--color-primary);
  background: transparent;
  animation: dot var(--animation-time) var(--animation-timging-function) 0.3s;
}

@keyframes dot {
  0% {
    offset-distance: 0%;
    opacity: 1;
  }
  90% {
    offset-distance: 60%;
    opacity: .5;
  }
  100% {
    offset-distance: 100%;
    opacity: 0;
  }
}

Don’t look at the code a little more complicated, but it’s not difficult to understand. The essence is to set the same offset-path: path() for each child element, set different rotation angles for the child elements under different groups, and use the animation delay animation-delay set 4 sets of animations starting at the same time.

Here our trajectory path is not a straight line, the effect is as follows:

You can click here for the complete code:

CodePen Demo -- Button Animation with CSS Offset Paths

Use Motion-Path to draw the pathfinding animation of the map path

This is also very practical. Now we can fully use CSS Motion-Path to realize the wayfinding animation on the map:

The Demo is derived from Ahmad Emran. You can click here for the complete code:

CodePen Demo -- CodePen Home Animation with offset-path | Only Using CSS & HTML

Use Motion-Path to draw path animation

Or, we can use the feature of Path to draw arbitrary paths to achieve all kinds of paths we want, such as adding a parabola to the shopping cart, or various motion trajectories, not to mention, here is another demo:

CodePen Demo -- CSS Motion Path offset-path animation

Can i Use - Motion-Path

Let's take a look at the current compatibility of Motion-Path? As of 2021-04-27.

Can i Use - Motion-Path

At present, except for the IE browser, it is necessary to wait for when Safari will be compatible, and whether to use it or not, it is also necessary to make a decision based on the browser usage of the target group.

At last

Well, this concludes this article. I introduce the Motion Path animation, and use it to achieve some path animation effects that could not be easily achieved in the past. I hope it will be helpful to you :)

If you want to get the most interesting CSS information, don’t miss my account - 1608abbebeb6eb iCSS front-end interesting 1608abbebeb6ed 😄

gzh_sssmall.png

More exciting CSS technical articles are summarized in my Github - iCSS , which is continuously updated, welcome to click a star to subscribe to the collection.

If you have any questions or suggestions, you can exchange more, original articles, limited writing style, and lack of knowledge. If there are any irregularities in the article, please let me know.


chokcoco
12.3k 声望18.5k 粉丝