SVG image

Overview

SVG is an image format based on XML grammar, its full name is Scalable Vector Graphics. Other image formats are based on pixel processing. SVG is a description of the shape of an image, so it is essentially a text file with a small volume and no distortion regardless of how many times it is enlarged.

SVG files can be directly inserted into web pages and become part of the DOM, and then manipulated with JavaScript and CSS.

<!DOCTYPE html>
<html>
  <head></head>
  <body>
    <svg
      id="mysvg"
      xmlns="http://www.w3.org/2000/svg"
      viewBox="0 0 800 600"
      preserveAspectRatio="xMidYMid meet"
    >
      <circle id="mycircle" cx="400" cy="300" r="50" />
    </svg>
  </body>
</html>

The above is an example of inserting SVG code directly into a web page.

The SVG code can also be written in a separate file, and then inserted into the web page with tags such as <img>, <object>, <embed>, and <iframe>.

<img src="circle.svg" />
<object id="object" data="circle.svg" type="image/svg+xml"></object>
<embed id="embed" src="icon.svg" type="image/svg+xml" />
<iframe id="iframe" src="icon.svg"></iframe>

CSS can also use SVG files.

.logo {
  background: url(icon.svg);
}

SVG files can also be converted to BASE64 encoding, and then written into web pages as Data URI.

<img src="data:image/svg+xml;base64,[data]" />

Syntax

<svg> tag

The SVG code is placed in the top-level tag <svg>. Below is an example.

<svg width="100%" height="100%">
  <circle id="mycircle" cx="50" cy="50" r="50" />
</svg>

The width attribute and the height attribute of <svg> specify the width and height of the SVG image in the HTML element. In addition to relative units, absolute units (units: pixels) can also be used. If you do not specify these two attributes, the size of the SVG image defaults to 300 pixels (width) x 150 pixels (height).

If you only want to display a part of the SVG image, you must specify the viewBox attribute.

<svg width="100" height="100" viewBox="50 50 50 50">
  <circle id="mycircle" cx="50" cy="50" r="50" />
</svg>

The value of the <viewBox> attribute has four numbers, which are the abscissa and ordinate of the upper left corner, and the width and height of the viewport. In the above code, the SVG image is 100 pixels wide x 100 pixels high, and the viewBox attribute specifies that the viewport starts from the point (50, 50). So, what you actually see is the quarter circle in the lower right corner.

Note that the viewport must fit in the space. In the above code, the size of the viewport is 50 x 50. Since the size of the SVG image is 100 x 100, the viewport will be enlarged to fit the size of the SVG image, which is four times larger.

If you do not specify the width property and the height property, and only specify the viewBox property, it is equivalent to only specifying the aspect ratio of the SVG image. At this time, the default size of the SVG image is the size of the HTML element where it is located.

<circle> tag

The <circle> tag represents a circle.

<svg width="300" height="180">
  <circle cx="30"  cy="50" r="25" />
  <circle cx="90"  cy="50" r="25" class="red" />
  <circle cx="150" cy="50" r="25" class="fancy" />
</svg>

The above code defines three circles. The cx, cy, and r attributes of the <circle> tag are the abscissa, ordinate, and radius, respectively, in pixels. The coordinates are all relative to the origin of the upper left corner of the <svg> canvas.

The class attribute is used to specify the corresponding CSS class.

.red {
  fill: red;
}

.fancy {
  fill: none;
  stroke: black;
  stroke-width: 3pt;
}

The CSS properties of SVG are different from web page elements.

  • fill: fill color
  • stroke: stroke color
  • stroke-width: border width

<line> tag

The <line> tag is used to draw straight lines.

<svg width="300" height="180">
  <line x1="0" y1="0" x2="200" y2="0" style="stroke:rgb(0,0,0);stroke-width:5" />
</svg>

In the above code, the x1 attribute and y1 attribute of the <line> tag indicate the abscissa and ordinate of the starting point of the line segment; the x2 attribute and y2 attribute indicate the abscissa and ordinate of the end point of the line segment ; The style attribute indicates the style of the line segment.

<polyline> tag

The <polyline> tag is used to draw a polyline.

<svg width="300" height="180">
  <polyline points="3,3 30,28 3,53" fill="none" stroke="black" />
</svg>

The points property of <polyline> specifies the coordinates of each end point. The abscissa and ordinate are separated by commas, and the points are separated by spaces.

<rect> tag

The <rect> tag is used to draw rectangles.

<svg width="300" height="180">
  <rect x="0" y="0" height="100" width="200" style="stroke: #70d5dd; fill: #dd524b" />
</svg>

