SVG从零基础到完全掌握

前言

首先,毫无疑问,这是一份非常完善且简洁的SVG学习教程

它包含了SVG所有的核心内容,而且有说明和示例

对于更复杂的细节,最后附有官方文档,我们一般也用不上

SVG版本说明

SVG1.1包含了SVG所有的基本用法

SVG2.0扩充了更多的动态编程属性

相对而言,SVG2.0的扩展部分,是比SVG1.1基础部分要复杂的

不过我们一般也不用手动去编写SVG脚本,会有专业编辑器帮我们去生成

SVG语法说明

这里我们不再区分哪个标签是1.1版本的,哪个标签是2.0版本的

因为现在的SVG渲染引擎,几乎都支持2.0版本语法,没必要刻意去区分

SVG根标签
<svg xmlns="http://www.w3.org/2000/svg" version="2.0" width="600" height="600">
</svg>

这里通过width和height来指定SVG整个图片的宽高

对于子标签,还能使用百分比作为元素宽高

viewport属性

通过宽高来指定图片尺寸,图片左上角坐标为[0, 0],右下角坐标为[width, height]

如果不想以[0, 0]作为左上角的坐标,可以通过viewBox来定义图片坐标范围

viewBox包含四个参数,分别是左上角坐标,和图片宽高

<svg xmlns="http://www.w3.org/2000/svg" version="2.0" viewBox="-600 -600 1200 1200">
</svg>
基本图形元素
  • 矩形,rect
  • 圆形,circle
  • 椭圆,ellipse
  • 直线,line
  • 多边形,polygon
  • 多段线,polyline
  • 路径,path,最强大最核心的元素,下面会单独讲解
  • 分组,g,将多个元素包含到一个容器元素里面,以便对多个元素进行整体操作,或提升可读性
<svg xmlns="http://www.w3.org/2000/svg" version="2.0" viewBox="-600 -600 1200 1200">
    <rect width="50%" height="50%" fill="#EEEE0022"/>
    <circle cx="100" cy="100" r="50" fill="blue" stroke="black" stroke-width="2" />
</svg>
通用属性
  • id,元素id,用于元素间关联,或提升可读性

  • width/height,元素宽高

  • x/y,起始坐标,不指定时默认为0

  • cx/cy,中心坐标

  • r,半径

  • rx/ry,圆角半径或椭圆半径

  • fill/stroke/stroke-width,填充色,描边色,描边宽度

  • x1/x2/y1/y2,两个点的坐标

  • points,多个点的坐标,格式为points=“x1,y1 x2,y2 x3,y3”

  • d,指定路径数据,参考格式如d=“M x1 y1 L x2 y2 … Z”

  • 不少size属性都可以使用百分比来表示

  • 有的百分比相对于图片大小,有的相对于自身大小,可以自己去尝试下效果

  • stroke-dasharray,虚线长度数组,数组可为任意长度,首个数值为实线长度,下个数值为虚线,依此循环

  • stroke-dashoffset,虚线数组偏移一定距离,从指定位置offset开始显示

SVG路径

SVG通过定义一系列运动指令,来绘制任意的自定义路径

  • M,移动到指定点,但不绘制移动路径
  • L,画一条直线到指定点,指定终点坐标
  • H,画一条水平线到指定点,指定x即可
  • V,画一条垂直线到指定点,指定y即可
  • C,画一条三次贝塞尔曲线到指定点,指定两个控制点坐标,和终点坐标
  • S,画一条对称三次贝塞尔曲线到指定点,只需指定一个控制点,会自动使用对称点作为另一个控制点
  • Q,画一条二次贝塞尔曲线到指定点,指定控制点坐标,和终点坐标
  • T,画一条对称二次贝塞尔曲线到指定点,指定终点坐标即可
  • T一般接在Q或T后面使用,会自动推断控制点,来画一条和前段曲线对称的下一段曲线
  • T单独使用时,将会以终点作为控制点,画出的是直线
  • Z,闭合路径,画一条连接当前点与起点的路径
  • 重复指令,当一个指令需要执行多次,但坐标不同时,可以省略重复指令,直接指定多组坐标即可
  • 相对位置,以上指令符大写时,表示绝对坐标,如果用小写,则表示相对于当前位置的相对坐标
  • A,以当前位置为起点,画一条到终点的弧形
  • 弧形指令需要的参数比较多,下一节我们专门来讲解
<svg xmlns="http://www.w3.org/2000/svg" version="2.0" viewBox="0 0 600 600">
    <path id="AB" d="M 100 350 l 150 -300" stroke="red" stroke-width="3" fill="none"/>
    <path id="BC" d="M 250 50 l 150 300" stroke="red" stroke-width="3" fill="none"/>
    <path id="Curve" d="M 100 350 q 150 -300 300 0" stroke="blue" stroke-width="5" fill="none"/>
