Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SVG教程 #38

Open
Marinerer opened this issue Mar 16, 2021 · 4 comments
Open

SVG教程 #38

Marinerer opened this issue Mar 16, 2021 · 4 comments

Comments

@Marinerer
Copy link
Owner

Marinerer commented Mar 16, 2021

@Marinerer
Copy link
Owner Author

Marinerer commented Mar 16, 2021

SVG入门教程

源自:https://www.ruanyifeng.com/blog/2018/08/svg.html
参考:MDN SVG教程
贝塞尔曲线 - 维基百科

[TOC]

概述

SVG 是一种基于 XML 语法的图像格式,全称是可缩放矢量图(Scalable Vector Graphics)。其他图像格式都是基于像素处理的,SVG 则是属于对图像的形状描述,所以它本质上是文本文件,体积较小,且不管放大多少倍都不会失真。

  1. SVG 文件可以直接插入网页,成为 DOM 的一部分,然后用 JavaScript 和 CSS 进行操作。
  2. SVG 代码也可以写在一个独立文件中,然后用<img><object><embed><iframe>等标签插入网页。
  3. CSS 也可以使用 SVG 文件
  4. SVG 文件还可以转为 BASE64 编码,然后作为 Data URI 写入网页
<html>
  <head>SVG</head>
  <body>
    <!--直接插入svg代码-->
    <svg width="300" height="180">
      <circle cx="30"  cy="50" r="25" />
    </svg>
    
    <!--独立文件插入-->
    <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>

    <!--base64-->
    <img src="data:image/svg+xml;base64,[data]">
    
    <!--css中引入-->
    <style>
    .logo {
      background: url(icon.svg);
    }
    </style>
  </body>
</html>

语法

2.1 <svg>标签

SVG 代码都放在顶层标签<svg>之中。下面是一个例子。

<svg width="450" height="400" viewBox="0 0 450 400" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <path id="lineAB" d="M 100 350 l 150 -300" stroke="red" stroke-width="3" fill="none" />
  <path id="lineBC" d="M 250 50 l 150 300" stroke="red" stroke-width="3" fill="none" />
  <path d="M 175 200 l 150 0" stroke="green" stroke-width="3" fill="none" />
  <path d="M 100 350 q 150 -300 300 0" stroke="blue" stroke-width="5" fill="none" />
  <!-- Mark relevant points -->
  <g stroke="black" stroke-width="3" fill="black">
    <circle id="pointA" cx="100" cy="350" r="3" />
    <circle id="pointB" cx="250" cy="50" r="3" />
    <circle id="pointC" cx="400" cy="350" r="3" />
  </g>
  <!-- Label the points -->
  <g font-size="30" font-family="sans-serif" fill="black" stroke="none" text-anchor="middle">
    <text x="100" y="350" dx="-30">A</text>
    <text x="250" y="50" dy="-10">B</text>
    <text x="400" y="350" dx="30">C</text>
  </g>
  Sorry, your browser does not support inline SVG.
</svg>

<svg>width属性和height属性,指定了 SVG 图像在 HTML 元素中所占据的宽度和高度。除了相对单位,也可以采用绝对单位(单位:像素)。如果不指定这两个属性,SVG 图像默认大小是300像素(宽) x 150像素(高)。

如果只想展示 SVG 图像的一部分,就要指定viewBox属性。

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

<viewBox>属性的值有四个数字,分别是左上角的横坐标和纵坐标、视口的宽度和高度。上面代码中,SVG 图像是100像素宽 x 100像素高,viewBox属性指定视口从(50, 50)这个点开始。所以,实际看到的是右下角的四分之一圆。

注意,视口必须适配所在的空间。上面代码中,视口的大小是 50 x 50,由于 SVG 图像的大小是 100 x 100,所以视口会放大去适配 SVG 图像的大小,即放大了四倍。

如果不指定width属性和height属性,只指定viewBox属性,则相当于只给定 SVG 图像的长宽比。这时,SVG 图像的默认大小将等于所在的 HTML 元素的大小。

2.2 <circle>圆形

<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>

上面的代码定义了三个圆。<circle>标签的cxcyr属性分别为横坐标、纵坐标和半径,单位为像素。坐标都是相对于<svg>画布的左上角原点。

class属性用来指定对应的 CSS 类。

.red {
	fill: red;
}

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

SVG 的 CSS 属性与网页元素有所不同。

  • fill:填充色
  • stroke:描边色
  • stroke-width:边框宽度
  • stroke-linecap:控制边框终点的形状
    • butt用直边结束线段,它是常规做法,线段边界90度垂直于描边的方向、贯穿它的终点。
    • square的效果差不多,但是会稍微超出实际路径的范围,超出的大小由stroke-width控制。
    • round表示边框的终点是圆角,圆角的半径也是由stroke-width控制的。
  • stroke-linejoin:控制两条描边线段之间,用什么样式连接 ,比如尖角、圆弧、横切
    • miter
    • round
    • bevel

2.3 <line>直线

<line>标签用来绘制直线。

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

上面代码中,<line>标签的x1属性和y1属性,表示线段起点的横坐标和纵坐标;x2属性和y2属性,表示线段终点的横坐标和纵坐标;style属性表示线段的样式。

2.4 <polyline>折线

<polyline>标签用于绘制一根折线。

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

<polyline>points属性指定了每个端点的坐标,横坐标与纵坐标之间与逗号分隔,点与点之间用空格分隔。

2.5 <rect>矩形

<rect>标签用于绘制矩形。

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

<rect>x属性和y属性,指定了矩形左上角端点的横坐标和纵坐标;width属性和height属性指定了矩形的宽度和高度(单位像素)。

rxry 属性可以创建圆角矩形,rx定义水平轴向的圆角半径,ry定义垂直轴向的圆角半径。

2.6 <ellipse>椭圆

<ellipse>标签用于绘制椭圆。

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

<ellipse>cx属性和cy属性,指定了椭圆中心的横坐标和纵坐标(单位像素);rx属性和ry属性,指定了椭圆横向轴和纵向轴的半径(单位像素)。

2.7 <polygon>多边形

<polygon>标签用于绘制多边形。

<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>

<polygon>points属性指定了每个端点的坐标,横坐标与纵坐标之间与逗号分隔,点与点之间用空格分隔。

2.8 <path>路径

<path>标签用于制路径。

<svg width="90" height="90">
  <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="blue" />
</svg>

<svg width="90" height="90">
  <path d="
     M60,30 
     a30,30 0 0,1 0,60 
     L0,90 0,30 
     a30,30 0 0,1 60,0" fill="red" />
</svg>

<svg width="90" height="90">
  <path d="
      M75,45 
      a30,30 0 0,1 -60,0 
      a30,30 0 0,1 60,0" stroke-width="1" stroke="blue" fill="none"/>
</svg>

<path>d属性表示绘制顺序,它的值是一个长字符串,每个字母表示一个绘制动作,后面跟着坐标。

  • M:移动到(moveto)
  • L:画直线到(lineto)
  • Z:闭合路径
  • A:弧形
  • C:贝塞尔曲线

Path相关指令:

先罗列一下有关于<path>元素相关的指令:

⚠️ 特别注意: 参数大写代表绝对坐标,小写代表与前一个坐标的相对座标

