记录SVG

170 阅读8分钟

SVG文档

SVG是一种基于XML的矢量图形格式,可以用于绘制各种图形。下面介绍SVG绘制的基本步骤:

1.创建SVG元素

首先需要在HTML文档中创建一个SVG元素,可以使用标签来创建,例如:

<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
  <!-- SVG图形代码 -->
</svg>

其中,width和height属性指定SVG元素的宽度和高度。

image

描述:SVG 使用的坐标系统或者说网格系统。

以页面的左上角为 (0,0) 坐标点,坐标以像素为单位,x 轴正方向是向右,y 轴正方向是向下。

1.1 绘制图形

SVG支持多种绘制图形的方式,包括线条、矩形、圆形、椭圆、多边形等等。以下是一些常用的绘制图形的代码示例:

1.1.1 绘制直线:

<line x1="0" y1="0" x2="100" y2="100" stroke="black"  />

其中,x1和y1指定起点坐标,x2和y2指定终点坐标,stroke属性指定线条颜色。

1.1.2 绘制矩形:

 <rect x="50" y="20" width="150" height="150" style="fill:blue;stroke:pink;stroke-width:5;fill-opacity:0.1;
  stroke-opacity:0.9"/>

其中,x和y指定左上角坐标,width和height指定宽度和高度,fill属性指定填充颜色,stroke-width 属性定义矩形边框的宽度,stroke 属性定义矩形边框的颜色, fill-opacity 属性定义填充颜色透明度, stroke-opacity 属性定义轮廓颜色的透明度(合法的范围是:0 - 1)。

例如:x 属性定义矩形的左侧位置(例如,x="0" 定义矩形到浏览器窗口左侧的距离是 0px)

  y 属性定义矩形的顶端位置(例如,y="0" 定义矩形到浏览器窗口顶端的距离是 0px)

1.1.3 绘制圆形:

<circle cx="100" cy="100" r="50" fill="blue" />

其中,cx和cy指定圆心坐标,r指定半径,fill属性指定填充颜色。

注意:如果省略cx和cy,圆的中心会被设置为(0, 0)

1.1.4 椭圆:

<ellipse cx="75" cy="75" rx="20" ry="5"/>

cx和cy指椭圆中心的x,y位置,rx和ry指椭圆的x,y半径。

1.1.5 多段线:

<polyline points="0,40 40,40 40,80 80,80 80,120 120,120 120,160" style="fill:white;stroke:red;stroke-width:4" />

points  点集数列。每个数字用空白、逗号、终止命令符或者换行符分隔开。每个点必须包含 2 个数字,一个是 x 坐标,一个是 y 坐标。所以点列表 (0,0), (1,1) 和 (2,2) 可以写成这样:“0 0, 1 1, 2 2”。

1.1.6 绘制多边形:

 标签用来创建含有不少于三个边的图形。

polygon和折线很像,它们都是由连接一组点集的直线构成。不同的是,polygon的路径在最后一个点处自动回到第一个点。

<polygon points="50,50 100,0 150,50" fill="yellow" />

其中,points属性指定各个点的坐标(x,y),用空格或逗号分隔,fill属性指定填充颜色。

points  点集数列。每个数字用空白符、逗号、终止命令或者换行符分隔开。每个点必须包含 2 个数字,一个是 x 坐标,一个是 y 坐标。所以点列表 (0,0), (1,1) 和 (2,2) 可以写成这样:“0 0, 1 1, 2 2”。路径绘制完后闭合图形,所以最终的直线将从位置 (2,2) 连接到位置 (0,0)。

1.1.7 路径:

