SVG Stroke animation, also known as “path drawing animation”, path stroke animation or path animation. The effect it achieves is similar to stroke, drawing the graph, that is, drawing along a line, so it is also called “line animation”.

SVG is an XML-formatted graphic, similar to the DOM, that can use CSS animations (keyframes) to achieve various dynamic effects.

Some animations may be possible using images or CSS, but SVG graphics can be zoomed in and out infinitely and animations are relatively simple to implement. It is more flexible than images, and CSS animation is more powerful than CSS animation alone.

Stroke animation principles (important)

Three attributes related to SVG stroke animations:

  • Stroke: Defines the color of the border.

  • Stroke-dasharray: Defines the lengths of dash and gap, and the values separating solid lines and intervals. Achieve dashed border effect, same as CSS dash effect. For example, stroke-dasharray:5, 5 means that the line is repeated with 5 solid lines and 5 intervals. The diagram below:

    Stroke-dasharray :5 also represents the solid line 5, dotted lines spaced 5 down. Stroke-dasharray :5, 3, 10 represents solid line 5, interval 3, solid line 10, then interval 5, solid line 3, interval 10, solid line 5… Continuous cycles fill the lines.

  • Stroke-dashoffset: Sets the starting position of the Dash line defined by Dasharray. A value of number | | percentage. Percentage is the viewport relative to SVG. Stroke animations are usually achieved in combination with Dasharray.

SVG line stroke animation is throughstroke-dashoffsetandstroke-dasharrayThe implementation is divided into two steps:

  1. Increment the solid line portion to the full length by Dasharray. For example, if the length of a path is 300, setting the stroke-dasharray value of path in SVG to 300,300 means that the path will be repeated with 300 solid lines and 300 intervals. So by default, we only see a solid line with a length of 300. The line segments that are 300 apart are invisible because they are already outside the canvas.

  2. At the same time, the new solid line is moved by stroke-dashoffset to create the effect of line segment movement. For example, stroke-dashoffset:500 becomes stroke-dashoffset:0.

Here’s an example of how stroke works:

A line 200 long.

<svg x="0px" y="0px" width="300px" height="100px" viewBox="0 0 300 100" class="svg1">
  <line x1="20" y1="50" x2="220" y2="50" stroke="# 000" stroke-width="1" ></line>
</svg>
Copy the code
.svg1{
   border: 2px solid red;
}
.svg1 line {
   stroke-dasharray:200.200;
   stroke-dashoffset:200;
}
Copy the code

Because stroke-dasharray and stroke-Dashoffset both have values of 200, this line segment displays a gap of length 200, with no lines. Set the stroke-Dashoffset value to 0, and the DASH line segment is displayed, as shown in the following GIF:

In fact, as long as the gap length is greater than the length of the line segment and dashoffset is the same length as the gap, dash should be the same length as the line segment. The best part is that all four are the same.

The spacing should be the length of the solid line

Another way to achieve stroke animation is to increase the length of the solid line in the dashed line by adjusting it so that it gradually takes up the entire line segment. This eliminates the need to involve stroke offset adjustments.

Using this principle, you can easily create a stroke animation with CSS transition or animation:

.svg1{
   border: 2px solid red;
}

/* js toggle class */
.svg1 line {
   stroke-dasharray:200.200;
   stroke-dashoffset:200;
   transition:all 2s linear;
}
.svg1.move line{
   stroke-dashoffset:0;
}
Copy the code
let body=document.getElementsByTagName('body') [0];
body.addEventListener('click'.() = >{
   var svg1=document.querySelector('.svg1');
   svg1.classList.toggle('move');
});
Copy the code

Change the stroke by clicking on class.

  • css animation
/* css animation */
.svg1 line {
    stroke-dasharray:200.200;
    stroke-dashoffset:200;
    animation: moveline 2s linear infinite;
}
@keyframes moveline {
    50% {
        stroke-dashoffset:0;
    }
    100%{
        stroke-dashoffset:-200; }}Copy the code

Note:

For stroke animation, although the total length of stroke should remain the same, the speed of drawing can be realized by changing the length of dashed line, which requires the coordination of solid line and time. The reason is that the shorter line segment must move faster than the longer line segment at the same time to complete the drawing (offset size).

In order to optimize the effect, the path animation of multiple graphics can also be delayed, adjust the execution time, etc., to achieve better effect.

SVG CSS Stroke animation

Stroke animation:stroke animation. Or path drawing animation:path drawing animation, sometimes called path stroke animation, path animationpath animation

Stroke animation example

Complete an animation that looks like this:

This animation consists of a color fill animation, stroke animation and zoom animation.

Take a look at the code for an SVG image, which consists of a circle and a pair of paths, and look at the effect by default

<svg class="checkmark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">
  <circle class="checkmark__circle" cx="26" cy="26" r="25" fill="none" stroke="black" />
  <path class="checkmark__check" fill="none" stroke="black" d="M14.1 l7.1 7.2 27.2 16.7 16.8"/>
</svg>
Copy the code

The purpose of the viewBox is to render images to SVG in full, or with a set view, making it easy to resize the SVG without affecting the graphics you see. This can be seen in test use

The initial state of the original animation is empty (individual elements are not displayed), and the animation that needs to be stroked is the circle and the middle tick.

Initially, you need to set circle fill to None with no fill color, and stroke-dasharry and stroke-dashoffset to circle length values. Set the stroke-dasharry and stroke-dashoffset values of the PATH element to the length value of path. To get the length value, you can use getTotalLength(), as described in the next section

/* Define SVG */
.checkmark {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    stroke-width: 2;
    stroke: #fff;
    box-shadow: inset 0px 0px 0px #7ac142; 
}

/* Initializes the circle */
.checkmark__circle {
    stroke-dasharray: 157;
    stroke-dashoffset: 157;
    stroke: #7ac142;
    fill: none;
}
/* Check */ for initialization
.checkmark__check {
    transform-origin: 50% 50%;
    stroke-dasharray: 34;
    stroke-dashoffset: 34;
}
Copy the code

Stroke animation for circles and strokes, keyframes with the target state set to 0 for stroke-dashoffset:

@keyframes stroke {
  100% {
    stroke-dashoffset: 0; }}Copy the code

Fill and zoom animations:

@keyframes scale {
  0%.100% {
    transform: none;
  }
  50% {
    transform: scale3d(1.1.1.1.1); }}@keyframes fill {
  100% {
    box-shadow: inset 0px 0px 0px 30px #7ac142; }}Copy the code

The complete code is as follows:

<svg class="checkmark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">
    <circle class="checkmark__circle" cx="26" cy="26" r="25" fill="none" />
    <path class="checkmark__check" fill="none" d="M14.1 l7.1 7.2 27.2 16.7 16.8" />
</svg>
Copy the code
/* Define SVG */
.checkmark {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    stroke-width: 2;
    stroke: #fff;
    box-shadow: inset 0px 0px 0px #7ac142; 
    animation: fill .4s ease-in-out .4s forwards, scale .3s ease-in-out .9s both;
}

.checkmark__circle {
    stroke-dasharray: 157;
    stroke-dashoffset: 157;
    stroke: #7ac142;
    fill: none;
    animation: stroke 0.6 s cubic-bezier(0.65.0.0.45.1) forwards;
}

.checkmark__check {
    transform-origin: 50% 50%;
    stroke-dasharray: 34;
    stroke-dashoffset: 34;
    animation: stroke 0.3 s cubic-bezier(0.65.0.0.45.1) 0.8 s forwards;
}

@keyframes stroke {
    100% {
        stroke-dashoffset: 0; }}@keyframes scale {
    0%.100% {
        transform: none;
    }
    50% {
        transform: scale3d(1.1.1.1.1); }}@keyframes fill {
    100% {
        box-shadow: inset 0px 0px 0px 30px #7ac142; }}Copy the code

usegetTotalLength()Gets the length of an SVG graphic element

You can use JavaScript’s API to get the length of the entire path with just two lines of code:

let path = document.querySelector('path');
let p_length = path.getTotalLength();
Copy the code

Similarly, the length of a circle can be obtained using getTotalLength()

let circle = document.querySelector('circle');
let c_length = circle.getTotalLength();
Copy the code

The length of an SVG graphic element can be seen in the AI’s “Document Info” panel:

Path Multipath stroke animation processing

Take a look at the following hexagonal SVG:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
	 viewBox="0 0 300 200" xml:space="preserve">
<path  class="st0" fill="green" stroke="# 000" d="M181.5, 32, 111 l - l - 31.6-18.7 l0.4 36.7 l32-18 l31 flashes. 6,18.7 L181.5, 111 z M181.7 l0.3 111.4 to 0.1 L0.4 37.3 l - 32.1-19-32.5 l and 18.3 l - 0.4, 37.3 l32.1, 19 l181. 7111 activity have z M118.8, l31.1 l31.5 73.9-17.8, 18.4-0.4 l and 36.1 l - 31.5, 17.8 l - 31.1-18.4 L118.8, 73.9 z"/>
</svg>
Copy the code

Add the following CSS for stroke animation:

.st0{
    stroke-dasharray: 670 670;
    stroke-dashoffset:670;
    animation: st0move 3s linear;
}
@keyframes st0move {
    0%{
        stroke-dashoffset:0;
    }
    100%{
        stroke-dashoffset: 670; }}Copy the code

You can see that the animation is “messy”,

This is because the path path uses more than one graphic path, so you can’t control the starting position of the path. Using stroke animation, multiple lines change together, and you can’t control the order. Cause changes are very messy.

To control the order of paths in a path, you can split multiple paths in the path (the multipath set in d is split into multiple single paths).

One is to disassemble it directly through the code; Or in AI, use the pen tool to outline the path stroke by stroke and export it as a path element.

Modified as follows:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
	 viewBox="0 0 300 200" xml:space="preserve">
    <path  class="st0" fill="green" stroke="# 000" d="M181.5, 32, 111 l - l - 31.6-18.7 l0.4 36.7 l32-18 l31 flashes. 6,18.7 L181.5, 111 z"/>
    <path  class="st0" fill="green" stroke="# 000" d="M181.7, 111.4 l0.4 l0.3-0.1-37.3 l - 32.1-19-32.5 l and 18.3 l - 0.4, 37.3 l32.1, 19 l181. 7111 activity have z"/>
    <path  class="st0" fill="green" stroke="# 000" d="M118.8 l31.1 l31.5 73.9-17.8, 18.4 l - 0.4, 36.1 l - 31.5, 17.8 l - 31.1-18.4 L118.8, 73.9 z"/>
</svg>
Copy the code
.st0{
    stroke-dasharray: 670 670;
    stroke-dashoffset:670;
    animation: st0move 2s linear forwards;
}
@keyframes st0move {
    0%{
        stroke-dashoffset:0;
    }
    100%{
        stroke-dashoffset: 670; }}.st0:nth-child(2) {
    animation-delay: 1s;
}
.st0:nth-child(3) {
    animation-delay: 2s;
}
Copy the code

Multiple paths in a path can be much more complicated in practice, but this is just an illustration. It is also annoying to process, and may need to be combined with other animation principles, but the key is to make the implementation elements in the graphics reasonable and easy to control.

In this example, the hexagon in the middle is not changed, just a closed line around the edge of the hexagon is fine, but the original SVG code uses a lot of lines, which makes movement and control very ugly.

This article is part of the “Gold Nuggets For Free!” Event, click to view details of the event