根据网道教程 https://wangdoc.com/webapi/svg.html

编写了一份图形示例的文档。用于形象化学习。

svg

概述

  • Scalable Vector Graphics
  • 可缩放矢量图
  • 其他图像格式都是基于像素处理的,SVG 则是属于对图像的形状描述,所以它本质上是文本文件,体积较小,且不管放大多少倍都不会失真。
In [54]:
%%html
<!DOCTYPE html>
<html>
<head></head>
    <body>
        <svg width="100%" height="100%">
          <circle id="mycircle1" cx="25" cy="25" r="50" fill="blue"/>
        </svg>
    </body>
</html>

语法

svg

  • SVG代码都放在顶层标签 <svg> 之中
In [55]:
%%html
<svg width="100%" height="100%">
  <circle id="mycircle2" cx="50" cy="50" r="50" fill="red" />
</svg>
  • <svg> 的width属性和height属性,指定了 SVG 图像在 HTML 元素中所占据的宽度和高度。
  • 除了相对单位,也可以采用绝对单位(单位:像素)。
  • 如果不指定这两个属性,SVG 图像的大小默认为300像素(宽)x 150像素(高)。
  • 如果只想展示 SVG 图像的一部分,就要指定 viewBox 属性
  • <viewBox>属性的值有四个数字,分别是左上角的横坐标和纵坐标、视口的宽度和高度。

circle

  • <circle>标签的cx、cy、r属性分别为横坐标、纵坐标和半径,单位为像素。
  • 坐标都是相对于<svg>画布的左上角原点。
In [56]:
%%html
<svg width="100" height="100" viewBox="50 0 100 50">
  <circle id="mycircle3" cx="50" cy="50" r="50" class="fancy"/>
</svg>
<style>
.fancy {
  fill: green;
  stroke: red;
  stroke-width: 3pt;
}
</style>
.red {
  fill: red;
}

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

// fill:填充色
// stroke:描边色
// stroke-width:边框宽度

line

  • 绘制直线
  • <line>标签的
    • x1属性和y1属性,表示线段起点的横坐标和纵坐标;
    • x2属性和y2属性,表示线段终点的横坐标和纵坐标;
    • style属性表示线段的样式。
In [57]:
%%html
<svg width="300" height="80">
  <line x1="0" y1="5" x2="200" y2="50" style="stroke:rgb(250,50,50);stroke-width:5" />
</svg>

polyline

  • 绘制一根折线
  • <polyline>的points属性指定了每个端点的坐标,
    • 横坐标与纵坐标之间与逗号分隔,
    • 点与点之间用空格分隔。
In [58]:
%%html
<svg width="300" height="180">
  <polyline points="3,3 30,28 3,53 100,200" fill="brown" stroke="black" stroke-width=5px />
</svg>
In [59]:
%%html
<svg width="300" height="180">
  <polyline points="3,3 30,28 3,53 100,200" fill="none" stroke="blue" stroke-width=5px />
</svg>

rect

  • <rect>的
    • x属性和y属性,指定了矩形左上角端点的横坐标和纵坐标;(y属性的纵坐标,是自上而下的)
    • width属性和height属性指定了矩形的宽度和高度(单位像素)。
In [60]:
%%html
<svg width="300" height="180">
  <rect x="10" y="10" height="100" width="200" style="stroke: #70d5dd; stroke-width: 5; fill:#dd524b" />
</svg>

ellipse

  • <ellipse>的
    • cx 属性和 cy 属性,指定了椭圆中心的横坐标和纵坐标(单位像素);
    • rx 属性和 ry 属性,指定了椭圆横向轴和纵向轴的半径(单位像素)
In [61]:
%%html
<svg width="300" height="180">
  <ellipse cx="60" cy="60" ry="55" rx="30" stroke="red" stroke-width="5" fill="silver"/>
</svg>

polygon

  • <polygon>的points属性指定了每个端点的坐标,
    • 横坐标与纵坐标之间与逗号分隔,
    • 点与点之间用空格分隔。
In [62]:
%%html
<svg width="800" height="200">
  <polygon fill="blue" stroke="brown" stroke-width="1" points="    0,50  50,0 150,25 125,100  25,125"/>
  <polygon fill="blue" stroke="brown" stroke-width="1" points=  "200,50 250,0 350,25 325,100 225,125"/>
</svg>

path

  • <path> 的 d属性 表示绘制顺序
  • 它的值是一个长字符串,每个字母表示一个绘制动作,后面跟着坐标。
    • M:移动到(moveto)
    • L:画直线到(lineto)
    • Z:闭合路径
In [63]:
%%html
<svg width="300" height="80">
<path d="
  M 18,3
  L 46,3
  L 46,40
  L 61,40
  L 32,68
  L 3,40
  L 18,40
  Z
" fill="orange"></path>
</svg>

text

In [64]:
%%html
<svg width="300" height="30">
  <text x="50" y="25">Hello World</text>
</svg>
Hello World

use

  • 复制一个形状
  • <use>的 href属性 指定所要复制的节点,
  • x 属性 和 y 属性 是<use>左上角的坐标。
  • 另外,还可以指定 width 和 height 坐标
In [65]:
%%html
<svg width="100%" height="100%">
  <circle id="myCircle4" cx="80" cy="80" r="50" />
  <use href="#myCircle4" x="150" y="0" fill="blue" />
  <use href="#myCircle4" x="300" y="0" fill="white" stroke="blue" stroke-width=10 />
</svg>

g

  • 用于将多个形状组成一个组(group),方便复用
In [66]:
%%html
<svg width="400" height="200">
  <g id="myCircle5">
    <text x="25" y="20">圆形</text>
    <circle cx="50" cy="75" r="40"/>
  </g>

  <use href="myCircle5" x="100" y="0" fill="blue" />
  <use href="myCircle5" x="200" y="20" fill="white" stroke="blue" />
</svg>
圆形

defs

  • 用于自定义形状,它内部的代码不会显示(与之前的g标签的比较),仅供引用
In [67]:
%%html
<svg width="300" height="100">
  <defs>
    <g id="myCircle6">
      <text x="25" y="20">圆形</text>
      <circle cx="50" cy="50" r="20"/>
    </g>
  </defs>

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

pattern

  • 用于自定义一个形状,该形状可以被引用来平铺一个区域
  • <pattern>标签将一个圆形定义为dots模式。
    • patternUnits="userSpaceOnUse"表示<pattern>的宽度和长度是实际的像素值。
    • 然后,指定这个模式去填充下面的矩形。
  • 注意 此处的 fill="url(#dots)" 的用法
In [68]:
%%html
<svg width="500" height="300">
  <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>

image

animate

  • 产生动画效果
  • <animate>的属性含义如下。
    • attributeName:发生动画效果的属性名。
    • from:单次动画的初始值。
    • to:单次动画的结束值。
    • dur:单次动画的持续时间。
    • repeatCount:动画的循环模式。
In [69]:
%%html
<svg width="700px" height="100px">
  <rect x="0" y="0" width="100" height="50" fill="#feac5e">
    <animate attributeName="x" from="0" to="600" dur="10s" repeatCount="indefinite" />
  </rect>
</svg>
In [70]:
%%html
<svg width="700px" height="100px">
  <rect x="0" y="0" width="100" height="50" fill="#feac5e">
    <animate attributeName="width" to="600" dur="10s" repeatCount="indefinite" />
  </rect>
</svg>

animateTransform

  • <animateTransform>的效果为旋转(rotate),这时from和to属性值有三个数字,
    • 第一个数字是角度值,
    • 第二个值和第三个值是旋转中心的坐标。
    • from="0 200 200"表示开始时,角度为0,围绕(200, 200)开始旋转;
    • to="360 400 400"表示结束时,角度为360,围绕(400, 400)旋转。
In [71]:
%%html
<svg width="500px" height="300px">
  <rect x="50" y="50" width="50" height="50" fill="#4bc0c8">
    <animateTransform attributeName="transform" type="rotate" begin="0s" dur="10s" from="0 100 100" to="160 200 200" repeatCount="indefinite" />
  </rect>
</svg>

JavaScript操作

DOM操作

In [72]:
%%html
<svg
  width="100"
  height="100"  
  id="mysvg"
  xmlns="http://www.w3.org/2000/svg"
  viewBox="0 0 80 60"
  preserveAspectRatio="xMidYMid meet"
>
  <circle id="mycircle7" cx="40" cy="30" r="15" />
<svg>
<style>
# circle {
#   stroke-width: 5;
#   stroke: #f00;
#   fill: green;
# }
circle:hover {
  stroke: #090;
  fill: #fff;
}
</style>    
<script>
var mycircle = document.getElementById('mycircle7');
mycircle.addEventListener('click', function(e) {  // 如果点击图形,就改写circle元素的r属性。
  console.log('circle clicked - enlarging');
  mycircle.setAttribute('r', 25);
}, false);    
</script>

获取 SVG DOM

读取 SVG 源码

SVG图像转为 Canvas 图像

实例:折线图

In [73]:
%%html
<svg width="350" height="160">
  <g class="layer" transform="translate(60,10)", fill="yellow" stroke="blue">
    <circle r="5" cx="0"   cy="110" />
    <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="110" />
      <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, 110)">
      <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>
$10 $80 January 2014 April

参考链接

◎ 欢迎参与讨论,请在这里发表您的看法、交流您的观点。