</svg>
Arc指令参数
  • 弧形半径rx/ry
  • 短轴方向x-axis-rotation,度数为单位
  • 取短弧还是长弧,large-arc-flag,1表示取长弧,0表示取短弧
  • 顺时针方向还是逆时针方向,sweep-flag,1表示顺时针到终点,0表示逆时针到终点
  • 终点坐标x/y
  • 给定起点和终点,给点弧长,给定中心轴方向,可能的弧形有四种,正好对应large-arc-flag和sweep-flag的四种组合
  • 可以通过以下模拟代码,来熟悉其使用效果
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
    <rect width="100%" height="100%" fill="#FFFF0011"/>
    <path d="M 75 75 A 50 50 0 0 0 125 125" fill="transparent" stroke="red" stroke-width="2"/>
    <path d="M 75 75 A 50 50 0 0 1 125 125" fill="transparent" stroke="green" stroke-width="2"/>
    <path d="M 75 75 A 50 50 0 1 1 125 125" fill="transparent" stroke="blue" stroke-width="2"/>
    <path d="M 75 75 A 50 50 0 1 0 125 125" fill="transparent" stroke="purple" stroke-width="2"/>
    <path d="M 75 75 L 125 125" fill="transparent" stroke="black" stroke-width="2" stroke-dasharray="1 3" stroke-dashoffset="1"/>
</svg>
文字

文字通过text标签创建,主要参数为

  • x/y,位置

  • font-size,字体大小

  • font-family,字体

  • text-anchor,文字相当于给定位置的对齐方式

<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
    <text x="100" y="100" font-family="Arial" font-size="20" fill="blue" text-anchor="middle">Hello, SVG!</text>
</svg>
图像

SVG可以通过image标签来嵌入图像

<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="400">
    <image href="https://img-home.csdnimg.cn/images/20230308042836.png"/>
</svg>
图案

SVG通过pattern标签来定义一个图案

图案可以由多个子元素组合而成,并且可以按一定方式重复显示,作为其它元素的填充材料

<svg width="200" height="200"
     xmlns="http://www.w3.org/2000/svg">
    <linearGradient id="Gradient1">
        <stop offset="5%" stop-color="white"/>
        <stop offset="95%" stop-color="blue"/>
    </linearGradient>
    <linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1">
        <stop offset="5%" stop-color="red"/>
        <stop offset="95%" stop-color="orange"/>
    </linearGradient>
    <pattern id="Pattern"
             x="0" y="0" width=".25" height=".25"
             patternUnits="objectBoundingBox">
        <rect x="0" y="0" width="50" height="50" fill="skyblue"/>
        <rect x="0" y="0" width="25" height="25" fill="url(#Gradient2)"/>
        <circle cx="25" cy="25" r="20"
                fill="url(#Gradient1)"
                fill-opacity="0.5"/>
    </pattern>
    <rect x="0" y="0" width="200" height="200"
          fill="url(#Pattern)" stroke="black"/>
</svg>
高级标签

以上是SVG的核心内容,到此为止,我们基本已经知道SVG是怎样一种使用方式

下面我们通过实例的方式,来演示高级标签的使用方法

并且,我将不再讲述具体参数的含义

从属性单词和运行效果,很容易知道参数的实际含义,没必要像背书一样去讲解

线性渐变
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
    <linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="0%">
        <stop offset="0%" stop-color="red"/>
        <stop offset="100%" stop-color="blue"/>
    </linearGradient>
    <rect x="50" y="50" width="100" height="80" fill="url(#gradient)"/>
</svg>
放射渐变
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
    <radialGradient id="gradient" cx="50%" cy="50%" r="50%" fx="100%" fy="50%">
        <stop offset="0%" stop-color="red"/>
        <stop offset="100%" stop-color="blue"/>
    </radialGradient>
    <circle cx="100" cy="100" r="80" fill="url(#gradient)"/>
</svg>
裁剪效果

SVG允许通过clipPath标签,来定义一个显示范围裁剪效果

默认显示范围,为clipPath下所有元素范围的总和

<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400">
    <rect x="0" y="0" width="200" height="200" fill="#FFFF0011"/>
    <clipPath id="clip">
        <circle cx="100" cy="50" r="50"/>
        <rect x="0" y="0" width="100" height="100"/>
    </clipPath>
    <circle cx="100" cy="100" r="100" fill="#00FFFF33" clip-path="url(#clip)"/>
</svg>
遮罩效果

SVG允许通过mask标签,来定义一个半透明的图层,叠加在当前元素上面

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
    <linearGradient id="gradient">
        <stop offset="0%" stop-color="white" stop-opacity="50%"/>
        <stop offset="100%" stop-color="white" stop-opacity="80%"/>
    </linearGradient>
    <mask id="mask">
        <rect x="0" y="0" width="200" height="200" fill="url(#gradient)"/>
    </mask>
    <rect x="0" y="0" width="200" height="200" fill="red" mask="url(#mask)"/>