<path d="M10 10 H 90 V 90 H 10 Z" fill="transparent" stroke="black"/>
<circle cx="10" cy="10" r="2" fill="red"/>
  1. M = moveto  --- 需要移动到的点的 x 轴和 y 轴的坐标。注: M 命令经常出现在路径的开始处,用来指明从何处开始画(M命令是移动画笔位置)

  2. L = lineto ---  L x y (or l dx dy) 一个点的 x 轴和 y 轴坐标。L 命令将会在当前位置和新位置,(L 前面画笔所在的点)之间画一条线段(能够真正画出线命令)

  3. H = horizontal lineto ---  H x (or h dx) 绘制水平线,只带一个参数,在x轴移动位置

  4. V = vertical lineto --- V y (or v dy) 绘制垂直线,只带一个参数,在y轴移动位置

  5. C = curveto --- C x1 y1, x2 y2, x y (or) c dx1 dy1, dx2 dy2, dx dy   三次贝塞尔曲线

  6. S = smooth curveto --- S 命令可以用来创建与前面一样的贝塞尔曲线 

  7. Q = quadratic Bézier curve --- 二次贝塞尔曲线 Q

  8. T = smooth quadratic Bézier curveto  ---快捷命令 T

  9. A = elliptical Arc --- 弧形命令 A 是另一个创建 SVG 曲线的命令

  10. Z = closepath --- Z (or z)闭合路径,Z命令会从当前点画一条直线到路径的起点,经常被放到路径的最后。Z 命令不用区分大小写

**注意:**以上所有命令均允许小写字母。大写表示绝对定位,小写表示相对定位。(例如:从上一个点开始,向上移动 10px,向左移动 7px)

  •  因为属性 d采用的是用户坐标系统,所以不需标明单位

  •  相对命令使用的是小写字母,它们的参数不是指定一个明确的坐标,而是表示相对于它前面的点需要移动多少距离

上述路径是:画笔移动到 (10,10) 点,由此开始,向右移动 80 像素构成一条水平线,然后向下移动 80 像素,然后向左移动 80 像素,然后再回到起点。

1.1.8 文本

在 SVG 中有两种截然不同的文本模式。一种是写在图像中的文本,另一种是 SVG 字体。

<text x="10" y="10">Hello World!</text>

例子:

<!DOCTYPE html>
<html>
<body>

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="338" height="329" class="dms-border-svg-container">
	<defs>
		<filter id="border-box-2-filterId-1f9e558f-d1ab-4df6-b772-cedf24b55946" height="150%" width="150%" x="-25%" y="-25%" filterUnits="userSpaceOnUse">
			<feMorphology operator="dilate" radius="3" in="SourceAlpha" result="thicken"></feMorphology>
			<feGaussianBlur in="thicken" stdDeviation="3" result="blurred"></feGaussianBlur>
			<feFlood flood-color="rgba(141,197,255,0.2)" result="glowColor"></feFlood>
			<feComposite in="glowColor" in2="blurred" operator="in" result="softGlowColored"></feComposite>
			<feComposite in="softGlowColored" in2="SourceGraphic" operator="out" result="outSoftGlowColored"></feComposite>
			<feMerge>
				<feMergeNode in="outSoftGlowColored"></feMergeNode>
				<feMergeNode in="SourceGraphic"></feMergeNode>
			</feMerge>
		</filter>
	</defs>
	<path fill="transparent" stroke="rgb(0, 234, 255)" stroke-width="2" d="
      M86,1 h232 l19,19
      v289 l-19,19
      h-298 l-19,-19
      v-277
      l16,-16 h54 z
    "></path>
	<path fill="rgb(251, 249, 20)" d="M29,0 h8 l-12,12 h-8 z"></path>
	<path fill="rgb(251, 249, 20)" d="M40,0 h8 l-12,12 h-8 z"></path>
	<path fill="rgb(251, 249, 20)" d="M51,0 h8 l-12,12 h-8 z"></path>
	<path fill="rgb(251, 249, 20)" d="M62,0 h8 l-12,12 h-8 z"></path>
	<path fill="rgb(251, 249, 20)" d="M73,0 h8 l-12,12 h-8 z"></path>
	<path fill="rgb(251, 249, 20)" d="
      M298,329 h24 l16,-19 v-22
      l-4,4 v14 l-16,19 h-14 z
    "></path>
	<polygon fill="rgb(0, 234, 255)" filter="url(#border-box-2-filterId-1f9e558f-d1ab-4df6-b772-cedf24b55946)" points="
      302, 20 312, 30 302 40 306, 30
    "></polygon>
	<polyline fill="transparent" stroke="rgb(0, 234, 255)" points="
      299, 25 303, 30 299, 35
    "></polyline>
	</svg>
 
