preface

The last article introduced the use of common elements in SVG. This article, mainly to <path> detailed introduction, including path path parameters and path common some animation effects are explained.

The articles

Set foot on SVG | construct comprehensive functions and characteristics of SVG based article (a) –

Set foot on SVG | construct comprehensive functions and characteristics of SVG – base (2) of article

path

Path can be used for rectangles, circles, lines, and all the other shapes mentioned in the previous article. It can also be used for more complex shapes by setting paths. It has its own set of syntax rules that define paths, just as if you were drawing with a pen.

Here are some of the basic uses of path. If you already know, you can look directly at the path animation section

Basic attributes:

  • D: a point-set number column and other information about how to draw a path.

Sequence instruction D

The value of attribute D is a sequence of commands + arguments

Each command is represented by a key letter, for example, the letter “M” for a “Move to” command, and when the parser reads the command, it knows that you intend to Move to a certain point. Following the command letter are the x and y coordinates of the point to which you need to move. For example, the command to move to the point (10,10) should be written as “M 10,10”. When this character is finished, the parser reads the next command. Each command can be represented in two ways, one in capital letters, indicating absolute positioning. The other is to use lowercase letters to indicate relative positioning (for example, move 10px up and 7px to the left from the previous point).

Move To

Move the brush, just move the brush, no wires

Command:

  • M x y (the absolute coordinates of the target point on the canvas)
  • M dx dy (coordinates of the target point relative to the previous point)

Line To

The target point line connects the current point directly to the target point

Command:

  • L x y (the absolute coordinates of the target point on the canvas)
  • L dx dy (coordinates of the target point relative to the previous point)

Horizontal

Draw a horizontal line

Command:

  • H x (the x position value of the canvas moved horizontally (absolute position))
  • H dx (moving dx distance horizontally from the current point (relative position))

Vertical

Draw a vertical line

Command:

  • V y (y position value of the canvas vertically moved to (absolute position))
  • V dy (move dy distance horizontally from current point (relative position))

Close Path

Close the path, connecting the last point to the start point. In actual measurement, path is automatically closed

Command:

  • Z or Z (both are the same)

Cubic Béziers

Cubic Bezier curves require a given target point and two control points

Command:

  • C x1 y1, x2 y2, x y
  • C dx1 dy1, dx2 dy2, dx dy.

The S command can be used to create the same Bezier curve as before, but if the S command follows a C or S command, its first control point is assumed to be the central symmetry point of the second control point of the previous command curve. If the S command is used alone, with no C or S command preceding it, the current point is used as the first control point.

Command:

  • S x2, y2, x, y (absolute coordinates)
  • S dx2 dy2, dx dy.

Quadratic Béziers

The quadratic Bezier curve Q, which is simpler than the cubic Bezier curve, requires only one control point, which is used to determine the slope of the curve at the beginning and end

Command:

  • Q x1 y1, x y (absolute coordinates)
  • Q dx1 dy1, dx dy (relative coordinates)

The T command is similar to the S of the cubic Bezier curve, used to extend the quadratic Bezier curve, and requires only one target point

Command:

  • T x y (absolute coordinates)
  • T dx dy relative coordinates

Arcs

The arc command A is another command to create an SVG curve. Basically, an arc can be considered part of a circle or an oval. Suppose, given the radius of the major axis and the radius of the minor axis of the ellipse, and given two points (on the ellipse), two ellipses can be drawn based on the radius and two points, and two arcs can be drawn on each ellipse based on two points.

Command:

  • A rx ry X-axis rotation large-arc-flag sweep-flag x y (absolute coordinates)
  • A rx ry x-axis-rotation large-Arc-flag sweep-flag dx dy (relative coordinates)

example

 <! -- L, L command draw w:100 h:40 rectangle -->
  <svg class="border" width="200" height="200" viewBox="0 0 200 200">
    <path d="M 10 10 L 110 10 L 110 50 L 10 50" fill="orange"/>
  </svg>
  <svg class="border" width="200" height="200" viewBox="0 0 200 200">
    <path d="M 10 10 l 100 0 l 0 40 l -100 0" fill="orange"/>
  </svg>

  <br/>
  <! -- H/V, H/V command draw w:100 H :40 rectangle -->
  <svg class="border" width="200" height="200" viewBox="0 0 200 200">
    <path d="M 10 10 H 110 V 50 H 10" fill="orange"/>
  </svg>
  <svg class="border" width="200" height="200" viewBox="0 0 200 200">
    <path d="M 10 10 h 100 v 40 h -100" fill="orange"/>
  </svg>

  <br/>
  <! -- Z/ Z command shutdown and path -->
  <! -- Path seems to be closed by default -->
  <svg class="border" width="200" height="200" viewBox="0 0 200 200">
    <path d="M 10 10 H 110 V 50 H 10 z" fill="orange"/>
  </svg>