The x and y attributes of <rect> specify the abscissa and ordinate of the upper left corner of the rectangle; the width and height attributes specify the width and height (in pixels) of the rectangle.

<ellipse> tag

The <ellipse> tag is used to draw an ellipse.

<svg width="300" height="180">
  <ellipse cx="60" cy="60" ry="40" rx="20" stroke="black" stroke-width="5" fill="silver"/>
</svg>

The cx and cy attributes of <ellipse> specify the abscissa and ordinate (unit pixel) of the center of the ellipse; the rx and ry attributes specify the horizontal and vertical axes of the ellipse Radius (in pixels).

<polygon> tag

The <polygon> tag is used to draw polygons.

<svg width="300" height="180">
  <polygon fill="green" stroke="orange" stroke-width="1" points="0,0 100,0 100,100 0,100 0,0"/>
</svg>

The points attribute of <polygon> specifies the coordinates of each end point. The abscissa and ordinate are separated by commas, and the points are separated by spaces.

<path> tag

The <path> tag is used to make paths.

<svg width="300" height="180">
<path d="
  M 18,3
  L 46,3
  L 46,40
  L 61,40
  L 32,68
  L 3,40
  L 18,40
  WITH
"></path>
</svg>

The d attribute of <path> represents the drawing order, and its value is a long string. Each letter represents a drawing action, followed by coordinates.

  • M: move to (moveto)
  • L: draw a straight line to (lineto)
  • Z: closed path

<text> tag

The <text> tag is used to draw text.

<svg width="300" height="180">
  <text x="50" y="25">Hello World</text>
</svg>

The x and y attributes of <text> indicate the abscissa and ordinate of the starting point of the baseline of the text block. The style of the text can be specified with the class or style attribute.

<use> tag

The <use> tag is used to copy a shape.

<svg viewBox="0 0 30 10" xmlns="http://www.w3.org/2000/svg">
  <circle id="myCircle" cx="5" cy="5" r="4"/>

  <use href="#myCircle" x="10" y="0" fill="blue" />
  <use href="#myCircle" x="20" y="0" fill="white" stroke="blue" />
</svg>

The href attribute of <use> specifies the node to be copied, and the x attribute and y attribute are the coordinates of the upper left corner of <use>. In addition, you can also specify the width and height coordinates.

<g> tag

The <g> tag is used to group multiple shapes into a group for easy reuse.

<svg width="300" height="100">
  <g id="myCircle">
    <text x="25" y="20">圆形</text>
    <circle cx="50" cy="50" r="20"/>
  </g>

  <use href="#myCircle" x="100" y="0" fill="blue" />
  <use href="#myCircle" x="200" y="0" fill="white" stroke="blue" />
</svg>

<defs> tag

The <defs> tag is used to customize the shape, the code inside it will not be displayed, it is for reference only.

<svg width="300" height="100">
  <defs>
    <g id="myCircle">
      <text x="25" y="20">圆形</text>
      <circle cx="50" cy="50" r="20"/>
    </g>
  </defs>

  <use href="#myCircle" x="0" y="0" />
  <use href="#myCircle" x="100" y="0" fill="blue" />
  <use href="#myCircle" x="200" y="0" fill="white" stroke="blue" />
</svg>

<pattern> tag

The <pattern> tag is used to customize a shape that can be referenced to tile an area.

<svg width="500" height="500">
  <defs>
    <pattern id="dots" x="0" y="0" width="100" height="100" patternUnits="userSpaceOnUse">
      <circle fill="#bee9e8" cx="50" cy="50" r="35" />
    </pattern>
  </defs>
  <rect x="0" y="0" width="100%" height="100%" fill="url(#dots)" />
</svg>

In the above code, the <pattern> tag defines a circle as a dots pattern. patternUnits="userSpaceOnUse" means that the width and length of <pattern> are actual pixel values. Then, specify this mode to fill the rectangle below.

<image> tag

The <image> tag is used to insert image files.

<svg viewBox="0 0 100 100" width="100" height="100">
  <image xlink:href="path/to/image.jpg"
    width="50%" height="50%"/>
</svg>

In the above code, the xlink:href attribute of <image> indicates the source of the image.

<animate> tag

The <animate> tag is used to produce animation effects.

<svg width="500px" height="500px">
  <rect x="0" y="0" width="100" height="100" fill="#feac5e">
    <animate attributeName="x" from="0" to="500" dur="2s" repeatCount="indefinite" />
  </rect>
</svg>

In the above code, the rectangle will move continuously to produce an animation effect.

The meaning of the attributes of <animate> is as follows.

  • attributeName: The attribute name of the animation effect.
  • from: The initial value of a single animation.
  • to: The end value of a single animation.
  • dur: the duration of a single animation.
  • repeatCount: The loop mode of the animation.

