preface

We’ve all worked with SVG in more or less everyday development, whether it’s to draw simple graphics, to build an engineering library of font files, or even to draw complex visualization modules. This article will detail the basic graphics of SVG and the common forms of animation to help you get started with SVG.

Basic graphics

The following will describe the default shapes of SVG and the corresponding attributes. Most of the time in the actual development or design process, drawing SVG ICONS will use some tools.

rectangular

    <svg width="200px" height="200px" version="1.1" xmlns="http://www.w3.org/2000/svg">
        <rect width="100" height="100" x="20" y="20" rx="30" ry="30" style="The fill: RGB (255255, 0); stroke-width:4; Stroke: RGB (0, 0); fill-opacity: .6; stroke-opacity: .5;" />
    </svg>
Copy the code

In an SVG tag, width represents the entire width, height represents the height, version represents the version, and XMLNS represents the namespace. The latter two attributes are relatively fixed things to understand.

The label attributes and style attributes in recT are explained as follows:

  • widthWidth:
  • heightHeight:
  • x: Offset in the horizontal direction
  • y: Offset in the vertical direction
  • rx,ry: Define rounded corner effect
  • style: Styles (These styles also apply to the following graphics, so the following graphics will only cover properties, not styles)
    • fill: RGB color, indicating the filling color of the rectangle
    • fill-opacity: Opacity of the fill
    • stroke: RGB color, indicating the border color of the rectangle
    • stroke-width: Size of the rectangle border
    • stroke-opacity: The opacity of the rectangle border

circular

<svg width="200px" height="200px" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <circle cx="100" cy="50" r="40" style="stroke:black; stroke-width:2; fill:blue" />
</svg>
Copy the code

The circle tag attributes are explained as follows:

  • cx,cy: Center coordinates
  • r: Radius of a circle

The ellipse

<svg width="200px" height="200px" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <ellipse cx="100" cy="50" rx="40" ry="50" style="fill:purple" />
</svg>
Copy the code

The ellipse tag attributes are explained as follows:

  • cx: the center of the circlexcoordinates
  • cy: the center of the circleycoordinates
  • rx: horizontal radius
  • ry: vertical radius

line

<svg width="200px" height="200px" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <line x1="10" y1="10" x2="100" y2="100" style="stroke:red; stroke-width:2" />
</svg>
Copy the code

The attributes of the LINE label are described as follows:

  • x1: Starting point of a line segmentxcoordinates
  • x2: The end of a line segmentxcoordinates
  • y1: Starting point of a line segmentycoordinates
  • y2: The end of a line segmentycoordinates

polygon

<svg width="200px" height="200px" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <polygon points="10, 10, 10200, 100200, 100, 10" style="fill:red; stroke:#000000; stroke-width:1" />
</svg>
Copy the code

The attributes of the polygon tag are explained as follows:

  • points: defines polygonsNA (x.y) coordinates, not less than three points

Broken line

<svg width="200px" height="200px" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <polyline points="10,10, 20,20, 30,15, 40,40, 50,30,60" style="fill:transparent; stroke:green; stroke-width:2" />
</svg>
Copy the code

The attributes of the polyline label are described as follows:

  • points: defines the curveNA (x.y) coordinates

PS: Look at this graph. Does it look like your latest stock fund

The path

The path tag uses property D to describe the path. There are many variations, so let’s look at them one by one.

M

Moveto, to see means to moveto a certain point, so imagine you are holding a pen in your hand and the M command is to move your pen to a certain point and start drawing. The syntax is M(x,y), where capital M represents absolute positioning and lowercase M represents relative positioning, as does the rest of the following syntax.

Z

Closepath, close the path you drew earlier.

L

Lineto means to draw a line. The syntax is L(x,y).

<svg width="100%" height="100px" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <path d="M10 10 L200 200 Z" style="stroke: red; stroke-width:2" />
</svg>
Copy the code

H

Horizontal line, horizontal line Syntax for H (y)

<svg width="100%" height="100px" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <path d="M10 10 H200 Z" style="stroke: red; stroke-width:2" />
</svg>
Copy the code

V

Draw a line vertically. Syntax for the V (x)

<svg width="100%" height="100px" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <path d="M10 10 V200 Z" style="stroke: red; stroke-width:2" />
</svg>
Copy the code

C

