SVG

0x01 概述

  • SVG(Scalable Vector Graphics,可缩放矢量图)是一种基于 XML 语法的图像格式

    • 一般的图片基于像素处理,放大后会失真,而 SVG 是基于对图像的形状描述,放大后不会失真

    • 本质上是体积较小的文本文件,比如:

      • SVG 文件

        <svg
          class="icon"
          style="
            width: 1em;
            height: 1em;
            vertical-align: middle;
            fill: currentColor;
            overflow: hidden;
          "
          viewBox="0 0 1024 1024"
          xmlns="http://www.w3.org/2000/svg"
        >
          <path
            d="M574.856 64c-247 0-447 200.6-447 448s200 448 447 448c121.2 0 231-48.4 311.6-126.8 10-9.8 12.6-25 6.2-37.4s-20.2-19.4-34-17c-19.6 3.4-39.6 5.2-60.2 5.2-193.8 0-351-157.6-351-352 0-131.6 72-246.2 178.6-306.6 12.2-7 18.4-21 15.4-34.6s-14.6-23.8-28.6-25c-12.6-1-25.2-1.6-38-1.6z"
          ></path>
        </svg>
        
      • SVG 图像预览

  • SVG 标签是 SVG 图形的一个容器:<svg></svg>

    • 可以理解为画布

    • 具有两个重要属性

      1. width:画布宽度
      2. height:画布高度
      <svg width="800" height="600">
          <!-- 编辑区 -->
      </svg>
      

可以通过在 HTML 页面中编辑和预览 SVG 图像:

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <title>SVG</title>
</head>

<body>
  <svg width="800" height="600">
    <!-- 编辑区 -->
  </svg>
</body>

</html>

0x02 形状

  • SVG 有一些预定义的形状元素:

    元素 描述
    line 线条
    polyline 折线(多线条)
    rect (圆角)矩形
    circle 圆形
    ellipse 椭圆形
    polygon 多边形
    path 路径
  • 画布的定位是基于二维坐标系

    • 坐标原点位于左上角
    • 从原点开始,向右为 \(x\) 轴正反向,向下为 \(y\) 轴正方向
    • 此坐标系称为“屏幕坐标系”,与“数学坐标系”不同
  • 标签 <g></g> 可以为形状成组(group)定义属性

(1)线条

  • 标签:<line />

  • 属性:

    • x1\(x\) 轴上的起点坐标
    • y1\(y\) 轴上的起点坐标
    • x2\(x\) 轴上的终点坐标
    • y2\(y\) 轴上的终点坐标
    • opacity:不透明度,取值范围 0 到 1,值越小越透明
    • stroke:笔画(详细使用方法在 0x04 描边 说明)
  • 举例:

    <svg width="100" height="60">
      <g
        stroke="red"
        stroke-width="4"
      >
        <line
          x1="0"
          y1="30"
          x2="100"
          y2="10"
          opacity="0.25"
        />
        <line
          x1="0"
          y1="30"
          x2="100"
          y2="30"
          opacity="0.5"
        />
        <line
          x1="0"
          y1="30"
          x2="100"
          y2="50"
          opacity="0.75"
        />
       </g>
     </svg>
    

(2)折线(多线条)

  • 标签:<polyline />

  • 属性:points:点集,定义折现每个转折点的 \((x,\ y)\) 坐标

    • 每一对坐标的 \(x\)\(y\) 使用 , 隔开
    • 坐标之间使用空格隔开
    • 坐标顺序为绘制线条连接的顺序,最后一个坐标连接第一个坐标
  • 举例:

    <svg width="100" height="75">
      <polyline
        points="0,25 25,25 25,50 50,50 50,25 75,25 75,50 100,50"
        fill="none"
        stroke="red"
        stroke-width="4"
      />
    </svg>
    