Copy the code
 <div>C</div>
  <svg class="border" width="200" height="200" viewBox="0 0 200 200">
    <path d="M 10 100 C 40 50 70 150 110 100" stroke="orange" fill="transparent" stroke-width="3" stroke-linecap="round"/>
  </svg>

  <svg class="border" width="200" height="200" viewBox="0 0 200 200">
    <path d="M 10 100 c 30 -50 60 50 100 0" stroke="orange" fill="transparent" stroke-width="3" stroke-linecap="round"/>
  </svg>
  <div>S</div>
  <br/>
  <svg class="border" width="200" height="200" viewBox="0 0 200 200">
    <path d="M 10 100 C 40 50 70 150 110 100 S 150 150 190 100" stroke="orange" fill="transparent" stroke-width="3" stroke-linecap="round"/>
  </svg>

  <div>Q</div>
  <svg class="border" width="200" height="200" viewBox="0 0 200 200">
    <path d="M 10 100 Q 60 180 110 100" stroke="orange" fill="transparent" stroke-width="3" stroke-linecap="round"/>
  </svg>

  <svg class="border" width="200" height="200" viewBox="0 0 200 200">
    <path d="M 10 100 q 50 80 100 0" stroke="orange" fill="transparent" stroke-width="3" stroke-linecap="round"/>
  </svg>

  <div>T</div>
  <! -- Happy painting waves -->
  <svg class="border" width="200" height="200" viewBox="0 0 200 200">
    <path d="M 10 100 Q 30 180 50 100 T 90 100 T 130 100 T 170 100 T 210 100" stroke="orange" fill="transparent" stroke-width="3" stroke-linecap="round"/>
  </svg>

  <div>A</div>

  <svg class="border" width="200" height="200" viewBox="0 0 200 200">
    <! -- Starting point 10 100 -->
    <! X = sx + rx y = xy + ry -->
    <! Move to the center of the circle to complete the line -->
    <path d="M10 100 A 40 40 0 0 0 50 140 L 50 100 Z" stroke="orange" fill="green" stroke-width="3" stroke-linecap="round"/>
  </svg>
  <br>
  <! - small arc - >
  <svg class="border" width="200" height="200" viewBox="0 0 200 200">
    <path d="M80 100 A 40 40 0 0 0 120 140 " stroke="orange" fill="green" stroke-width="3" stroke-linecap="round"/>
  </svg>
  <! - big arc - >
  <svg class="border" width="200" height="200" viewBox="0 0 200 200">
    <path d="M80 100 A 40 40 0 1 0 120 140 L 120 100 Z" stroke="orange" fill="green" stroke-width="3" stroke-linecap="round"/>
  </svg>

  <br/>
  <! -- Draw an arc from start to finish -->
  <svg class="border" width="200" height="200" viewBox="0 0 200 200">
    <path d="M80 100 A 40 40 0 1 0 120 140" stroke="orange" fill="green" stroke-width="3" stroke-linecap="round"/>
  </svg>
  <! -- Draw an arc from the end to the beginning -->
  <svg class="border" width="200" height="200" viewBox="0 0 200 200">
    <path d="M80 100 A 40 40 0 1 1 120 140 L 120 100 Z" stroke="orange" fill="green" stroke-width="3" stroke-linecap="round"/>
  </svg>
  <br />
  <svg class="border" width="325px" height="325px" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <path d="M80 80 A 45 45, 0, 0, 0, 125 125 L 125 80 Z" fill="green" stroke="orange" stroke-width="3"/>
    <path d="M230 80 A 45 45, 0, 1, 0, 275 125 L 275 80 Z" fill="red" stroke="orange" stroke-width="3"/>
    <path d="M80 230 A 45 45, 0, 0, 1, 125 275 L 125 230 Z" fill="purple" stroke="orange" stroke-width="3"/>
    <path d="M230 230 A 45 45, 0, 1, 1, 275 275 L 275 230 Z" fill="blue" stroke="orange" stroke-width="3"/>
  </svg>

Copy the code

Common path animations

Here are three common animations for Path.

Stroke animation

As shown in the figure below

This is done using stroke-Dasharray, stroke-Dashoffset, and animation

A brief explanation of the stroke-Dasharray and stroke-Dashoffset properties.

First let’s think about how we would implement a dashed line in SVG. Do I write multiple lines, or do I move the brush with M through path to draw different lines.

Both methods can be used to draw a dotted line, but SVG provides an attribute that makes it easier to draw a dotted line

stroke-dasharray

A dashed line is made up of a solid line and a gap. Stroke-dasharray is used to control the size of the solid line and the gap

stroke-dasharray:

  • None (default)
  • Inherit inheritance
  • Dasharray an array is a rule that controls the drawing of dashed lines for textures.

Dasharray can be understood as follows:

Odd digits represent the length of a solid line, and even digits represent the length of a dashed line. If the line is too long and exceeds the sum of the defined lengths in the array, then the rest of the line will be completed according to the defined lengths in the array. It is used repeatedly, sort of like an array concat.