</body>
</html>

2 添加样式

可以使用CSS来为SVG元素添加样式,例如:

<style>
  line {
    stroke-width: 2;
  }

  rect {
    stroke: blue;
    stroke-width: 4;
  }

  circle {
    fill-opacity: 0.5;
  }

  polygon {
    fill: none;
    stroke: red;
    stroke-width: 3;
  }
</style>

1.3 延伸效果

1.3.1 动画

1.3.1.1 animateMotion

www.runoob.com/svg/svg-ref…

线性运动
<svg xmlns="http://www.w3.org/2000/svg" width="300" height="100">
  <title>SVG SMIL Animate with Path</title>
  <rect x="0" y="0" width="300" height="100" stroke="black" stroke-width="1" />
  <circle cx="0" cy="50" r="15" fill="blue" stroke="black" stroke-width="1">
    <animateMotion
       path="M 0 0 H 300 Z"
       dur="3s" repeatCount="indefinite" />
  </circle>
</svg>

由 MoveTo 命令和 Horizontal-line 命令、Z 命令构成的路径,MoveTo 命令命令指定动画路径的起始点,而 Horizontal-line 命令把圆移到右边 300 像素处,Z 命令闭合路径,建立一个回到起始点的回路

曲线运动
<svg width="300" height="100">
  <title>SVG SMIL Animate with Path</title>
  <rect x="0" y="0" width="300" height="100" stroke="black" stroke-width="1" />
  <rect x="0" y="0" width="20" height="20" fill="blue" stroke="black" stroke-width="1">
    <animateMotion
       path="M 250,80 H 50 Q 30,80 30,50 Q 30,20 50,20 H 250 Q 280,20,280,50 Q 280,80,250,80Z"
       dur="3s" repeatCount="indefinite" rotate="auto" />
  </rect>
</svg>
calcMode="动画的插补模式。可以是'discrete', 'linear', 'paced', 'spline'" path="运动路径" keyPoints="沿运动路径的对象目前时间应移动多远" rotate="应用旋转变换" xlink:href="一个URI引用元素,它定义运动路径"

1.3.1.2  animate

<svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">
  <rect width="10" height="10">
    <animate attributeName="rx" values="0;5;0" dur="10s" repeatCount="indefinite" />
  </rect>
</svg>

<svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">
  <rect width="10" height="10">
    <animate attributeName="rx"  from="0" to="10" dur="5s" repeatCount="indefinite" />
  </rect>
</svg>
attributeName --- "目标属性名称" from --- "起始值" to --- "结束值" dur --- "持续时间" repeatCount --- "动画时间将发生" values ---  values 属性具有不同的含义,具体取决于使用的上下文,它可以定义在动画过程中使用的值序列,或者它是颜色矩阵的数字列表,根据颜色类型的不同,它们的解释也不同。要执行的颜色更改。

注意: values在上方中: 是将图形放大缩小 0-5-0 缩小还原;from:原始大小,to: 结束大小

1.3.2 容器 defs

SVG 允许我们定义以后需要重复使用的图形元素。建议把所有需要再次使用的引用元素定义在defs元素里面。这样做可以增加 SVG 内容的易读性和无障碍。在defs元素中定义的图形元素不会直接呈现。你可以在你的视口的任意地方利用 元素呈现这些元素。

<svg width="80px" height="30px" viewBox="0 0 80 30"
     xmlns="http://www.w3.org/2000/svg">

  <defs>
    <linearGradient id="Gradient01">
      <stop offset="20%" stop-color="#39F" />
      <stop offset="90%" stop-color="#F3F" />
    </linearGradient>
  </defs>

  <rect x="10" y="10" width="60" height="10"
        fill="url(#Gradient01)"  />
</svg>

<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <style>
    .classA { fill:red }
  </style>
  <defs>
    <g id="Port">
      <circle style="fill:inherit" r="10"/>
    </g>
  </defs>

  <text y="15">black</text>
  <use x="50" y="10" xlink:href="#Port" />
  <text y="35">red</text>
  <use x="50" y="30" xlink:href="#Port" class="classA"/>
  <text y="55">blue</text>
  <use x="50" y="50" xlink:href="#Port" style="fill:blue"/>
 </svg>