Curveto, three Bezier curves. The syntax is C x1 y1, x2 y2, x y. A cubic Bezier curve should have four points to control it, and only three points are described in C, so the starting point is what you describe with M. For example: M10 10 C 100 100 150 100 200 10 refers to the cubic Bezier curve controlled by starting point (10,10), first auxiliary point (100,100), second auxiliary point (150,100) and ending point (200,10).

S

Smooth curveto, used to describe symmetrical cubic Bezier curves. The syntax is S x2 y2, x y. When S follows an S command or a C command, its first control point (x1, y1 omitted from S syntax) is assumed to be the symmetric point of the previous control point. If it is not preceded by an S or C command, its two control points are assumed to be the same point.

<svg width="100%" height="100px" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <path d="M10 10 S 100 100 200 10" style="stroke: red; stroke-width:1; fill:white" />
</svg>

<svg width="100%" height="200px" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <path d="M100 100 C 150 150 200 150 250 100 S 300 20 400 100" style="stroke: red; stroke-width:1; fill:white" />
</svg>
Copy the code

Copy the code

Q

Quadratic Bezier curves, only need one control point. The syntax is Q, x1, y1, x, y

<svg width="100%" height="200px" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <path d="M0 0 Q100 100 200 0" style="stroke: red; stroke-width:1; fill:white" />
</svg>
Copy the code

T

Similar to S, the new control point can be inferred from the previous control point. The syntax is T x y

<svg width="100%" height="200px" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <path d="M10 80 Q 52.5 10, 95 80 T 180 80" stroke="red" fill="transparent" />
</svg>
Copy the code

A

Octagonal Octagonal Arc Rx ry x-axis-rotation large-arc-flag sweep-flag x y

  • rx,ryIf the length of two half axes of an elliptic arc is equal, it is an arc
  • x-axis-rotationThe rotation Angle of the ellipse with respect to the coordinate system
  • large-arc-flagDraw good arc (1), bad arc (0)
  • sweep-flagDraw clockwise (1) and counterclockwise (0)
  • x yCircular end point coordinates
<svg width="100%" height="100vh" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <path d="M200 200 H300 V100 A 100 100 0 1 1 200 200" style="stroke: red; stroke-width:2; fill:white" />
</svg>
Copy the code

Path drawing is very complicated. It is recommended to use an SVG editor to assist in drawing graphics.

SVGanimation

Above we learned about the graphics and syntax of various SVG, SVG can draw a variety of graphics in addition to its animation effect is also unique. Let’s take a look at the common forms and applications of SVG animation.

Stroke animation

I’ll start with two properties, stroke-Dasharray and stroke-dashoffset. The stroke animation we implement revolves around these two properties.

stroke-dasharray

Used to create dashed lines with the syntax stroke-dasharray: N1 [n2 [n3]]. What does that mean? Let’s start with a couple of examples

<svg width="100vw" height="100vh" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <path d="M0 100 H400" class="line" style="stroke-dasharray: 10;"></path>
    <path d="M0 200 H400" class="line" style="stroke-dasharray: 10 20;"></path>
    <path d="M0 300 H400" class="line" style="stroke-dasharray: 10 20 30;"></path>
</svg>
Copy the code

With the image above, we can summarize the stroke-Dasharray rules:

  • A parameter that describes the equal length of the real and dotted lines, for examplestroke-dasharray: 10That means that when I describe this path,The length of the tenThe solid line – >The length of the tenThe dotted line – >The length of the tenThe solid line… and so on.
  • The length of a solid line is the first parameter, the length of a dotted line is the second parameter,stroke-dasharray: 10 20saidThe length of the tenSolid lines – >The length of the 20Dotted line – >The length of the tenSolid line… and so on.
  • When three parameters are used to describe the length of solid line and dotted line alternately,stroke-dasharray: 10 20 30saidThe length of the tenSolid lines – >The length of the 20Dotted line – >The length of the 30Solid lines – >The length of the tenDotted line… and so on.

stroke-dashoffset

Represents the offset of the dotted line. A positive value indicates an offset in the opposite direction, and a negative value indicates a offset in the positive direction.

<svg width="100vw" height="100vh" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <path d="M0 100 H400" class="line" style="stroke-dasharray: 400; stroke-dashoffset:200"></path>
</svg>
Copy the code

As can be seen from the figure, the path is divided into 400 solid lines and 400 dotted lines. By shifting the dotted line 200 in the opposite direction, the 200 length of the solid line can be covered, thus completing the path with only half of the figure left. Since then, we have been able to use these two properties to create a path animation by combining them with the CSS animation.

Start with something simple, like this line from scratch animation:

.line { stroke-width: 4px; stroke: red; stroke-dasharray: 400; stroke-dashoffset: 400; animation: move 2s; } @keyframes move { to { stroke-dashoffset: 0; }}<svg width="100vw" height="100vh" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <path d="M0 100 H400" class="line"></path>
</svg>
Copy the code

After simple animation from scratch, it is not difficult to find that it can not only work on a simple line, for example, we now have an SVG graph as follows, and we can also do a stroke animation.

Before we begin, let’s look at a method in the Path element, getTotalLength(), which returns the calculated value of the total length of the path in user units. We can use it to calculate the total length of any path element.

With that in mind, we have roughly done the above animation, and here is the code to implement it

<style>
    .path {
        stroke-width: 4px;
        stroke: white;
        stroke-dasharray: 5199.931640625;
        stroke-dashoffset: 5199.931640625;
        animation: move 2s linear;
        fill: white;
        animation-fill-mode: forwards;
    }

    @keyframes move {
        to {
            stroke-dashoffset: 0;
            stroke: black;
            transform: scale3d(1.1.1.1.1.1); }}.scale {
        stroke-dashoffset: 0;
        stroke: black;
        animation: scale-path .2s;
        animation-fill-mode: forwards;
        opacity: 0;
    }

    @keyframes scale-path {
        0% {
            transform: scale3d(1.1.1);
            fill: white;
            opacity: 0;
        }

        50% {
            transform: scale3d(1.2.1.2.1);
        }

        100% {
            transform: scale3d(1.1.1);
            opacity: 1; fill: black; }}</style>

<svg class="icon" viewBox="0 0 2000 2000" version="1.1" xmlns="http://www.w3.org/2000/svg"
   width="200" height="200">
    <path class="path" d="..."p-id="2506"></path>
</svg>
<script>
    const path = document.querySelector('.path')
    setTimeout(() = > {
        $(path).addClass('scale')},2000)
</script>
Copy the code

Path following animation

Path-following animation is another common form of SVG animation, where an object moves along the path of an SVG graph. GetPointAtLength (number):Point, which takes a number from 0 to getTotalLength() and returns the coordinates of the Point corresponding to the length. After understanding this, we only need to divide the path length into N parts to obtain the coordinates of N points. Let the coordinates of the controlled elements be gradually assigned to the coordinates of these N points, and then we can achieve the effect of elements moving along the SVG path. The specific implementation logic is as follows:

const STEP = 1000
let currentStep = 1
const path = document.querySelector('.path');
const length = path.getTotalLength();
const slider = document.querySelector('.slider')
setInterval(() = > {
    const point = path.getPointAtLength(currentStep / STEP * length)
    slider.style.top = point.y - 10 + 'px' //10 is half the width of the slider to better fit the path
    slider.style.left = point.x - 10 + 'px'
    if (currentStep === STEP) {
        currentStep = 1
    } else {
        currentStep++
    }
}, 10)
Copy the code

After obtaining the specific coordinates, we only need to use a timer to continuously assign the coordinates to achieve the path following effect. However, in the above effect, it was noticed that the Angle of the slider did not change, resulting in the visual effect of the arc part could not reflect the following, that is to say, we still need to ask for the rotation Angle of the slider.

Notice here that we’re dividing the waypoints into N, because there are enough of them, and the coordinates are changing fast enough, that we look continuous, but we’re actually moving discretely. Computer sampling is like this, as long as there are enough sample points, it will be infinitely close to a smooth curve.

So to figure out the Angle of the slider at a certain point, you can figure out the slope of the tangent line of the slider at that point. In this scenario, assuming that the current point is (x2,y2) and the last point is (x1,y1), then k=(y2-y1)/(x2-x1) the slope of the line segment, as long as the line segment is short enough, can be used as the current slope of the slider, So once we have the slope, we can use the arctangent trigonometry function math.atan to figure out the Angle, and notice that the Angle is in radians, and we have to turn it into an Angle so that we can use it in rotate.

let prePos
setInterval(() = > {
    / /...
    if (prePos) {
        const k = (point.y - prePos.y) / (point.x - prePos.x)
        const val = Math.atan(k) / Math.PI * 180
        slider.style.transform = `rotate(${val}deg)`
    }
    prePos = point
    / /...
}, 10)

Copy the code

With the Angle offset, you can feel the path of a higher degree of fit, better visual effect.