指令 参数 描述
M x y 起始点坐标x yMove to
L x y 从当前点的坐标画直线到指定点的 x y坐标 (Line to
H x 从当前点的坐标画水平直线到指定的x轴坐标 (Horizontal line to
V y 从当前点的座标画垂直直线到指定的y轴坐标 (Vertical line to
C x1 y1 x2 y2 x y 从当前点的坐标画条贝塞尔曲线到指定点的x, y坐标,其中 x1 y1x2, y2为控制点 (Curve
S x2 y2 x y 从当前点的坐标画条反射的贝塞曲线到指定点的x, y坐标,其中x2, y2为反射的控制点(Smooth curve
Q x1 y1 x y 从当前点的坐标画条反射二次贝塞曲线到指定点的x, y坐标,其中x1 y1为控制点(Quadratic Bézier curve
T x y 从当前点的坐标画条反射二次贝塞曲线到指定点的x, y坐标,以前一个坐标为反射控制点(Smooth Quadratic Bézier curve
A rx ry x-axis-rotation large-arc-flag sweep-flag x y 从当前点的坐标画个椭圆形到指定点的x, y坐标,其中rx, ry为椭圆形的x轴及y轴的半径,x-axis-rotation是弧线与x轴的旋转角度,large-arc-flag则设定1最大角度的弧线或是0最小角度的弧线,sweep-flag设定方向为1顺时针方向或0逆时针方向(Arc
Z 关闭路径,将当前点坐标与第一个点的坐标连接起来(Closepath

cubic-bezier

贝塞尔曲线 - 维基百科

2.9 <text>文本

<text>标签用于绘制文本。

<svg height="200" width="200">
  <text x="10" y="20" style="fill:red;" font-weight="bold">Several lines:
    <tspan x="24" y="45">First line.</tspan>
    <tspan x="24" y="70">Second line.</tspan>
  </text>
</svg>

<text>x属性和y属性,表示文本区块基线(baseline)起点的横坐标和纵坐标。文字的样式可以用classstyle属性指定。

设置字体属性:

SVG提供了一些属性,类似于它们的CSS同行,用来激活文本选区。下列每个属性可以被设置为一个SVG属性或者成为一个CSS声明:font-familyfont-stylefont-weightfont-variantfont-stretchfont-sizefont-size-adjustkerningletter-spacingword-spacingtext-decoration

文本相关的元素:

  • tspan : 用来标记大块文本的子部分,它必须是一个text元素或别的tspan元素的子元素。
  • tref : 允许引用已经定义的文本,高效地把它复制到当前位置。你可以使用xlink:href属性,把它指向一个元素,取得其文本内容。你可以独立于源样式化它、修改它的外观。
  • textPath : 该元素利用它的xlink:href属性取得一个任意路径,把字符对齐到路径,于是字体会环绕路径、顺着路径走。

2.10 <use>标签

<use>标签用于复制一个形状。

<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>

<use>href属性指定所要复制的节点,x属性和y属性是<use>左上角的坐标。另外,还可以指定widthheight坐标。

2.11 <g>

<g>标签用于将多个形状组成一个组(group),方便复用。

<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>

2.12 <defs>标签

<defs>标签用于自定义形状,它内部的代码不会显示,仅供引用。

<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>

2.13 <pattern>标签

<pattern>标签用于自定义一个形状,该形状可以被引用来平铺一个区域。

<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>

上面代码中,<pattern>标签将一个圆形定义为dots模式。patternUnits="userSpaceOnUse"表示<pattern>的宽度和长度是实际的像素值。然后,指定这个模式去填充下面的矩形。

2.14 <image>图片

<image>标签用于插入图片文件。

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

上面代码中,<image>xlink:href属性表示图像的来源。

2.15 <animate>动画

<animate>标签用于产生动画效果。

<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>

上面代码中,矩形会不断移动,产生动画效果。

<animate>的属性含义如下。

  • attributeName:发生动画效果的属性名。
  • from:单次动画的初始值。
  • to:单次动画的结束值。
  • dur:单次动画的持续时间。
  • repeatCount:动画的循环模式。

可以在多个属性上面定义动画。

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

2.16 <animateTransform>变形动画

<animate>标签对 CSS 的transform属性不起作用,如果需要变形,就要使用<animateTransform>标签。

<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>

上面代码中,<animateTransform>的效果为旋转(rotate),这时fromto属性值有三个数字,第一个数字是角度值,第二个值和第三个值是旋转中心的坐标。from="0 200 200"表示开始时,角度为0,围绕(200, 200)开始旋转;to="360 400 400"表示结束时,角度为360,围绕(400, 400)旋转。

2.17 <animateMotion> 路径动画

<animateMotion> 元素可以定义一个元素沿着指定路径进行移动。

  1. 直线路径可以简单使用from + to属性来指定起点和终点;
  2. 使用path指定复杂的路径;
  3. 可以指定<path>元素作为自己的路径

**注意:**为了复用一个已经定义的路径,就有必要使用一个 mpath 元素嵌入到 <animateMotion> 中,而不是使用 path

例如: <mpath xlink:href="#cubicCurve"/>

<svg viewBox="0 0 200 100">
  <path id="cubicCurve" fill="none" stroke="lightgrey" d="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z" />

  <circle r="5" fill="red">
    <animateMotion
    	dur="10s"
    	repeatCount="indefinite"
    	path="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z"
    />
  </circle>
  
  <rect x="0" y="0" width="10" height="10" fill="blue">
    <animateMotion dur="20" repeatCount="indefinite">
      <mpath xlink:href="#cubicCurve" />
    </animateMotion>
  </rect>
</svg>

<animateMotion>有个rotate属性,默认为0,元素在运动时不会旋转。当设置为auto时,元素对应的水平轴会始终与path路径保持水平,上图中加上rotate="auto"后的效果就像是车子开过山坡。

2.17 <linearGradient> 线性渐变

渐变有两种类型:线性渐变径向渐变。你必须给渐变内容指定一个id属性,否则文档内的其他元素就不能引用它。为了让渐变能被重复使用,渐变内容需要定义在<defs>标签内部,而不是定义在形状上面。

线性渐变沿着直线改变颜色,要插入一个线性渐变,你需要在SVG文件的defs元素内部,创建一个<linearGradient> 节点。

<svg width="120" height="240" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <defs>
      <linearGradient id="Gradient1">
        <stop class="stop1" offset="0%"/>
        <stop class="stop2" offset="50%"/>
        <stop class="stop3" offset="100%"/>
      </linearGradient>
      <linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1">
        <stop offset="0%" stop-color="red"/>
        <stop offset="50%" stop-color="black" stop-opacity="0"/>
        <stop offset="100%" stop-color="blue"/>
      </linearGradient>
      <style type="text/css"><![CDATA[
        #rect1 { fill: url(#Gradient1); }
        .stop1 { stop-color: red; }
        .stop2 { stop-color: black; stop-opacity: 0; }
        .stop3 { stop-color: blue; }
      ]]></style>
  </defs>

  <rect id="rect1" x="10" y="10" rx="15" ry="15" width="100" height="100"/>
  <rect x="10" y="120" rx="15" ry="15" width="100" height="100" fill="url(#Gradient2)"/>

</svg>

2.18 <radialGradient>径向渐变

<?xml version="1.0" standalone="no"?>
<svg width="120" height="240" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <defs>
      <radialGradient id="RadialGradient1">
        <stop offset="0%" stop-color="red"/>
        <stop offset="100%" stop-color="blue"/>
      </radialGradient>
      <radialGradient id="RadialGradient2" cx="0.25" cy="0.25" r="0.25">
        <stop offset="0%" stop-color="red"/>
        <stop offset="100%" stop-color="blue"/>
      </radialGradient>
  </defs>

  <rect x="10" y="10" rx="15" ry="15" width="100" height="100" fill="url(#RadialGradient1)"/>
  <rect x="10" y="120" rx="15" ry="15" width="100" height="100" fill="url(#RadialGradient2)"/>

</svg>

2.19 <clipPath>剪切

我们在一个圆形的基础上创建半圆形,在(100,100)创建一个圆形,半径是100。属性clip-path引用了一个带单个rect元素的<clipPath>元素。它内部的这个矩形将把画布的上半部分涂黑。注意,clipPath元素经常放在一个defs元素内。

<svg version="1.1">
  <defs>
    <clipPath id="cut-off-bottom">
      <rect x="0" y="0" width="200" height="100" />
    </clipPath>
  </defs>

  <circle cx="100" cy="100" r="100" clip-path="url(#cut-off-bottom)" />
</svg>

2.20 <mask>遮罩

遮罩的效果最令人印象深刻的是表现为一个渐变。如果你想要让一个元素淡出,你可以利用遮罩效果实现。

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <linearGradient id="Gradient">
      <stop offset="0" stop-color="white" stop-opacity="0" />
      <stop offset="1" stop-color="white" stop-opacity="1" />
    </linearGradient>
    <mask id="Mask">
      <rect x="0" y="0" width="200" height="200" fill="url(#Gradient)"  />
    </mask>
  </defs>

  <rect x="0" y="0" width="200" height="200" fill="green" />
  <rect x="0" y="0" width="200" height="200" fill="red" mask="url(#Mask)" />
</svg>

2.21 <filter>滤镜

https://developer.mozilla.org/zh-CN/docs/Web/SVG/Tutorial/Filter_effects

填充和描边

以下属性均可以直接用作CSS样式表内部的属性。

填充属性

fill : 设置SVG对象内部的填充色。可选值:颜色值 | none
fill-rule : 确定形状内部(即要填充的区域)的算法。 可选值:nonzero | evenodd
fill-opacity : 控制填充色的不透明度。 可选值:[0-1] | <percentage>

fill-rule 比较难懂,详见 https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill-rule

描边属性

  • stroke : 描边颜色

  • stroke-width : 描边的粗细

  • stroke-linecap : 描边端点表现方式。可选值:butt | round | square

  • stroke-linejoin : 描边转角的表现方式。可选值:miter(尖角) | round(圆角) | bevel(斜角)

  • stroke-miterlimit : 描边相交(锐角)的表现方式。默认大小是4

    stroke-miterlimit 属性给 miter-lengthstroke-width 之间的比率做了限制,它的比值范围应大于或等于1。当比值不在这个范围的时候, stroke 就会被转换成斜角(bevel)。

  • stroke-dasharray : 设置虚线描边。可选值为:none | <dasharray>

  • stroke-dashoffset : 虚线的起始偏移。可选值为:<percentage> | <length>

  • stroke-opacity : 描边透明度。默认是1

stroke-dasharraystroke-dashoffset 可用于实现描边动画。

🌰 心形路径动画例子:

<svg class="heart" width="90" height="90" viewBox="0 0 90 90">
  <g class="heart-group">
    <path class="heart-heartPath" stroke-width="2" d="M60,30 a30,30 0 0,1 0,60 L0,90 0,30 a30,30 0 0,1 60,0" />
  </g>
</svg>

<style>
.heart {
  margin: 90px;
  overflow: visible;
  
  &-group {
    transform-origin: 0 90px;
    transform: rotate(-45deg);
    animation: group-anim 4s infinite;
  }
  
  &-heartPath {
    stroke: #E21737;
    fill: transparent;
    stroke-dasharray: 308.522, 308.522;
    stroke-dashoffset: 308.522;
    animation: heart-anim 4s infinite;
  }
}
@keyframes group-anim {
  0%, 100% {
    opacity: 0;
  }
  40%, 90% {
    opacity: 1;
  }
}
@keyframes heart-anim {
  15% {
    stroke-dashoffset: 308.522;
    fill: transparent;
  }
  50% {
    stroke-dashoffset: 0;
    fill: transparent;
  }
  70%, 100% {
    stroke-dashoffset: 0;
    fill: #E21737;
  }
}
</style>

其他属性

vector-effect

vector-effect 指定绘制对象时要使用的矢量效果。矢量效果会先于其他任何合成操作(即滤镜,蒙版和剪辑)应用。

可选值:none | non-scaling-stroke | non-scaling-size | non-rotation | fixed-position
最常用的就是 non-scaling-stroke ,指定描边宽度不随SVG本身尺寸变大而变大。

JavaScript 操作

3.1 DOM 操作

如果 SVG 代码直接写在 HTML 网页之中,它就成为网页 DOM 的一部分,可以直接用 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>

上面代码插入网页之后,就可以用 CSS 定制样式。

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

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

然后,可以用 JavaScript 代码操作 SVG。

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

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

上面代码指定,如果点击图形,就改写circle元素的r属性。

3.2 获取 SVG DOM

使用<object><iframe><embed>标签插入 SVG 文件,可以获取 SVG DOM。

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

注意,如果使用<img>标签插入 SVG 文件,就无法获取 SVG DOM。

3.3 读取 SVG 源码

由于 SVG 文件就是一段 XML 文本,因此可以通过读取 XML 代码的方式,读取 SVG 源码。

<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>

使用XMLSerializer实例的serializeToString()方法,获取 SVG 元素的代码。

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

@Marinerer
Copy link
Owner Author

SVG动画入门

源自:https://segmentfault.com/a/1190000009371194
参考: https://www.zhangxinxu.com/wordpress/2014/08/so-powerful-svg-smil-animation/

[toc]

1. <animate> 基本动画

<animate> 元素用于实现动画效果。
可以将<animate>元素嵌入到元素内,来实现该元素的动画效果。

<rect x="10" y="10" width="200" height="20" stroke="black" fill="none">
    <animate
      attributeName="width"
      attributeType="XML"
      from="200"
      to="20"
      begin="0s"
      dur="5s"
      fill="freeze"
    />
</rect>

以上代码会生成一个200x20的长方形,在5秒内渐变成一个20x20的正方形,并且在动画结束时停留在正方形的状态。

1.1 动画属性

attributeName = <attributeName>

定义发生变化的元素属性名

  1. 可以是元素直接暴露的属性。例如<ellipse>元素的cxcy
  2. 可以是CSS属性。例如,透明度opacity

attributeType = CSS | XML | auto

attributeType="XML"时,attributeName被认为是XML的属性;当attributeType="CSS"时,attributeName被认为是css的属性;不指定attributeType时,默认为"auto",会先将attributeName作为css的属性,如果无效,再将attributeName作为XML的属性。

例如 x, y以及transform就属于XMLopacity就属于CSS

from & to & by & values

上面4个属性是一个家族的,他们要解决的问题:你从哪里来?要到哪里去?...

  • from = <value> : 动画的起始值
  • to = <value> : 指定动画的结束值
  • by = <value> : 动画的相对变化值
  • values = <list> : 用分号分隔的一个或多个值,可用于多节点动画

from, to, by, values虽然属于一个家族,但是相互之间还是有制约关系的。有以下一些规则:

  1. 如果动画的起始值与元素的默认值是一样的,from参数可以省略。
  2. (不考虑valuesto,by两个参数至少需要有一个出现。否则动画效果没有。to表示绝对值,by表示相对值。拿位移距离,如果from100, to值为160则表示移动到160这个位置,但是,如果by值是160,则表示移动到100+160=260这个位置。
  3. 如果to,by同时出现,则by打酱油,只识别to.
  4. 如果to,by,values都没设置,自然没动画效果。如果任意(包括from)一个属性的值不合法,规范上说是没有动画效果。
  5. values可以是一个值或多值。经测试,是一个值的时候是没有动画效果。多值时候有动画效果。当values值设置并能识别时候,from, to, by的值都会被忽略。当我们实现动画,不可能就是单纯的从a位置到b位置,有时候,需要去c位置过渡下。此时,实际上有3个动画关键点。而from, to/by只能驾驭两个,此时就可以用values来实现。
<svg viewBox="0 0 10 10">
  <rect width="10" height="10">
    <animate attributeName="rx" values="0;5;0" dur="10s" repeatCount="indefinite" />
  </rect>
</svg>

总结下,也就是from-to动画、from-by动画、to动画、by动画以及values动画。

begin & dur & end

  • begin 定义动画开始时间;
  • dur 表示单次动画的持续时间;
  • end 定义动画终止时间。

时间单位:h:小时;min:分钟;s:秒;ms:毫秒。默认时间单位为s

begin, end 也可以是分号分隔的一组值(单值只是其中的情况之一)。例如,beigin="3s;5s"表示的是3s之后动画走一下,6s时候动画再走一下(如果之前动画没走完,会立即停止从头开始)。所以,如果一次动画时间为3s, 即dur="3s",同时没有repeatCount属性时候,我们可以看到动画似乎连续执行了2次。

begin的单值除了普通value,还有下面这些类别的value:
offset-value | syncbase-value | event-value | repeat-value | accessKey-value | media-marker-value | wallclock-sync-value | "indefinite"

详见(https://www.zhangxinxu.com/wordpress/2014/08/so-powerful-svg-smil-animation/)

fill

fill="freeze"时,动画终止时,发生变化的元素属性值停留在动画终止时的状态;
fill="remove"时,动画终止时,发生变化的元素属性值回复到动画起始时的状态。fill属性默认值为remove

允许在同一个元素内嵌入多个<animate>

<rect x="10" y="10" width="20" height="20" style="stroke: black; fill: #cfc;">
    <animate attributeName="width" attributeType="XML" begin="0s" dur="2s" from="20" to="120" fill="freeze"/>
    <animate attributeName="height" attributeType="XML" begin="0s" dur="2s" from="20" by="100" fill="freeze"/>
</rect>

accumulate, additive

有时候我们需要动画能够以它之前的动画结束点作为开始,比如,你需要一个元素的某个属性值一直增加,这个时候我们就需要使用additive和accumulate。

1. accumulate
accumulate 控制动画是否累加,在原来的结果的基础上重复动画的时候,它通常很有用,每一次循环都累加。这个属性告诉动画是否是每次循环,前一个动画属性值要加上去。

- `nonoe` : 重复循环是不累加的。这是默认值。
- `sum` : 表示动画结束时候的位置作为下次动画的起始位置

如果目标属性不支持累加,动画并没有重复,或者是动画仅规定了to属性,这时accumulate会失效。

2. additive
additive 控制动画是否附加。

- `replace` : 默认值,指定动画的基础值将覆盖其他低优先级的动画上。
- `sum` : 表示动画的基础值会附加到其他低优先级的动画上。
<svg width="500" height="500">
  <rect x="150" y="150" width="50" height="50" fill="#4bc0c8">
    <animateTransform attributeName="transform" type="scale" from="1" to="2" dur="10s" repeatCount="indefinite" additive="sum"/>
    <animateTransform attributeName="transform" type="rotate" from="0 100 120" to="360 150 150" dur="10s" fill="freeze" repeatCount="indefinite" additive="sum"/>
  </rect>
</svg>

1.2 动画时间

当begin设置为一个具体时间,比如2s,svg会在元素加载完毕后,过2秒开始执行动画。
begin还可以指定一个其他<animate>的begin或者end,比如:

<circle cx="60" cy="60" r="30" style="fill: #f9f; stroke: gray;">
    <animate id="c1" attributeName="r" attributeType="XML" begin="0s" dur="4s" from="30"  to="10" fill="freeze"/>
</circle>
<circle cx="120" cy="60" r="10" style="fill: #9f9; stroke: gray;">
    <animate attributeName="r" attributeType="XML" begin="c1.end" dur="4s" from="10" to="30" fill="freeze"/>
</circle>

第二个圆的动画执行起始时间为第一个圆动画执行完毕时间。
begin属性还可以进行简单计算:
begin="c1.end+1.5s":表示动画执行起始时间为第一个圆执行完毕后的1.5秒。

当end设置为一个具体时间,比如2s,svg会在元素加载完毕后,过2秒即停止执行动画,不管这个元素的动画是否执行完毕。如果end设置的比begin小,则动画根本不会执行。

end同样可以指定一个其他<animate>的begin或者end,同样支持计算。

其他参见(https://www.zhangxinxu.com/wordpress/2014/08/so-powerful-svg-smil-animation/)

1.3 重复动画

通过设置repeatDur或者repeatCount属性,让动画重复执行。

  • repeatDur : 设置动画执行的总时长。在repeatDur设置的时间内,动画一直会重复执行。如果repeatDur小于dur,repeatDur的作用与end一样。
  • repeatCount : 设置动画重复执行的次数。

repeatDur和repeatCount都可以通过设置为indefinit实现无限循环动画。
当repeatDur和repeatCount同时作用于同一个<animate>时,动画终止时间取两者中较小值。

repeat可作为begin和end中的参数使用:

<circle cx="60" cy="60" r="15" style="fill: none; stroke: red;">
    <animate id="circleAnim" attributeName="cx" attributeType="XML" begin="0s" dur="5s" repeatCount="3" from="60" to="260" fill="freeze"/>
</circle>
<rect x="230" y="80" width="30" height="30" style="fill: #ccf; stroke: black;">
    <animate attributeName="x" attributeType="XML" begin="circleAnim.repeat(1)+2.5s" dur="5s" from="230" to="30" fill="freeze"/>
</rect>

长方形的动画会在圆形动画执行过一遍后延迟2.5秒后开始执行。

repeat(n)中的n需大于0。

1.4 多节点动画

实现一个属性的连续变化有两种方式:

  1. 多个<animate>组合
  2. 使用values + keyTimes + calcMode属性

values = <list>

values属性值表示一个动画经过的节点数值,数值间以分号分割。

<circle cx="175" cy="75" r="20" fill="red">
    <animate attributeName="r"
             attributeType="XML"
             values="20;50;20"
             begin="0" dur="1" repeatCount="indefinite"
             fill="freeze">
  	</animate>
</circle>

上例中1秒内,圆的半径由20变为50,再由50变为20。

keyTimes = <list>

keyTimes属性值与values属性值一一对应,第一个数值永远是0(表示起始时间点),最后一个数值永远是1(表示终止时间点),中间的数值表示变化到对应values属性值时所处时间点百分比(0~1之间)。

<circle cx="175" cy="75" r="20" fill="red">
    <animate attributeName="r"
             attributeType="XML"
             values="20;50;20"
             keyTimes="0;0.2;1"
             begin="0" dur="1" repeatCount="indefinite"
             fill="freeze">
  	</animate>
</circle>

上例中0.2秒时圆的半径由20变为50,在之后的0.8秒又从50变为20。

calcMode = <calcMode>

calcMode可以影响动画各阶段的表现。calcMode有四种属性值:paced, linear, discrete, spline

  • calcMode="paced"时,动画会忽略keyTimes属性,根据values数值以匀速变化。仅支持线性数值区域内的值,这样点之间“距离”的概念才能被计算(如position, width, height等)
  • calcMode="linear"时,动画根据values和keyTimes属性,在每个时间段内匀速变化。linear为calcMode的默认属性值
  • calcMode="discrete"时,动画根据values和keyTimes属性,去掉过渡动画,到了keyTimes的某个节点,属性值直接变为values对应数值。
  • calcMode="spline"时,需要配合keySplines属性,设置每个时间段内的三次贝塞尔变化曲线。
<circle cx="75" cy="75" r="20" fill="red">
    <animate attributeName="r"
             attributeType="XML"
             values="20;50;20"
             keyTimes="0;.15;1"
             calcMode="spline"  keySplines=".5 0 .5 1;.5 0 .5 1"
             begin="0" dur="1" repeatCount="indefinite"
             fill="freeze">
  	</animate>
</circle>

上例中加上贝塞尔曲线后圆形的变化有点类似心跳的节奏。

keySplines = <list>

keySplines表示与keyTimes相关联的一组贝塞尔控制点(默认0 0 1 1)。每个控制点使用4个浮点值表示:x1 y1 x2 y2

只有模式calcMode = spline 时候这个参数才有用,也是分号分隔,值范围0~1,总是比keyTimes少一个值。

如果keySplines值不合法或个数不对,是没有动画效果的。

2. <set>

<set>元素也可设置属性变化的动画,但与<animate>有明显区别:

  • 不需要from属性,起始状态即为父节点属性值。
  • 一到begin属性设置的时点,指定的attributeName属性值即改为to指定的属性值,没有过渡动画
  • attributeName可以是属性值非数字的属性,如style="visibility: hidden;"
<text text-anchor="middle" x="60" y="60" style="visibility: hidden;">
    <set attributeName="visibility" attributeType="CSS"
         to="visible" begin="1s" dur="10s" fill="freeze"></set>
    <set attributeName="x" attributeType="XML"
         to="120" begin="2s" dur="10s" fill="freeze"></set>
    All gone!
</text>

上例中1秒后显示All gone!,再过1秒后文字移动至(120,60)。

3. <animateTransform> 变形动画

<animate>标签对 CSS 的transform属性不起作用, 要实现transform属性改变的动画,需要使用<animateTransform>来替代<animate>

<rect x="-10" y="-10" width="20" height="20" style="fill: #ff9; stroke: black;">
    <animateTransform id="a1" attributeName="transform" attributeType="XML" type="scale" from="1" to="4 2" additive="sum" begin="0s" dur="4s" fill="freeze"></animateTransform>
    <animateTransform attributeName="transform" attributeType="XML" type="rotate" from="0" to="45" additive="sum" begin="a1.end" dur="4s" fill="freeze"></animateTransform>
</rect>

<animateTransform>的attributeName指定为transform。用type属性指定transform需要改变的属性(translate, scale, rotate, skewX, skewY)。

<animateTransform>还有个additive属性。上例中两个<animateTransform>同时作用于一个<rect>元素,默认情况下additive属性值为replace,表示当前<animateTransform>的初始状态与之前的<animateTransform>变化结果无关。如果additive="sum",表示当前<animateTransform>的变化基于之前的<animateTransform>变化之上。

4. <animateMotion> 路径动画

<animateMotion> 元素可以定义一个元素沿着指定路径进行移动。

  1. 直线路径可以简单使用from + to属性来指定起点和终点;
  2. 使用path指定复杂的路径;
  3. 可以指定<path>元素作为自己的路径

**注意:**为了复用一个已经定义的路径,就有必要使用一个 mpath 元素嵌入到 <animateMotion> 中,而不是使用 path

例如: <mpath xlink:href="#cubicCurve"/>

<svg viewBox="0 0 200 100">
  <path id="cubicCurve" fill="none" stroke="lightgrey" d="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z" />

  <circle r="5" fill="red">
    <animateMotion
    	dur="10s"
    	repeatCount="indefinite"
    	path="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z"
    />
  </circle>
  
  <rect x="0" y="0" width="10" height="10" fill="blue">
    <animateMotion dur="20" repeatCount="indefinite">
      <mpath xlink:href="#cubicCurve" />
    </animateMotion>
  </rect>
</svg>

<animateMotion>有个rotate属性,默认为0,元素在运动时不会旋转。当设置为auto时,元素对应的水平轴会始终与path路径保持水平,上图中加上rotate="auto"后的效果就像是车子开过山坡。

节点属性

calcMode

与多节点动画中的calcMode属性值及作用完全一致。

keyPoints

第一个属性值为0(表示path路径的起始位置),最后一个属性值为1(表示path路径的终点位置),各属性值用分号分割,每个属性值与keyTimes的属性值一一对应,表示到某个时点运动到相对于路径的哪个位置。

keyTimes

第一个属性值为0(表示动画起始时间),最后一个属性值为1(表示动画终止时间),各属性值用分号分割,每个属性值与keyPoints的属性值一一对应,表示运动到某个位置需要的总动画时常占比。

<path d="M-10,-3 L10,-3 L0,-25z" style="fill: yellow; stroke: red;" >
    <animateMotion
    path="M50,125 C 100,25 150,225, 200, 125"
    rotate="auto"
    keyPoints="0;0.2;0.8;1"
    keyTimes="0;0.33;0.66;1"
    calcMode="linear"
    dur="6s" fill="freeze"/>
</path>

5. CSS动画

css中的两种实现动画方式 transitionanimation 都可以直接应用于 SVG的DOM元素。

transition

<single-transition> = [ none | <single-transition-property> ] || <time> || <single-transition-timing-function> || <time>
  • transition-property : 定义动画属性,可定义多个属性,逗号分隔
  • transition-duration : 定义动画执行时间,单位(s,ms),可定义多个属性,与transition-property一一对应,逗号分隔
  • transition-timing-function : 与calcMode 类似,影响动画的表现。默认值为ease
  • transition-delay : 定义动画延迟多少时间后开始执行
.rect{
    transition-property:width, height;
    transition-duration:1s, 3s;
    transition-timing-function: ease-in, cubic-bezier(1,0,0,1);
    transition-delay:2s, 0.5s;
}

// 缩写方式
.rect{
  transition: width 1s ease-in 2s, height 3s cubic-bezier(1,0,0,1) 0.5s;
}

animation

<single-animation> = <single-animation-name> || <time> || <single-animation-timing-function> || <time> || <single-animation-iteration-count> || <single-animation-direction> || <single-animation-fill-mode> || <single-animation-play-state>
  • animation-name : 动画名称,对应<animate>attributeName属性,属性值为@keyframes名对应
  • animation-duration : 动画持续时间,对应<animate>dur属性
  • animation-timing-function : 动画过渡类型,对应<animate>calcMode属性,可用三次贝塞尔曲线来设置动画运行的效果
  • animation-iteration-count : 动画循环次数,对应<animate>repeatCount属性。默认为1infinite表示无限重复(不同于repeatCount的indefinte)
  • animation-delay : 动画延迟执行的时间。有点类似<animate>start属性的作用,用start加上一些事件和时间的计算,也可以实现延迟执行动画的效果
  • animation-fill-mode : 动画时间结束的状态,类似<animate>fill属性,但有区别。animation-fill-mode有四个属性值可选:none | forwards | backwards | both
  • animation-play-state : 控制动画的状态,两个属性值 running | paused
  • animation-direction : 控制动画是正向运动,或者反向运动,如果设置了animation-iteration-count重复执行次数,还能控制一次动画执行完毕后,以何种方式执行接下去的一次动画。有四个属性值normal | reverse | alternate | alternate-reverse

🌰 心形路径动画例子:

<svg class="heart" width="90" height="90" viewBox="0 0 90 90">
  <g class="heart-group">
    <path class="heart-heartPath" stroke-width="2" d="M60,30 a30,30 0 0,1 0,60 L0,90 0,30 a30,30 0 0,1 60,0" />
  </g>
</svg>

<style>
.heart {
  margin: 90px;
  overflow: visible;
  
  &-group {
    transform-origin: 0 90px;
    transform: rotate(-45deg);
    animation: group-anim 4s infinite;
  }
  
  &-heartPath {
    stroke: #E21737;
    fill: transparent;
    stroke-dasharray: 308.522, 308.522;
    stroke-dashoffset: 308.522;
    animation: heart-anim 4s infinite;
  }
}
@keyframes group-anim {
  0%, 100% {
    opacity: 0;
  }
  40%, 90% {
    opacity: 1;
  }
}
@keyframes heart-anim {
  15% {
    stroke-dashoffset: 308.522;
    fill: transparent;
  }
  50% {
    stroke-dashoffset: 0;
    fill: transparent;
  }
  70%, 100% {
    stroke-dashoffset: 0;
    fill: #E21737;
  }
}
</style>

@Marinerer Marinerer changed the title SVG基础文档 SVG文档教程 Mar 25, 2021
@Marinerer
Copy link
Owner Author

SVG 参考手册


来源:https://www.w3cschool.cn/svg/svg-reference.html

SVG 元素

元素 说明 属性
创建一个SVG元素周围链接 xlink:show xlink:actuate xlink:href target
允许对象性文字进行控制,来呈现特殊的字符数据 x y dx dy rotate glyphRef format xlink:href
定义一系列象性符号的替换 id
定义一系列候选的象性符号的替换 id
随时间动态改变属性 attributeName="目标属性名称" from="起始值" to="结束值" dur="持续时间" repeatCount="动画时间将发生"
定义随着时间的推移颜色转换 by="相对偏移值" from="起始值" to="结束值"
使元素沿着动作路径移动 calcMode="动画的插补模式。可以是'discrete', 'linear', 'paced', 'spline'" path="运动路径" keyPoints="沿运动路径的对象目前时间应移动多远" rotate="应用旋转变换" xlink:href="一个URI引用元素,它定义运动路径"
动画上一个目标元素变换属性,从而使动画控制平移,缩放,旋转或倾斜 by="相对偏移值" from="起始值" to="结束值" type="类型的转换其值是随时间变化。可以是 'translate', 'scale', 'rotate', 'skewX', 'skewY'"
定义一个圆 cx="圆的x轴坐标" cy="圆的y轴坐标" r="圆的半径". 必需. + 显现属性:颜色,FillStroke,图形
用于隐藏位于剪切路径以外的对象部分。定义绘制什么和什么不绘制的模具被称为剪切路径 clip-path="引用剪贴路径和引用剪贴路径交叉" clipPathUnits="userSpaceOnUse'或'objectBoundingBox"。第二个值childern一个对象的边框,会使用掩码的一小部分单位(默认:"userSpaceOnUse")"
指定颜色配置文件的说明(使用CSS样式文件时) local="本地存储颜色配置文件唯一ID" name="" rendering-intent="auto|perceptual|relative-colorimetric|saturation|absolute-colorimetric" xlink:href="ICC配置文件资源URI"
定义一个独立于平台的自定义光标 x="x轴左上角光标(默认为0)" y="y轴的左上角光标(默认为0)" xlink:href="使用光标图像URI
引用的元素容器
对 SVG 中的元素的纯文本描述 - 并不作为图形的一部分来显示。用户代理会将其显示为工具提示
定义一个椭圆 cx="椭圆x轴坐标" cy="椭圆y轴坐标" rx="沿x轴椭圆形的半径"。必需。 ry="沿y轴长椭圆形的半径"。必需。 + 显现属性:颜色,FillStroke,图形
使用不同的混合模式把两个对象合成在一起 mode="图像混合模式:normal|multiply|screen|darken|lighten" in="标识为给定的滤镜原始输入:SourceGraphic | SourceAlpha | BackgroundImage | BackgroundAlpha | FillPaint | StrokePaint | " in2="第二输入图像的混合操作"
feColorMatrix SVG滤镜。适用矩阵转换
feComponentTransfer SVG 滤镜。执行数据的 component-wise 重映射
feComposite SVG 滤镜
feConvolveMatrix SVG 滤镜
feDiffuseLighting SVG 滤镜
feDisplacementMap SVG 滤镜
feDistantLight SVG滤镜。定义一个光源
feFlood SVG滤镜
feFuncA SVG 滤镜。feComponentTransfer 的子元素
feFuncB SVG 滤镜。feComponentTransfer 的子元素
feFuncG SVG 滤镜。feComponentTransfer 的子元素
feFuncR SVG 滤镜。feComponentTransfer 的子元素
feGaussianBlur SVG滤镜。执行高斯模糊图像
feImage SVG滤镜。
feMerge SVG滤镜。建立在彼此顶部图像层
feMergeNode SVG 滤镜。feMerge的子元素
feMorphology SVG 滤镜。 对源图形执行"fattening" 或者 "thinning"
feOffset SVG滤镜。相对其当前位置移动图像
fePointLight SVG滤镜
feSpecularLighting SVG滤镜
feSpotLight SVG滤镜
feTile SVG滤镜
feTurbulence SVG滤镜
filter 滤镜效果的容器
font 定义字体
font-face 描述一种字体的特点
font-face-format
font-face-name
font-face-src
font-face-uri
foreignObject
用于把相关元素进行组合的容器元素 id="该组的名称" fill="该组填充颜色" opacity="该组不透明度" + 显现属性: All
glyph 为给定的象形符号定义图形
glyphRef 定义要使用的可能的象形符号
hkern
定义图像 x="图像的左上角的x轴坐标" y="图像的左上角的y轴坐标" width="图像的宽度". 必须. height="图像的高度". 必须. xlink:href="图像的路径". 必须. + 显现属性: Color, Graphics, Images, Viewports
定义一条线 x1="直线起始点x坐标" y1="直线起始点y坐标" x2="直线终点x坐标" y2="直线终点y坐标" + 显现属性: Color, FillStroke, Graphics, Markers
定义线性渐变。通过使用矢量线性渐变填充对象,并可以定义为水平,垂直或角渐变。 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"
标记可以放在直线,折线,多边形和路径的顶点。这些元素可以使用marker属性的"marker-start","marker-mid"和"marker-end",继承默认情况下或可设置为"none"或定义的标记的URI。您必须先定义标记,然后才可以通过其URI引用。任何一种形状,可以把标记放在里面。他们绘制元素时把它们附加到顶部 markerUnits="strokeWidth'或'userSpaceOnUse"。如果是strokeWidth"那么使用一个单位等于一个笔划宽度。否则,标记尺度不会使用同一视图单位作为引用元素(默认为'strokeWidth')" refx="标记顶点连接的位置(默认为0)" refy="标记顶点连接的位置(默认为0)" orient="'auto'始终显示标记的角度。 "auto"将计算某个角度使得X轴一个顶点的正切值(默认为0) markerWidth="标记的宽度(默认3)" markerHeight="标记的高度(默认3)" viewBox="各点"看到"这个SVG绘图区域。由空格或逗号分隔的4个值。(min x, min y, width, height)" + presentation attributes: All
度屏蔽是一种不透明度值的组合和裁剪。像裁剪,您可以使用图形,文字或路径定义掩码的部分。一个掩码的默认状态是完全透明的,也就是裁剪平面的对面的。在掩码的图形设置掩码的不透明部分 maskUnits="'userSpaceOnUse' or 'objectBoundingBox'.设定裁剪面是否是相对完整的视窗或对象(默认:'objectBoundingBox')" maskContentUnits="第二个掩码相对对象的图形位置使用百分比'userSpaceOnUse'或'objectBoundingBox'(默认:'userSpaceOnUse')" x="裁剪面掩码(默认值:-10%)" y="裁剪面掩码(默认值:-10%)" width="裁剪面掩码(默认是:120%)" height="裁剪面掩码(默认是:120%)"
metadata 指定元数据
missing-glyph
mpath
定义一个路径 d="定义路径指令" pathLength="如果存在,路径将进行缩放,以便计算各点相当于此值的路径长度" transform="转换列表" + 显现属性: Color, FillStroke, Graphics, Markers
定义坐标,你想要的视图显示和视图的大小。然后添加到您的模式形状。该模式命中时重复视图框的边缘(可视范围) id="用于引用这个模式的唯一ID。"必需的。 patternUnits="userSpaceOnUse'或'objectBoundingBox"。第二个值X,Y,width,height 一个会使用模式对象的边框的小部分,单位(%)。" patternContentUnits="'userSpaceOnUse'或 'objectBoundingBox'" patternTransform="允许整个表达式进行转换" x="模式的偏移量,来自左上角(默认为0)" y="模式的偏移量,来自左上角(默认为0)" width="模式平铺的宽度(默认为100%)" height="模式平铺的高度(默认为100%)" viewBox="各点"看到"这个SVG绘图区域。由空格或逗号分隔的4个值。(min x, min y, width, height)" xlink:href="另一种模式,其属性值是默认值以及任何子类可以继承。递归"
定义一个包含至少三边图形 points="多边形的点。点的总数必须是偶数"。必需的。 fill-rule="FillStroke演示属性的部分" + 显现属性: Color, FillStroke, Graphics, Markers
定义只有直线组成的任意形状 points=折线上的"点"。必需的。 + 显现属性: Color, FillStroke, Graphics, Markers
定义放射性渐变。放射性渐变创建一个圆圈 gradientUnits="'userSpaceOnUse' or 'objectBoundingBox'. 使用视图框或对象以确定相对位置的矢量点。 (默认为'objectBoundingBox)" gradientTransform="适用于渐变的变换" cx="渐变的中心点(数字或% - 50%是默认)" cy="渐变的中心点。 (默认50%)" r="渐变的半径。 (默认50%)" fx="渐变的焦点。 (默认0%)" fy="渐变的焦点。 (默认0%)" spreadMethod="'pad' or 'reflect' or 'repeat'" xlink:href="引用到另一个渐变,其属性值作为默认值。递归"
定义一个矩形 x="矩形的左上角的x轴" y="矩形的左上角的y轴" rx="x轴的半径(round元素)" ry="y轴的半径(round元素)" width="矩形的宽度"。必需的。 height="矩形的高度"。必需的。 + 显现属性: Color, FillStroke, Graphics
script 脚本容器。(例如ECMAScript)
set 设置一个属性值指定时间
渐变停止 offset="偏移停止(0到1/0%到100%)". 参考 stop-color="这个stop的颜色" stop-opacity="这个Stop的不透明度 (0到1)"
style 可使样式表直接嵌入SVG内容内部
创建一个SVG文档片段 x="左上角嵌入(默认为0)" y="左上角嵌入(默认为0)" width="SVG片段的宽度(默认为100%)" height="SVG片段的高度(默认为100%)" viewBox="点"seen"这个SVG绘图区域。由空格或逗号分隔的4个值。 (min x, min y, width, height)" preserveAspectRatio="'none'或任何'xVALYVAL'的9种组合,VAL是"min","mid"或"max"。(默认情况下none)" zoomAndPan="'magnify' or 'disable'.Magnify选项允许用户平移和缩放您的文件(默认Magnify )" xml="最外层元素都需要安装SVG和它的命名空间: xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"" + 显现属性: All
switch
symbol
定义一个文本 x="列表的X -轴的位置。在文本中在第n个字符的位置在第n个x轴。如果后面存在额外的字符,耗尽他们最后一个字符之后放置的位置。 0是默认" y="列表的Y轴位置。(参考x)0是默认" dx="在字符的长度列表中移动相对最后绘制标志符号的绝对位置。(参考x)" dy="在字符的长度列表中移动相对最后绘制标志符号的绝对位置。(参考x)" rotate="一个旋转的列表。第n个旋转是第n个字符。附加字符没有给出最后的旋转值" textLength="SVG查看器将尝试显示文本之间的间距/或字形调整的文本目标长度。(默认:正常文本的长度)" lengthAdjust="告诉查看器,如果指定长度就尝试进行调整用以呈现文本。这两个值是'spacing'和'spacingAndGlyphs'" + 显现属性: Color, FillStroke, Graphics, FontSpecification, TextContentElements
textPath
title 对 SVG 中的元素的纯文本描述 - 并不作为图形的一部分来显示。用户代理会将其显示为工具提示
引用任何SVG文档中的元素和重用 相同的元素
元素等同于,但可以在内部嵌套文本标记以及内部本身 Identical to the element + in addition: xlink:href="引用一个元素"
使用URI引用一个,或其他具有一个唯一的ID属性和重复的图形元素。复制的是原始的元素,因此文件中的原始存在只是一个参考。原始影响到所有副本的任何改变。 x="克隆元素的左上角的x轴" y="克隆元素的左上角的y轴" width="克隆元素的宽度" height="克隆元素的高度" xlink:href="URI引用克隆元素" + 显现属性: All
view
vkern

@Marinerer
Copy link
Owner Author

Marinerer commented Aug 20, 2021

svgo - SVG精简压缩工具

svgo 是什么?

svgo 是一个用于优化SVG文件的Node.js工具。

svgo-github

为什么要用svgo?

因为我们从网上下载或者导出的SVG文件中包含着大量无用的信息,例如编辑源信息,注释以及其它一些不会影响渲染效果但可以去除的信息,这时候可以通过svgo插件,将这些无用的信息进行去除,从而达到优化的效果。该svgo具有基于插件的体系结构,因此几乎每个优化都是一个单独的插件。

svgo 怎么使用?

  1. 安装
npm install svgo --save-dev
  1. 配置

⚠️ 注意:[email protected] 版本已不再支持 yml 配置文件方式了,仅支持 js 配置方式。

创建 src/svgo.config.js文件

详细参见:https://github.com/svg/svgo/blob/master/README.md#configuration

module.exports = {
  multipass: true, // boolean. false by default
  datauri: 'enc', // 'base64', 'enc' or 'unenc'. 'base64' by default
  js2svg: {
    indent: 2, // string with spaces or number of spaces. 4 by default
    pretty: true, // boolean, false by default
  },
  plugins: [
    // enable a built-in plugin by name
    'builtinPluginName',
    // or by expanded version
    {
      name: 'builtinPluginName',
    },
    // some plugins allow/require to pass options
    {
      name: 'builtinPluginName',
      params: {
        optionName: 'optionValue',
      },
    },
  ]
};
  1. 在package.json文件中配置检测svg的命令
{
	"svgo": "svgo -f src/icons/svg --config=src/svgo.config.js" 
}

-f src/icons/svg 中的 -f 表示指定文件夹src/icons/svg中以.svg结尾的文件;
-–config=src/svgo.config.js 表定用于扩展或者替换默认值的配置文件;

内置插件列表

SVGO基于插件模式构建,基本上所有的优化都是一个分离的插件。

Plugin Description Default
cleanupAttrs 清除换行,结束符以及重复空格 enabled
mergeStyles 将多个样式元素合二为一 enabled
inlineStyles 将样式从 <style> 元素移动并合并到元素 style 属性 enabled
removeDoctype 删除doctype声明 enabled
removeXMLProcInst remove XML processing instructions enabled
removeComments 移除 XML 处理指令 enabled
removeMetadata remove <metadata> enabled
removeTitle remove <title> enabled
removeDesc remove <desc> enabled
removeUselessDefs remove elements of <defs> without id enabled
removeXMLNS removes the xmlns attribute (for inline SVG) disabled
removeEditorsNSData remove editors namespaces, elements, and attributes enabled
removeEmptyAttrs remove empty attributes enabled
removeHiddenElems remove hidden elements enabled
removeEmptyText remove empty Text elements enabled
removeEmptyContainers remove empty Container elements enabled
removeViewBox 尽可能删除 viewBox 属性 enabled
cleanupEnableBackground 尽可能删除或清理 enable-background 属性 enabled
minifyStyles minify <style> elements content with CSSO enabled
convertStyleToAttrs convert styles into attributes disabled
convertColors convert colors (from rgb() to #rrggbb, from #rrggbb to #rgb) enabled
convertPathData 将路径数据转换为的相对路径和绝对路径中简短的那一个,过滤无用的分隔符,智能四舍五入以及其他很多处理 enabled
convertTransform 将多个变换折叠为一个,将矩阵转换为短别名等 enabled
removeUnknownsAndDefaults 移除未知元素内容和属性,移除具有默认值的属性 enabled
removeNonInheritableGroupAttrs 删除不可继承组的presentation属性 enabled
removeUselessStrokeAndFill remove useless stroke and fill attributes enabled
removeUnusedNS 删除未使用的命名空间声明 enabled
prefixIds 使用 SVG 文件名或任意字符串前缀 ID 和类 disabled
cleanupIDs remove unused and minify used IDs enabled
cleanupNumericValues 数值四舍五入提高精度, 删除默认的px单位 enabled
cleanupListOfValues 取数字列表的属性中的舍入数值(如viewBoxenable-background disabled
moveElemsAttrsToGroup 将元素的属性移动到它们的封闭组 enabled
moveGroupAttrsToElems 将一些组属性移动到包含的元素 enabled
collapseGroups collapse useless groups enabled
removeRasterImages 移除光栅图像 disabled
mergePaths 将多个路径合并为一个 enabled
convertShapeToPath 将一些基本形状转换为 <path> enabled
convertEllipseToCircle 将非偏心 <ellipse> 转换为 <circle> enabled
sortAttrs 排序元素属性以获得史诗般的可读性 disabled
sortDefsChildren <defs> 的子项进行排序以提高压缩率 enabled
removeDimensions 删除 width/height 并添加 viewBox 如果它丢失(与 removeViewBox 相反,先禁用它) disabled
removeAttrs 按模式删除属性 disabled
removeAttributesBySelector 删除与 CSS 选择器匹配的元素的属性 disabled
removeElementsByAttr 通过 IDclassName 删除任意元素 disabled
addClassesToSVGElement 将类名添加到外部 <svg> 元素 disabled
addAttributesToSVGElement 向外部 <svg> 元素添加属性 disabled
removeOffCanvasPaths 删除在视图框之外绘制的元素 disabled
removeStyleElement remove <style> elements disabled
removeScriptElement remove <script> elements disabled
reusePaths 查找重复元素并用链接替换它们 disabled

svgo命令

svgo [OPTIONS] [ARGS]

Options:
  -h, --help : Help 帮助
  -v, --version : Version版本
  -i INPUT, --input=INPUT : 输入的文件, "-" 为标准输入
  -s STRING, --string=STRING : 输入SVG数据字符串
  -f FOLDER, --folder=FOLDER : 输入的文件夹,会优化与重写所有的*.svg文件
  -o OUTPUT, --output=OUTPUT : 输入的文件或文件夹 (默认同输入), "-" 标准输出
  -p PRECISION, --precision=PRECISION : 设置数字的小数部分,重写插件参数
  --config=CONFIG : 配置文件扩展或替换默认设置
  --disable=DISABLE : 根据名字禁用插件
  --enable=ENABLE : 根据名字开启插件
  --datauri=DATAURI : 输入文件以Data URI字符串形式(base64, URI encoded or unencoded)
  -q, --quiet : 仅输出错误信息,不包括正常状态消息
  --pretty : 让SVG漂亮的打印
  --show-plugins : 显示可用和存在的插件

Arguments:
  INPUT : 别名 --input
  OUTPUT : 别名 --output

refs

@Marinerer Marinerer changed the title SVG文档教程 SVG教程 Nov 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant