1

SVG

总结的 svg 知识,方便以后复习查看 ~ ~

SVG是什么

SVG 表示可缩放矢量图
SVG 用来定义WEB上使用的矢量图
SVG 用XML格式定义矢量图
SVG 在缩放时不会损失任何的图片质量
SVG 文件里的所有元素和属性都可以运用动画效果
SVG 是W3C推荐的
SVG 集成了其它W3C标准,比如 DOM 和 XSL
// 先来一个简单的例子
 <svg width="100" height="100">
    <circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="red"></circle>
</svg>
1. SVG图片用<svg>标记定义
2. <svg>元素里提供了`“width”`和`“height”`两个属性来定义SVG图片的高度和宽度
3. <circle>元素的功能是画出一个圆
4. cx和cy两个属性分别定义了圆心的x坐标和y坐标。如果没有提供cx和cy的值,那么,缺省圆心是(0, 0)
5. r属性定义了圆的半径长度
6. stroke和stroke-width两个属性用来定义图像的边框样子。上面例子中定义圆的边框颜色为green,边框粗细为4px
7. fill属性定义了圆内部填充的颜色。我们可以看出,例子中填充了黄色

SVG形状

矩形 <rect>
圆形 <circle>
椭圆 <ellipse>
直线 <line>
折线 <polyline>
多边形 <polygon>
路径 <path>

一、rect 矩形

<svg width="500" height="500">
    <rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:4;stroke:rgb(0,0,0)" />
</svg>

clipboard.png

style属性定义了这个矩形的CSS属性。
style属性里的fill属性定义了这个矩形填充的颜色
style属性里的stroke-width属性定义了矩形边线的宽度
style属性里的stroke属性定义了矩形的边线的颜色

<svg x="50" y="50" width="500" height="500">
    <rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:4;stroke:rgb(0,0,0);stroke-opacity=0.9;fill-opacity=0.9;opacity=0.9" />
</svg>

clipboard.png

x属性定义矩形距离左边的距离,比如,x="50"相对于CSS里的 margin-left: 50px
y属性定义了矩形距离上边的距离,比如y="20"相当于CSS里的 margin-top: 20px
CSS fill-opacity属性定义了填充颜色的透明度,值范围为 0 到 1
CSS stroke-opacity属性定义了边线颜色的透明度,值范围为 0 到 1
CSS opacity属性定义了整个图形元素的透明度

<svg width="400" height="180">
    <rect x="50" y="20" rx="20" ry="20" width="150" height="150" style="fill:red;stroke:black;stroke-width:5;opacity:0.5" />
</svg>

clipboard.png

rxry定义了矩形四个角的圆角效果


二、circle 圆形

<svg height="100" width="100">
    <circle cx="50" cy="50" r="40" stroke="black"
    stroke-width="3" fill="red" />
</svg>

clipboard.png

cxcy属性是用来定义圆心的坐标。如果没有提供cx和cy的值,则缺省圆心是(0,0)
r属性定义了圆的半径长度


三、ellipse 椭圆

<svg height="140" width="500">
  <ellipse cx="200" cy="80" rx="100" ry="50"
  style="fill:yellow;stroke:purple;stroke-width:2" />
</svg>

clipboard.png

cx属性定义了椭圆的x坐标
cy属性定义了椭圆的y坐标
rx属性定义了椭圆的横向半径
ry属性定义了椭圆的纵向半径

<svg height="150" width="500">
 
<ellipse cx="240" cy="100" rx="220" ry="30"
style="fill:purple" />
 
<ellipse cx="220" cy="70" rx="190" ry="20"
style="fill:lime" />
 
<ellipse cx="210" cy="45" rx="170" ry="15"
style="fill:yellow" />
</svg>

clipboard.png

<svg height="100" width="500">
 
<ellipse cx="240" cy="50" rx="220" ry="30"
style="fill:yellow" />
 
<ellipse cx="220" cy="50" rx="190" ry="20"
style="fill:white" />
</svg>