(3)(圆角)矩形

  • 标签:<rect />

  • 属性:

    • width:矩形宽度
    • height:矩形高度
    • x:定义矩形的左边位置
    • y:定义矩形的顶部位置
    • rx:矩形 \(x\) 轴圆角半径长度
    • ry:矩形 \(y\) 轴圆角半径长度
    • fill:填充颜色,如颜色名称、rgb()、十六进制颜色值
    • fill-opacity:填充颜色不透明度,取值范围 0 到 1
  • 举例:

    <svg width="200" height="150">
      <rect
        width="100"
        height="75"
        fill="blue"
        fill-opacity="0.7"
        stroke="red"
        stroke-width="4"
        x="40"
        y="30"
        rx="20"
        ry="40"
      />
    </svg>
    

(4)圆形

  • 标签:<circle />

  • 属性:

    • cx:圆心 \(x\) 坐标
    • cy:圆心 \(y\) 坐标
    • r:圆半径
  • 举例:

    <svg width="200" height="150">
      <circle
        cx="100"
        cy="75"
        r="50"
        fill="blue"
        stroke="red"
        stroke-width="4"
      />
    </svg>
    

(5)椭圆形

  • 标签:<ellipse />

  • 属性:

    • cx:中心 \(x\) 坐标
    • cy:中心 \(y\) 坐标
    • rx:水平半径
    • ry:垂直半径
  • 举例:

    <svg width="200" height="150">
      <ellipse
        cx="100"
        cy="75"
        rx="50"
        ry="25"
        fill="blue"
        stroke="red"
        stroke-width="4"
      />
    </svg>
    

(6)多边形

至少包含三个边

  • 标签:<polygon />

  • 属性:points:点集,定义多边形每个角的 \((x,\ y)\) 坐标

  • 举例:

    <svg width="200" height="150">
      <polygon
        points="100,0 0,25 25,100 100,150 175,100 200,25"
        fill="blue"
        stroke="red"
        stroke-width="4"
      />
    </svg>
    

(7)路径

  • 标签:<path />

  • 属性:d:(draw)绘制路径的命令

    • 命令区分大小写

      • 大写表示绝对定位,相对坐标原点
      • 小写表示相对定位,相对上一个绘制点
    • M x yM 是 M 命令(move to),作用是定义绘制图形的起点坐标 \((x,\ y)\)

    • l x yL 是 L 命令(line to),作用是从上一个绘制点到 \((x,\ y)\) 绘制直线

      <svg width="200" height="100">
        <path
          d="M 0 100 L 100 0 L 200 50"
        />
      </svg>
      
    • q x1 y1 x2 y2Q 是命令(quadratic Bézier curve),作用是绘制二次贝塞尔曲线,需要控制点坐标 \((x1,\ y1)\) 和终点坐标 \((x2,\ y2)\)

      <svg width="200" height="160">
        <g fill="orange">
          <circle cx="40" cy="140" r="3" />
          <circle cx="100" cy="20" r="3" />
          <circle cx="160" cy="140" r="3" />
        </g>
        <g font-size="20" text-anchor="middle" fill="orange">
          <text x="40" y="140" dx="-20">A</text>
          <text x="100" y="20" dx="-20">B</text>
          <text x="160" y="140" dx="20">C</text>
        </g>
        <g stroke-width="3" fill="none">
          <path d="M 40 140 l 60 -120" stroke="red" />
          <path d="M 100 20 l 60 120" stroke="red" />
          <path d="M 70 80 l 60 0" stroke="green" />
          <path d="M 40 140 q 60 -120 120 0" stroke="blue" />
        </g>
      </svg>
      
      A B C

0x03 文本

  • 标签:

    • <text>Text</text>

    • 子标签:<tspan>Sub text</tspan>

      • 可以设置文本的不同格式
    • 添加链接,如:

      <svg xmlns:xlink="http://www.w3.org/1999/xlink">
        <a xlink:href="https://example.com" target="_blank">
          <text>example.com</text>
        </a>
      </svg>
      
  • 属性:

    • x\(x\) 轴上的位置坐标
    • y\(y\) 轴上的位置坐标
    • dx:坐标相对 \(x\) 轴正方向偏移量
    • dy:坐标相对 \(y\) 轴正方向偏移量
    • font-size:文本大小
    • text-anchor:文本对齐方式
      • 取值包括:startmiddleend
      • 通过设定 \((x,\ y)\) 相对于文本的位置实现
        • 比如,当设置为 middle 时,\((x,\ y)\) 在文本的中间
    • transform:文本变换
      • rotate(deg x,y):旋转,deg 为旋转角度,xy 表示旋转中心点的坐标(默认 \((0,\ 0)\)
  • 举例:

    <svg width="200" height="100">
      <rect
        width="200"
        height="100"
        fill="red"
      />
      <text
        x="100"
        y="55"
        font-size="16"
        text-anchor="middle"
        fill="white"
        transform="rotate(10 100,55)"
      >
        Hello,
        <tspan font-size="24">
          SVG
        </tspan>
      </text>
    </svg>
    
    Hello, SVG

0x04 描边

  • SVG 通过笔画属性实现描边效果,如颜色、宽度、不透明度、线帽、自定义虚线

    • stroke:笔画颜色,取值为任何合法的颜色值,如颜色名称、rgb()、十六进制颜色值

      <svg width="100" height="60">
        <g stroke-width="4">
          <line x1="0" y1="10" x2="80" y2="10" stroke="red" />
          <line x1="0" y1="30" x2="80" y2="30" stroke="rgb(255,0,0)" />
          <line x1="0" y1="50" x2="80" y2="50" stroke="#FF0000" />
        </g>
      </svg>
      
    • stroke-width:笔画宽度,取值为数字

      <svg width="100" height="60">
        <g stroke="red">
          <line x1="0" y1="10" x2="80" y2="10" stroke-width="1" />
          <line x1="0" y1="30" x2="80" y2="30" stroke-width="3" />
          <line x1="0" y1="50" x2="80" y2="50" stroke-width="5" />
        </g>
      </svg>
      
    • stroke-opacity:笔画不透明度,取值在 0 到 1 之间

      <svg width="100" height="60">
        <g stroke="red" stroke-width="4">
          <line x1="0" y1="10" x2="80" y2="10" stroke-opacity="0.25" />
          <line x1="0" y1="30" x2="80" y2="30" stroke-opacity="0.5" />
          <line x1="0" y1="50" x2="80" y2="50" stroke-opacity="0.75" />
        </g>
      </svg>
      
    • stroke-linecap:笔画线帽属性,定义开放路径不同类型的结束点,取值有三个:

      • butt:默认,无线帽
      • round:圆形线帽
      • square:方形线帽
      <svg width="100" height="60">
        <g stroke="red" stroke-width="4">
          <line x1="0" y1="10" x2="80" y2="10" stroke-linecap="butt" />
          <line x1="0" y1="30" x2="80" y2="30" stroke-linecap="round" />
          <line x1="0" y1="50" x2="80" y2="50" stroke-linecap="square" />
        </g>
      </svg>
      
    • stroke-dasharray:虚线笔画属性,取值为数字数组(个数 \(\geq 2\)),用于定义线条与间隙大小

      • 奇数位为线条长度,偶数位为间隙长度
      <svg width="100" height="60">
        <g stroke="red" stroke-width="4">
          <line x1="0" y1="10" x2="80" y2="10" stroke-dasharray="10,5" />
          <line x1="0" y1="30" x2="80" y2="30" stroke-dasharray="10,10,5" />
          <line x1="0" y1="50" x2="80" y2="50" stroke-dasharray="5,5,10,10" />
        </g>
      </svg>
      
  • 笔画属性可以应用于所有形状与文本

0x05 效果

  • 通过 <filter></filter> 标签实现模糊和阴影效果

    • 其中可以包含一个或多个效果滤镜
    • 必要属性 id 用于标识过滤器,从而被形状使用
    • 其父元素为 <defs></defs>,defs 是 definitions 的简写
    <svg>
      <defs>
        <filter id="cusFilter"></filter>
      </defs>
    
      <rect filter="url(#cusFilter)" />
    </svg>
    

(1)模糊

  • 高斯模糊效果可以通过 feGaussianBlur 滤镜实现

    <svg width="100" height="60">
      <defs>
        <filter x="0" y="0" id="filter-blur">
          <feGaussianBlur />
        </filter>
      </defs>
    </svg>
    
  • 模糊效果滤镜属性 stdDeviation:定义模糊数量,值越大越模糊

    <svg width="120" height="70">
      <defs>
        <filter x="0" y="0" id="filter-blur">
          <feGaussianBlur stdDeviation="10" />
        </filter>
      </defs>
      <g fill="blue" stroke="red" stroke-width="4">
        <circle cx="30" cy="30" r="25" filter="url(#filter-blur)" />
        <circle cx="90" cy="30" r="25" />
      </g>
    </svg>
    

(2)阴影

  • 阴影效果的原理:将图形复制并相对原图形偏移

  • 阴影效果可以通过 feOffsetfeBlend 滤镜实现

  • <feOffset /> 用于偏移图形,其属性包括:

    • dx:阴影在 \(x\) 轴上的偏移量
    • dy:阴影在 \(y\) 轴上的偏移量
    • in:阴影图形来源,取值如下
      • SourceAlpha:黑色阴影
      • SourceGraphic:原图形
  • <feBlend /> 用于在偏移的图形上混合原始图形,其属性需要 in=SourceGraphic

  • 举例:

    <svg width="120" height="80">
      <defs>
        <filter x="0" y="0" id="filter-shadow">
          <feOffset dx="10" dy="10" in="SourceAlpha" />
          <feGaussianBlur stdDeviation="10" />
          <feBlend in="SourceGraphic" />
        </filter>
      </defs>
      <g fill="blue" stroke="red" stroke-width="4">
        <circle cx="30" cy="30" r="25" filter="url(#filter-shadow)" />
        <circle cx="90" cy="30" r="25" />
      </g>
    </svg>
    

0x06 渐变

  • 渐变是指从一种颜色到另一种颜色的平滑过渡
    • 可以是两个或多个颜色之间渐变
  • SVG 渐变分为线性渐变和径向渐变

(1)线性

  • 线性渐变包括水平渐变、垂直渐变、角度渐变

  • <defs></defs> 中使用 <linearGradient></linearGradient> 实现

  • linearGradient 标签属性:

    • id:标识渐变设置,从而被形状使用
    • x1\(x\) 轴上的起点坐标
    • y1\(y\) 轴上的起点坐标
    • x2\(x\) 轴上的终点坐标
    • y2\(y\) 轴上的终点坐标
    • \(y1 = y2\)\(x1 \neq x2\) 时,是水平渐变
    • \(x1 = x2\)\(y1 \neq y2\) 时,是垂直渐变
  • 渐变过程中的每个颜色使用 <stop /> 指定

  • stop 标签属性:

    • offset:定义渐变颜色的结束位置,取值为相对位置的百分比
    • stop-color:定义渐变的颜色
  • 举例:

    <svg width="100" height="60">
      <defs>
        <linearGradient id="lg" x1="0%" y1="0%" x2="100%" y2="0%">
          <stop offset="0%" stop-color="red" />
          <stop offset="16%" stop-color="orange" />
          <stop offset="32%" stop-color="yellow" />
          <stop offset="48%" stop-color="green" />
          <stop offset="64%" stop-color="blue" />
          <stop offset="80%" stop-color="cyan" />
          <stop offset="96%" stop-color="purple" />
        </linearGradient>
      </defs>
      <ellipse cx="50" cy="30" rx="45" ry="25" fill="url(#lg)" />
    </svg>
    

(2)径向

  • <defs></defs> 中使用 <radialGradient></radialGradient> 实现

  • radialGradient 标签属性:

    • id:标识渐变设置,从而被形状使用
    • cxcy:定义外圆的中心坐标
    • fxfy:定义内圆的中心坐标
    • r:定义外圆半径
  • 径向渐变的颜色也用 <stop /> 标签指定

  • 举例:

    <svg width="100" height="60">
      <defs>
        <radialGradient id="rg" cx="50%" cy="50%" fx="50%" fy="50%" r="50%">
          <stop offset="0%" stop-color="red" />
          <stop offset="96%" stop-color="orange" />
        </radialGradient>
      </defs>
      <ellipse cx="50" cy="30" rx="45" ry="25" fill="url(#rg)" />
    </svg>
    

-End-

posted @ 2024-06-07 01:29  SRIGT  阅读(25)  评论(0编辑  收藏  举报