SVG学习(一)

50 阅读6分钟

SVG 可缩放矢量图形,是一种以xml格式,描述的二维图形。由于是xml格式,所以可以直接写在html中展示出来。也可以用.svg格式在img标签中展示。在网页图形越来越复杂的现代,会一点svg语法会很有帮助。

以MDN上为例,一个简单的svg图形示例

<svg version="1.1"
     baseProfile="full"
     width="300" height="200"
     xmlns="http://www.w3.org/2000/svg">
  <rect width="100%" height="100%" fill="red" />
  <circle cx="150" cy="100" r="80" fill="green" />
  <text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text>
</svg>

其中svg标签内是版本号,命名空间等。重点看width和height,它表示当前图形绘制的区域大小,宽300像素,长200像素。rect表示一个矩形,它的宽高都是当前区域的100%,用红色填充。circle表示是圆形,圆心在(150,100)像素处,半径是80px。

text表示文本,其中的x和y表示当前文本底边上的一点,text-anchor则表示这个点是中点。如果没有text-anchor的话,这个点就是起点。font-size表示字体大小,fill是填充颜色。

最终呈现的效果如下图

在svg中坐标与html中一致,从(0,0)开始,往左是横坐标,往下是纵坐标。整个区域的大小由svg标签中的width和height来定义。

在svg中用特定的标签来表示基本的图形形状,其中

rect表示矩形,x, y 属性代表这个矩形的左上角位置,width和height代表这个矩形的宽高。rx和ry代表矩阵圆角。

circle是圆形,x和y代表圆心的位置,r代表半径。

ellipse是椭圆,rx和ry代表椭圆的长半径和短半径,cx和cy代表圆心位置。

line是一段线条,所有它有四个点,x1和y1是起点,x2和y2是终点位置。

polyline是折线,将一堆点的集合连接在一起就是折线,所以它的属性是points,必须由两个数字组成一个点,数字之间可以用逗号,空格隔开,例如:

<polyline points="60,110  65,120 70,115 75,130 80,125 85,140 90,135 95,150 100,145"/>

path路径是svg中一个很重要的形状,可以用来绘制直线,曲线等各种图形。path元素的形状是依靠d属性来绘制的。d属性是“命令+参数”的集合。下面会介绍具体的命令。

M命令表示移动到某一个点上,需要注意它代表移动而不是绘制。可以理解为“提起画笔,然后把画笔放在某个点上”,这个时候画布上没有任何图案。通常会写在开头,表示一个图形的起点

L命令是真正画出直线的命令,它的后面通常会跟一个点的位置,表示当前位置绘制直线到某个点。

H命令代表水平方向移动,V代表垂直方向移动,所以它们后面只有一个点的参数。

除此之外也可以用小写字母,m,l,h,v,表示移动到当前点的相对位置上。

Z不区分大小写字母,表示闭合路径,从当前点回到起点。

<path d="M 10 10 H 90 V 90 H 10 Z" fill="transparent" stroke="black"/>

上面的路径可以绘制出一个正方形

绘制贝塞尔曲线可以用C和Q命令,代表三次贝塞尔曲线和二次贝塞尔曲线,涉及到几何和数学,具体可以看MDN  developer.mozilla.org/zh-CN/docs/…

C命令后面需要有三个点,前两个是曲线控制点,后一个是曲线终点。也可以用S命令简化为两个点,用前一个曲线控制点,或者当前点做这条曲线的第一个控制点。

Q命令后有两个点,代表一个控制点和一个终点。简化后的T命令,前面必须有一个Q或者另一个T命令。T命令后只需要一个点。

A命令可以绘制一个圆弧,由7个参数构成,分别是x半径,y半径,旋转情况,角度大小,弧线方向,最后是终点坐标。

对于任意一个形状,可以用fill属性设置形状内部颜色,stroke设置线条颜色,可以用css相同的,例如颜色名称,十六进制,rgb值等。fill-opacity和stroke-opacity设置对应的透明度。stroke-width设置线条宽度,或者可以说是画笔粗细。此外还有stroke-linecap属性设置线条终点形状,stroke-linejoin设置两条线条连接方式,stroke-dasharray定义虚线形状。

除此之外还可以用style属性来定义样式,可以写在行内

<rect x="10" height="180" y="10" width="180" style="stroke: black; fill: red;"/>

也可以写在defs区域

<?xml version="1.0" standalone="no"?>
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" version="1.1">
  <defs>
    <style><![CDATA[
       #MyRect {
         stroke: black;
         fill: red;
       }
    ]]></style>
  </defs>
  <rect x="10" height="180" y="10" width="180" id="MyRect"/>
</svg>

svg也可以设置渐变,和css设置的思路是一致的,开始颜色,在何处要变为另一种颜色。但是要写在defs区域内。

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

还可以设置径向渐变等,具体可以查看developer.mozilla.org/zh-CN/docs/…

patterns可以由基础形状来构成自定义形状,从而在其他地方引用。也需要在defs内定义。有一点类似border-image。具体可以看MDN:developer.mozilla.org/zh-CN/docs/…

设置文字可以用三种方式,一是text标签,还有写在text标签内的tspan标签,还可以用tref标签引用其他位置的文本内容。text的一些属性,x和y表示当前文本底边上的一点,text-anchor则表示这个点是中点。如果没有text-anchor的话,这个点就是起点。font-size表示字体大小,fill是填充颜色。stroke是文字描边颜色。tspan属性中同样有x,y用来表明文字的位置,还可以是一个数组,来对文字的每一个字符单独设置。textpath 利用它的xlink:h属性取得一个任意路径,把字符对齐到路径,于是字体会环绕路径、顺着路径走。

g标签可以把某一个属性同时应用到其内包含的所有元素

平移translate,旋转rotate,缩放scale等也可以像css一样应用在transform属性上

<rect x="0" y="0" width="10" height="10" transform="translate(30,40)" />

剪切的原理是用clipPath定义一块可以展示的区域,实际的元素来引用这块区域,两个叠加产生剪切的效果

<svg
  version="1.1"
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink">
  <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>

mask遮罩也是同理,定义一个透明度渐变的遮罩,再与实际元素叠加产生效果。

image标签用来引入图片内容,x,y属性定义位置,width和height定义大小,xlink:href引入图片地址。

filter标签可以用来创建滤镜效果

svg可以用link标签引入css文件,而text等每个标签都可以设置class值,这样css与svg就可以结合在一起了。

svg基础内容就以上,更多信息可以看MDN:developer.mozilla.org/zh-CN/docs/…