A simple example

    <svg class="border" width="200" height="200" viewBox="0 0 200 200">
      <! -- The solid line 20 is still wired after 20, 40 units. Redraw with the defined 20,20. With 20,20,20,20. And so on -->
      <path stroke-dasharray="20, 20" d="M 10 10 H 110 V 110 H 10 Z" fill="orange" />
    </svg>
    <svg class="border" width="200" height="200" viewBox="0 0 200 200">
      <! With 20, 20 -- > -
      <path stroke-dasharray="20,20,20,20" d="M 10 10 H 110 V 110 H 10 Z" fill="orange" />
    </svg>
    <svg class="border" width="200" height="200" viewBox="0 0 200 200">
      <! -- solid line 20 gap 20 solid line 10,50 units after the line, redraw with the definition of 20,20,10. With 20,20,10,20,20,10. And so on --> 
      <path stroke-dasharray="20, 10." d="M 10 10 H 110 V 110 H 10 Z" fill="orange" />
    </svg>
    <svg class="border" width="200" height="200" viewBox="0 0 200 200">
      <! -- Solid line 20, still wired after 20 units, redraw with defined 10. With 20, 20. And so on -->
      <path stroke-dasharray="20" d="M 10 10 H 110 V 110 H 10 Z" fill="orange" />
    </svg>
Copy the code

stroke-dashoffset

Stroke-dashoffset is an initial displacement to set the stroke line. Positive values want to move counterclockwise, negative values the opposite. This can be seen by setting stroke-dasharray.

stroke-dashoffset: 20% | 20 | inherit

If a percentage value is used, it represents a percentage of the current viewPort. The width and height of the viewport will matter.

For example

 <svg class="border" width="200" height="200" viewBox="0 0 200 200">
      <path stroke-dasharray="400" stroke-dashoffset="20" d="M 10 10 H 110 V 110 H 10 Z" fill="orange" />
 </svg>
Copy the code

With this knowledge, the stroke animation is actually very simple, just do the following steps

  1. Set a dashed line texture with stroke-dasharray. The rules for the texture I want to set solid lines and gaps based on the total graphic length of the path
  2. Set a dashed line displacement with stroke-dashoffset. The displacement distance is the total graphic length of path. This way the path shows all the space between dotted lines, and the solid lines are hidden
  3. Set the animation with the animation property to dynamically change the stroke-dashoffset value to 0

PS: The total length of the path graph can be obtained from the DOM of the path by using the getTotalLength method.

The specific code is as follows

<svg class="border" width="200" height="200" viewBox="0 0 200 200">
      <path id="myPath" stroke-dasharray="400" stroke-dashoffset="400" d="M 10 10 H 110 V 110 H 10 Z" fill="orange" />
</svg>
Copy the code
  path {
    stroke: orange;
    stroke-width: 6;
    /* Make the connection smoother */
    stroke-linecap: round;
    stroke-linejoin: round;
    fill: transparent;
    animation: line-anm 2s ease-in-out forwards;
  }
  @keyframes line-anm {
    to {
      stroke-dashoffset: 0; }}Copy the code

The path trajectory

Use animateMotion and Mpath to define the desired motion path. This is explained in detail in the length of SMIL Animation

<svg class="border" width="200" height="200" viewBox="0 0 200 200">
  <path d="M10,110 A120, 120-45 0,1 110 10 A120, 120-45 0,110 110" stroke="lightgrey" stroke-width="2" fill="none" id="theMotionPath" />
  <path fill="red" d="M -5 -5 L 10 0 L -5 5 L 0 0 Z">
    <animateMotion dur="6s" repeatCount="indefinite" rotate="auto">
      <! -- Use mpath to reference external path path -->
      <mpath href="#theMotionPath" />
    </animateMotion>
  </path>
</svg>
Copy the code

Dynamic path

We all know that when we define path, we use the d attribute to plan the specific path. Combined with the nature of the SVG tags themselves, the attributes defined are instantly fed back into the DOM for re-rendering.

Animate by adding the transition effect to the D property.

The d property can be modified using CSS or JS

For example: Path in CSS

  <svg id="path1" class="border" width="200" height="200" viewBox="0 0 200 200">
    <path  d="M 50 90 L 100 150 L 150 90" fill="transparent" stroke="orange" stroke-width="5"/>
  </svg>
Copy the code
svg path {
    stroke-linecap: round;
    stroke-linejoin: round;
    transition: d ease-in-out 0.2 s;
}
#path1:hover path{
  d: path("M 50 90 L 100 30 L 150 90");
}
Copy the code

Another example: Path in JS

  <svg id="path2" class="border" width="200" height="200" viewBox="0 0 200 200">
    <path  d="M 50 40 L 100 150 L 150 40" fill="transparent" stroke="orange" stroke-width="5"/>
  </svg>
Copy the code
svg path {
    stroke-linecap: round;
    stroke-linejoin: round;
    transition: d ease-in-out 0.2 s;
}
Copy the code
const path2 = document.querySelector('#path2 path')
setTimeout(() = >{
  path2.setAttribute('d'."M 50 60 L 100 120 L 50 180")},1000)
Copy the code

Write in the last

The resources

Source: MDN