</svg>
滤镜效果

SVG提供了以下滤镜效果

  • 阴影效果,Shadow
  • 模糊效果,Blur
  • 亮度调整,Brightness
  • 对比度调整,Contrast
  • 颜色变换,Color Matrix
  • 图像混合,Blend Mode
阴影效果
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
    <filter id="shadow_filter">
        <feDropShadow dx="2" dy="2" stdDeviation="3" flood-color="gray" flood-opacity="0.9"/>
    </filter>
    <rect x="50" y="50" width="100" height="80" fill="red" filter="url(#shadow_filter)"/>
</svg>
模糊效果
<svg width="400" height="400" xmlns="http://www.w3.org/2000/svg">
    <filter id="blur_filter">
        <feGaussianBlur in="SourceGraphic" stdDeviation="5 5"/>
    </filter>
    <rect x="100" y="100" width="200" height="200" fill="red" filter="url(#blur_filter)"/>
</svg>
坐标转换

SVG提供了transform属性,用于对元素进行转换,包括以下方式

  • 平移变换,translate,需提供dx/dy两个参数
  • 旋转变化,rotate,需提供degree/cx/cy三个参数
  • 缩放变换,scale,需提供sx/sy两个参数,注意,scale是针对整个画布的,x/y也会被一起缩放
  • 斜切变换,skewX,skewY,需提供一个degree参数,skew也是针对整个画布的,x/y也会被一起缩放
  • 矩阵变换,通过一个2×3的矩阵,对初始坐标进行转换
  • 矩阵转换公式为
  • newX = ax + cy + e
  • newY = bx + dy + f
<svg xmlns="http://www.w3.org/2000/svg" version="2.0" width="300" height="100">
    <rect width="100%" height="100%" fill="#FFFF0011"/>
    <rect x="25" y="25" width="50" height="50" fill="#003333AA"
          transform="scale(1.2,0.8) rotate(20,50,50) translate(30,0) skewX(10) skewY(10)"/>
</svg>
矩阵变换

矩阵变换需要提供六个参数,分别代表

  • a,scaleX
  • b,skewY
  • c,skewX
  • d,scaleY
  • e,translateX
  • f,translateY
  • 注意,这里的skew不再是斜切度数,而是最终的坐标转换系数
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
    <rect
        width="100%"
        height="100%"
        fill="#FFFF0011"/>
    <rect
        x="10"
        y="10"
        width="30"
        height="20"
        fill="#FF00FF22"/>
    <rect
        x="10"
        y="10"
        width="30"
        height="20"
        fill="#00FFFF22"
        transform="matrix(3 1 1 3 30 40)"/>
</svg>
定义可复用对象

defs标签,可以包含若干元素,这些元素可以被其它地方引用或复用

defs标签下的元素,在被复用前,都不会被展示

复用通过use标签来实现,引用通过#来连接其id

<svg width="100" height="100"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">
    <defs>
        <circle id="C" r="10"/>
        <filter id="BF">
            <feGaussianBlur in="SourceGraphic" stdDeviation="1 1"/>
        </filter>
    </defs>
    <style>
        #C1 { fill:red }
        #C2 { fill:green }
        #C3 { fill:blue; filter:url(#BF) }
    </style>
    <use id="C1" x="50" y="20" xlink:href="#C"/>
    <use id="C2" x="50" y="50" xlink:href="#C" filter="url(#BF)"/>
    <use id="C3" x="50" y="80" xlink:href="#C"/>
</svg>
动画

SVG允许通过animate标签,来为指定属性添加动画

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
    <rect width="100%" height="100%" fill="#FF00FF11">
        <animate
            attributeName="rx"
            values="30%;50%;30%"
            dur="3s"
            repeatCount="indefinite"/>
    </rect>
</svg>
CSS样式

在SVG中,也可以像HTML一样,通过style标签,或style属性,来设置元素样式

上面的代码已经使用到了该特性

Script脚本

类似于对CSS的支持,SVG也支持Script脚本,并且可以通过onclick等属性调用脚本函数

<svg xmlns='http://www.w3.org/2000/svg' width="200" height="200">
    <script type="text/ecmascript">
        function reshape(event) {
            var element=event.target
            var rx = element.getAttribute ("rx")
            if(rx=="50%"){
                element.setAttribute ("rx", "0%")
            }else{
                element.setAttribute ("rx", "50%")
            }
        }
    </script>
    <rect onclick="reshape(evt)" width="100%" height="100%" fill="#FF00FF11"/>
</svg>
参考文档

https://www.w3.org/TR/SVG

https://www.w3.org/TR/SVG/coords.html

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

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值