Summary: This article mainly combines the previous SVG knowledge summary, through the example to achieve SVG animation. The main record animation drawing ideas, and the principle of the relevant source code implementation, the explanation of related properties.

SVG + CSS animation

SVG combined with CSS to achieve ring progress bar, square progress bar

Idea: Whether it is a square progress bar or a circular progress bar, the principle is to draw two identical circles or rectangles, one as the bottom, the other for animation. The outer display length is then controlled by the attribute Stroke-Dasharray. Then define the animation from the keyframe completely invisible, to fully visible by CSS, through the animation tween animation. After the implementation, it is found that the movement is not from the vertex of the circle, but from the coordinate point of the circle, then the transform:matrix(a b C D e f) attribute of SVG can be used to transform the coordinate.

stroke-dasharray

Stroke-dasharray =”x y” = solid line of x pixels, visible path. A Y pixel is a blank space

Ring progress bar implementation

  <svg width="200" height="200" viewBox="0 0 400 400"> <! - the radius is1006 -->
    <circle cx="200" cy="200" r="160" stroke-width="30" stroke="#D1D3D7" fill="transparent"></circle>
    <circle transform="matrix(0 -1 1 0 0 400)" class="circle" cx="200" cy="200" r="160" stroke-width="30" stroke="blue" fill="transparent"></circle>
  </svg>
Copy the code

Square progress bar implementation

  <svg width="200" height="200" viewBox="0 0 200 200">
    <rect x="0" y="0" width="200" height="200" fill="none" stroke="grey" stroke-width="8"></rect>
    <rect class="circle" x="0" y="0" width="200" height="200" fill="none" stroke="blue" stroke-width="8"  transform="The matrix (0, 1, 1,0,200,0)"></rect>
  </svg>
Copy the code

CSS animation styles are common

  @keyframes circle {
    from {
      stroke-dasharray: 1006 0;
    }
    to {
      stroke-dasharray: 0 1006;
    }
  }
  .circle {
    animation: circle 5s linear infinite;
  }
Copy the code

SVG combined with CSS to achieve logo stroke animation

The svgdom.getTotAllength () of the SVG element is used to calculate the path length of the LoGO, and then the strokeDasharray StrokeDasHoffset attribute is used to control the animation of the drawing process. The other tween processes then achieve an effect of color changes. Calculating the LOGO length

  const path = document.getElementById('singlePath')
  const pathLen = path.getTotalLength()
  console.log(pathLen);
Copy the code

stroke-dashoffset

Stroke – dashoffset: n. Moves the element n pixels from right to left

  <svg viewBox="0 0 1024 1024" width="200" height="200">
    <path id="singlePath" class="singlePath" fill="#ccc" d="M512.1129 963.711577 0-48.095259 - c - 23.93473-9.031974 - c - 600.62624-66.385006-27.32172 L109.964278 11.289967 479.371996-15.805954 283.603969 99.803308 164.381918 C61.643219-63.449614 153.54355-95.287321 245.66968-84.900551 66.385006 7.451378 124.867034 36.353693 166.414112 81.513561 40.86968-44.934068 98.674311-74.062183 164.607718-81.73936 93.029327-10.838368 185.607056 20.999338 248.153473 85.35215 115.609261 119.222051 111.093275 314.990077-10.38677 436.244322L578.272106 936.389857 C-18.289746 18.289746-42.224476 27.32172-66.159206 27.32172zM311.828886 145.188975c-61.869019 0-122.83484 24.386329-163.478721 66.385005-90.093936 92.803528-85.803749 245.89548 9.483573 341.182801l335.763616 335.763616c9.935171 9.935171 27.095921 9.935171 36.805292 0 l335. C95.287321 763616-335.763616-95.287321, 99.577508 to 248.379272 9.483573-341.182801-46.966262-48.772657-120.351047-73.836384-191.477839-65.481808-62.772216-7.225579-113.351268 38.385888 142.479383 87.384344 6.096582 10.16097 17.612348 16.709151 29.353914 16.709151-12.418964-0.903197-23.257332-6.322381-29.579713-16.257552 0 0-0.225799-0.225799-0.2258-0.451599-29.579713-48.546858-82.190959-80.384564-144.737376-87.384344-8.580375-0.451599-17.38 6549-0.903197-25.966924-0.903197 - z" p-id="803"></path>
  </svg>
  <style>
    .singlePath {
      fill: none;
      stroke: # 333;
      stroke-width: 1;
      animation: singlePath 5s linear infinite forwards;
    }
    @keyframes singlePath {
      10% {
        stroke-dasharray: 5564;
        stroke-dashoffset: 5564;
      }
      50% {
        stroke-dasharray: 5564;
        stroke-dashoffset: 0;
      }
      70% {
        stroke: green;
        fill:green
      }
      85% {
        stroke: blue;
        fill:blue
      }
      100% {
        stroke: red;
        fill:red
      }
    }
  </style>
Copy the code

Examples of SMIL animations in SVG