clipboard.png


四、line 直线

<svg height="210" width="500">
    <line x1="0" y1="0" x2="200" y2="200"
    style="stroke:rgb(255,0,0);stroke-width:2" />
</svg>

clipboard.png

x1属性定义了直线的x轴起始坐标
y1属性定义了直线的y轴起始坐标
x2属性定义了直线的x轴终止坐标
y2属性定义了直线的y轴终止坐标


五、polyline 折线

<svg height="200" width="500">
    <polyline points="20,20 40,25 60,40 80,120 120,140 200,180"
      style="fill:none;stroke:black;stroke-width:3" />
</svg>

clipboard.png

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

clipboard.png

points属性里定义了各个点的坐标,x和y坐标之间用逗号分别,多个坐标之间用空格分割

五、polygon 多边形

<svg height="210" width="500">
 
<polygon points="200,10 250,190 160,210"
style="fill:lime;stroke:purple;stroke-width:1" />
</svg>

clipboard.png

points属性里定义了多边形各个角的x和y坐标,多个坐标间用空格分隔

<svg height="210" width="500">
  <polygon points="100,10 40,198 190,78 10,78 160,198"
 
style="fill:lime;stroke:purple;stroke-width:5;fill-rule:nonzero;" />
</svg>

clipboard.png

fill-rule属性的取值可以是nonzero | evenodd | inherit

  • 使用fill-rule: evenodd属性:

clipboard.png

六、path 路径

clipboard.png

// 从点 150,0 开始,连直线到点 75,200,然后连直线到点 225,200,最后闭合这个路径,连直线回到点 150,0:
<svg height="210" width="400">
  <path d="M150 0 L75 200 L225 200 Z" />
</svg>

clipboard.png

`贝塞尔曲线`是一种非常顺滑的曲线。通常,用户需要提供两个端点和一个或两个控制点。使用一个控制点的贝塞尔曲线叫做`二次方贝塞尔曲线`,使用两个控制点的贝塞尔曲线叫做`三次方贝塞尔曲线`。

下面的例子里使用了二次方贝塞尔曲线,其中 A 和 C 分别是两个端点,B是控制点:
<svg height="400" width="450">
      <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>
    </svg>

clipboard.png

是不是很复杂呢,确实是,所以一般复杂的过程都需要SVG编辑器来编辑


七、text 文本

<svg height="30" width="200">
 
<text x="0" y="15" fill="red">SVG是个好东西!</text>
</svg>

clipboard.png

<svg height="60" width="200">
 
<text x="0" y="15" fill="red" 
transform="rotate(30 20,40)">SVG是个好东西!</text>
</svg>

transform 可以进行变换

clipboard.png

// 在<text>元素里,我们可以使用<tspan>元素给文字分组,每个<tspan>元素可以定义自己的格式/样式/位置。
<svg height="90" width="200">
  <text x="10" y="20" style="fill:red;">这里有几行文字:
    <tspan x="10" y="45">这是第一行文字。</tspan>
    <tspan x="10" y="70">第二行文字在这里。</tspan>
  </text>
</svg>

clipboard.png

// 还可以插入链接
<svg height="30" width="200">
    <a xlink:href="http://know.webhek.com/svg/" target="_blank">
        <text x="0" y="15" fill="red">SVG是个好东西!</text>
    </a>
</svg>

SVG重点属性

一、 SVG边线边框属性

SVG stroke 属性

这个stroke属性用来定义图形、文本等的边线颜色:

SVG stroke-width 属性

stroke-width属性用来定义图形或文字边线的宽度:

SVG stroke-linecap 属性

stroke-linecap属性用来定义开放式路径的端点的样子:

<svg height="80" width="300">
  <g fill="none" stroke="black" stroke-width="20">
    <path stroke-linecap="butt" d="M5 20 l215 0" />
    <path stroke-linecap="round" d="M5 40 l215 0" />
    <path stroke-linecap="square" d="M5 60 l215 0" />
  </g>
</svg>