Animation can be defined on multiple properties.

<animate attributeName="x" from="0" to="500" dur="2s" repeatCount="indefinite" />
<animate attributeName="width" to="500" dur="2s" repeatCount="indefinite" />

<animateTransform> tag

The <animate> tag has no effect on the transform property of CSS. If you need to transform it, you must use the <animateTransform> tag.

<svg width="500px" height="500px">
  <rect x="250" y="250" width="50" height="50" fill="#4bc0c8">
    <animateTransform attributeName="transform" type="rotate" begin="0s" dur="10s" from="0 200 200" to="360 400 400" repeatCount="indefinite" />
  </rect>
</svg>

In the above code, the effect of <animateTransform> is rotation (rotate). At this time, the attribute values ​​of from and to have three numbers, the first number is the angle value, the second value and the third The value is the coordinate of the center of rotation. from="0 200 200" means at the beginning, the angle is 0, and starts to rotate around (200, 200); to="360 400 400" means at the end, the angle is 360, around (400, 400)Rotate.

JavaScript operation

DOM manipulation

If the SVG code is written directly in the HTML page, it becomes a part of the DOM of the page and can be manipulated directly with the DOM.

<svg
  id="mysvg"
  xmlns="http://www.w3.org/2000/svg"
  viewBox="0 0 800 600"
  preserveAspectRatio="xMidYMid meet"
>
  <circle id="mycircle" cx="400" cy="300" r="50" />
  <svg></svg>
</svg>

After the above code is inserted into the web page, you can use CSS to customize the style.

circle {
  stroke-width: 5;
  stroke: #f00;
  fill: #ff0;
}

circle:hover {
  stroke: #090;
  fill: #fff;
}

Then, you can manipulate the SVG with JavaScript code.

var mycircle = document.getElementById("mycircle");

mycircle.addEventListener(
  "click",
  function (e) {
    console.log("circle clicked - enlarging");
    mycircle.setAttribute("r", 60);
  },
  false
);

The above code specifies that if the graphic is clicked, the r attribute of the circle element will be overwritten.

Get SVG DOM

Use the <object>, <iframe>, <embed> tags to insert the SVG file to get the SVG DOM.

var svgObject = document.getElementById("object").contentDocument;
var svgIframe = document.getElementById("iframe").contentDocument;
var svgEmbed = document.getElementById("embed").getSVGDocument();

Note that if you use the <img> tag to insert an SVG file, you cannot get the SVG DOM.

Read SVG source code

Since the SVG file is just a piece of XML text, you can read the SVG source code by reading the XML code.

<div id="svg-container">
  <svg
    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xml:space="preserve"
    width="500"
    height="440"
  >
    <!-- svg code -->
  </svg>
</div>

Use the serializeToString() method of the XMLSerializer instance to get the code of the SVG element.

var svgString = new XMLSerializer().serializeToString(
  document.querySelector("svg")
);

Convert SVG image to Canvas image

First, you need to create a new Image object and assign the SVG image to the src attribute of the Image object.

var img = new Image();
var svg = new Blob([svgString], { type: "image/svg+xml;charset=utf-8" });

var DOMURL = self.URL || self.webkitURL || self;
var url = DOMURL.createObjectURL(svg);

img.src = url;

Then, when the image is loaded, draw it to the <canvas> element.

img.onload = function () {
  var canvas = document.getElementById("canvas");
  var ctx = canvas.getContext("2d");
  ctx.drawImage(img, 0, 0);
};

Example: Line chart

Next, draw a data table into a line graph.

Date |Amount -----|------ 2014-01-01 | $10 2014-02-01 | $20 2014-03-01 | $40
2014-04-01 | $80

The above graph can be drawn as a coordinate system, with Date as the horizontal axis, Amount as the vertical axis, and four rows of data as one data point.

<svg width="350" height="160">
  <g class="layer" transform="translate(60,10)">
    <circle r="5" cx="0"   cy="105" />
    <circle r="5" cx="90"  cy="90"  />
    <circle r="5" cx="180" cy="60"  />
    <circle r="5" cx="270" cy="0"   />

    <g class="y axis">
      <line x1="0" y1="0" x2="0" y2="120" />
      <text x="-40" y="105" dy="5">$10</text>
      <text x="-40" y="0"   dy="5">$80</text>
    </g>
    <g class="x axis" transform="translate(0, 120)">
      <line x1="0" y1="0" x2="270" y2="0" />
      <text x="-30"   y="20">January 2014</text>
      <text x="240" y="20">April</text>
    </g>
  </g>
</svg>