Hybrid animation

A block moves back and forth along the path, changing color as it moves. Add a variety of motion below the box, animateMotion track motion tag begin to understand the use of understanding

Use the begin

  • If there is no begin parameter or the begin parameter parsing exception is abnormal, the value is treated as 0.
  • Begin indicates the time when the animation begins. Begin is defined as a set of values separated by semicolons. A single value is only one of these cases and represents a time delay.

For example, beigin = “3 s. “5s” means that after 3s, the animation takes a walk. When the 6s animation to go again (if the animation did not go before, will immediately stop from the beginning). So, if an animation time is 3s, that is dur=”3s”, and there is no repeatCount attribute, we can see that the animation appears to execute twice in a row.

  • Begin’s single values include the following categories of values in addition to normal values
  1. Offset -value indicates the offset value, which is preceded by + or -. Should mean relative to the BEGIN value of the DOM
  2. Syncbase-value Specifies the value determined during synchronization. Syntax is: [element ID].begin/end +/- time value.

In other words, the begin value of another element can be added or subtracted from it. This is exactly how two separate elements can be cascaded

 <svg width="320" height="200">
    <text font-family="microsoft yahei" font-size="120" y="160" x="160">The horse<animate id="x" attributeName="x" to="60" begin="0s" dur="3s" fill="freeze" />
        <animate attributeName="y" to="100" begin="x.end" dur="3s" fill="freeze" />
    </text>
</svg>
Copy the code

As you can see, the begin value for an element attributeName y is x.end.x.end.x is the ID value of the animate element above, and end is an attribute that all animated elements have, the time when the animation ends. So begin=” x.nd “means that when the element with ID x is animated, I execute the animation. Very similar to the “after the last animation” option for PowerPoint animations.

We can also add offset values, such as begin=” x.endn-1s “, to indicate that the element with ID x begins to move vertically one second before the end of the animation.

  1. Event-value Specifies the value associated with the event. “Click to Execute this animation” is similar to PowerPoint animation. The syntax is: [element ID].[event type] +/- time value. For example, click on the circle in the image below and the horse will run by itself!
 <svg id="svg" width="320" height="200">
    <circle id="circle" cx="100" cy="100" r="50"></circle>
    <text font-family="microsoft yahei" font-size="120" y="160" x="160">The horse<animate attributeName="x" to="60" begin="circle.click" dur="3s" />
    </text>
</svg>
Copy the code

Begin =”circle. Click +2s”, where circle is the id of the circle element (black circle),click = click event, if you want to click on the circle for 2 seconds before the horse runs, it is easy to add the offset time to begin=”circle. Click +2s”. The main thing to note is that this kind of event-associated SVG needs to be inline in the page, otherwise the click stuff is useless.

Track motion mix animation

<svg width="200" height="200">
        <rect x="0" y="0" fill="red" width="10" height="10">
          <! Begin ="0", then only one round trip will be performed -->
          <animateMotion
            id="forward-rect"
            path="M10 10 L110 10 L110 110 L10 110"
            dur="2s"
            rotate="0"
            fill="freeze"
            begin="0; The back - the rect. End + 0.5 s"></animateMotion>
          <! -- begin="forward-reat.end" -->
          <animateMotion
            id="back-rect"
            path="M10 110 L110 110 L110 10 L10 10"
            dur="2s"
            rotate="0"
            fill="freeze"
            begin="Forward - the rect. End + 0.5 s"></animateMotion>
          <animate
            id='red-to-blue'
            attributeName="fill"
            attributeType="XML"
            from="red"
            to="blue"
            dur="2s"
            fill="freeze"
            begin="0; Blue - to - red. End + 0.5 s"></animate>
          <animate
            id='blue-to-red'
            attributeName="fill"
            attributeType="XML"
            from="blue"
            to="red"
            dur="2s"
            fill="freeze"
            begin="Red - to - blue. End + 0.5 s"></animate>
        </rect>
        <path
          d="M10 10 L110 10 L110 110 L10 110"
          fill="none"
          stroke="pink"
        ></path>
      </svg>
Copy the code

Click on the color displacement motion

    <svg viewBox="0 0 200 200" width="200" height="200">
      <g id="rect1">
        <rect x="0" y="0" rx="0" ry="0" width="100" height="100" fill="red">
          <animate
            attributeType="XML"
            attributeName="fill"
            from="red"
            to="green"
            begin="rect1.click"
            dur="2s"
            fill="freeze"/></rect>
      </g>
      <animateTransform
        attributeType="XML"
        attributeName="transform"
        type="translate"
        from="0, 0"
        to="50 to 50,"
        begin="rect1.click"
        dur="2s"
        fill="freeze"/>
      <rect x="0" y="100" width="100" height="100" fill="blue">
        <animate
          attributeType="XML"
          attributeName="fill"
          from="blue"
          to="yellow"
          begin="rect1.click"
          dur="2s"
          fill="freeze"/>
      </rect>
    </svg>
Copy the code