clipboard.png

SVG stroke-dasharray 属性

stroke-dasharray属性用来定义开放式路径的端点的样子:

<svg height="80" width="300">
  <g fill="none" stroke="black" stroke-width="4">
    <path stroke-dasharray="5,5" d="M5 20 l215 0" />
    <path stroke-dasharray="10,10" d="M5 40 l215 0" />
    <path stroke-dasharray="20,10,5,5,5,10" d="M5 60 l215 0" />
  </g>
</svg>

二、 SVG的viewBox和preserveAspectRatio属性

请参考下面的手册~

viewBox和preserveAspectRatio属性


SVG结构元素

use 克隆

<svg width="100%" height="300">
    <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>

clipboard.png

<use>标记的作用是能从SVG文档内部取出一个节点,克隆它,并把它输出到别处。跟‘引用’很相似,但它是深度克隆。

symbol 图像模板

<!-- 
    这个<symbol>标记的作用是定义一个图像模板,你可以使用<use>标记实例化它,
    然后在SVG文档中反复使用,这种用法非常的高效。
    <symbol>本身不会输出任何图像,只有使用<use>实例化后才会显示。
 -->
<svg  height='300'>
    <!-- symbol definition  NEVER draw -->
    <symbol id="sym01" viewBox="0 0 150 110">
        <circle cx="50" cy="50" r="40" stroke-width="8" stroke="red" fill="red" />
        <circle cx="90" cy="60" r="40" stroke-width="8" stroke="green" fill="white" />
    </symbol>

    <!-- actual drawing by "use" element -->
    <use xlink:href="#sym01" x="0" y="0" width="100" height="50" />
    <use xlink:href="#sym01" x="0" y="50" width="75" height="38" />
    <use xlink:href="#sym01" x="0" y="100" width="50" height="25" />
</svg>

clipboard.png

g 分组 + 继承父级

<g>标记就是‘group’的简写,是用来分组用的,它能把多个元素放在一组里,对<g>标记实施的样式和渲染会作用到这个分组内的所有元素上。组内的所有元素都会继承<g>标记上的所有属性。用<g>定义的分组还可以使用<use>进行复制使用。

<svg>
    <g stroke="green" fill="white" stroke-width="5">
        <circle cx="25" cy="25" r="15" />
        <circle cx="40" cy="25" r="15" />
        <circle cx="55" cy="25" r="15" />
        <circle cx="70" cy="25" r="15" />
    </g>
</svg>

clipboard.png


SVG文字文本

SVG文字文本参考


SVG 滤镜和渐变

SVG 滤镜和渐变参考


参考文献

WEB学习手册 KNOW


实例

  • 圆形进度条
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        circle{
            stroke-width: 5px;
            transform-origin: center;
        }
        .background{
            /* 缩小一点可以放进容器 */
            transform: scale(0.9);
            stroke: green;
        }
        .bar{
            /* 缩小 + 逆时针旋转 90度 */
            transform: scale(0.9) rotate(-90deg);
            stroke: red;
        }        
    </style>
</head>
<body>
    <!-- 整个 svg 图的大小为 32 * 32 -->
    <!-- 设置viewBox
         这里的 100 * 100是根据下面圆的大小来定的
         目的是让其占满容器
    -->
    <svg width="32" height="32" viewBox="0 0 100 100">
        <!-- 底层 -->
        <circle class="background" cx="50" cy="50" r="50" fill="transparent" />
        <!-- transparent 目的是让其内部变为透明 -->
        <!-- 顶层 -->
        <circle class="bar" cx="50" cy="50" r="50" fill="transparent" stroke-dasharray="314" stroke-dashoffset="220" />
        <!-- 
            stroke-dasharray="314" 是一圈的长度
            stroke-dashoffset="220" 可以设置其周长 220 = 314 -95 ==> 效果是顺时针转过 95 的长度
        -->
    </svg>
</body>
</html>

clipboard.png


Meils
1.6k 声望157 粉丝

前端开发实践者