linearGradient:定义线性渐变。通过使用矢量线性渐变填充对象,并可以定义为水平,垂直或角渐变。

id="id 属性可为渐变定义一个唯一的名称。引用必须" gradientUnits="'userSpaceOnUse' or 'objectBoundingBox'.使用视图框或对象,以确定相对位置矢量点。 (默认为'objectBoundingBox)" gradientTransform="适用于渐变的转变" x1="渐变向量x启动点(默认0%)" y1="渐变向量y启动点(默认0%)" x2="渐变向量x的终点。 (默认100%)" y2="渐变向量y的终点。 (默认0%)" spreadMethod="'pad' or 'reflect' or 'repeat'" xlink:href="reference to another gradient whose attribute values are used as defaults and stops included. Recursive"

use :使用URI引用一个,或其他具有一个唯一的ID属性和重复的图形元素。复制的是原始的元素,因此文件中的原始存在只是一个参考。原始影响到所有副本的任何改变。

x="克隆元素的左上角的x轴" y="克隆元素的左上角的y轴" width="克隆元素的宽度" height="克隆元素的高度" xlink:href="URI引用克隆元素"

1.3.3 滤镜

SVG在使用了滤镜的元素里,不会将原始图形直接渲染出来,而是会将原始图形的像素信息渲染到临时位图中,然后由 filter元素指定的操作会被应用到这个临时位图,最终把计算结果渲染为最终图形输出。

<svg viewBox="0 0 480 200" xmlns="http://www.w3.org/2000/svg">
  <filter id="gaussianBlur1">
    <feGaussianBlur stdDeviation="1" />
  </filter>
  <filter id="gaussianBlur2">
    <feGaussianBlur stdDeviation="5" />
  </filter>
  <filter id="gaussianBlur3" x="-30%" y="-30%" width="160%" height="160%">
    <feGaussianBlur stdDeviation="10" />
  </filter>

  <circle cx="100" cy="100" r="50" style="filter: url(#gaussianBlur1);" />
  <circle
    cx="100"
    cy="100"
    r="50"
    style="filter: url(#gaussianBlur2); transform: translateX(140px);" />
  <circle
    cx="100"
    cy="100"
    r="50"
    style="filter: url(#gaussianBlur3); transform: translateX(280px);" />
</svg>
feMorphology:SVG 滤镜。 feGaussianBlur:SVG滤镜。执行高斯模糊图像。 feFlood:SVG滤镜 feComposite:SVG 滤镜 feMerge:SVG滤镜。建立在彼此顶部图像层 feMergeNode:SVG 滤镜。feMerge的子元素 (元素拿另一个滤镜的结果,让它的父元素处理。)
filter:滤镜效果的容器 x ---  用户坐标系统中标识了一个 x 轴坐标 y ---  用户坐标系统中标识了一个 y 轴坐标。 width --- 用户坐标系统中定义了元素的一个水平长度。 height --- 用户坐标系统中标识了一个垂直长度        1.该坐标的确切效果依赖于每个元素。大多数时候,它体现引用元素的矩形区域的高度;       2.除了元素之外,别的元素都必须指定该属性,的高度默认是 100%****,而  元素以及  元素的默认高度是 120%****。
stdDeviation :定义了模糊操作的标准差。值越大,模糊效果越强。       1:如果列出两个数值,第一个数字表示沿着 x 轴的标准差值。第二个值表示沿着 y 轴的标准差值。如果只提供了一个数字,那个值就表示在 x 轴和 y 轴上有着相同的标准差;       2:负值是不允许的。设为零即禁用了已有滤镜的原本效果(比如,结果是滤镜输入图像)。如果 stdDeviation 在 x 轴和 y 轴上只有一个为 0,那么模糊效果就只会应用于非 0 的那个方向。

参考文档:

www.runoob.com/svg/svg-tut…

SVG:可缩放矢量图形 | MDN