初学svg

Posted just小千

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初学svg相关的知识,希望对你有一定的参考价值。

初学svg

svg(scalable vector graphics)可缩放矢量图形,使用xml格式来定义图像,svg在放大或者改变尺寸的情况下其图形质量不会有所损失

<?xml version="1.0" standalone="no"?>
<!-- XML 指可扩展标记语言(EXtensible Markup Language),被设计为传输和存储数据,其焦点是数据的内容 -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">  
<!-- 文档类型定义(DTD)可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。
DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用,在此是外部引用-->
<svg   version="1.1"
xmlns="http://www.w3.org/2000/svg">
<rect  
style="fill:rgb(0,0,255);stroke-width:1;
stroke:rgb(0,0,0)"/>
</svg>

demo显示的是一个高100,宽300的长方形

1.svg形状
  • 矩形 <rect>

    width/height:矩形的宽高

    x/y:矩形的左侧和顶端距离

    rx/ry:使矩形产生圆角

    style:定义css属性(fill是填充颜色,stroke-width是边框宽度,stroke是边框颜色),属性之间用分号隔开

  • 圆形 <circle>

    cx/cy:圆点的x/y坐标,默认为(0,0)

    r:半径

    Tips:没有宽高(有半径和圆点就能画出来了),style属性都是通用的

  • 椭圆 <ellipse>

    cx/cy:圆点的x/y坐标,默认为(0,0)

    rx/ry:水平半径/垂直半径

  • 线 <line>

    x1/y1:线条开始的xy

    x2/y2:线条结束的xy

  • 折线 <polyline>

    创建仅仅包含直线的形状

    points:定义每个点的x和y坐标,用空格区分

  • 多边形 <polygon>

    不少于三个点的图形

    points:定义多边形每个角的x和y坐标,用空格区分

    e.g.points="220,100 300,210 170,250"

  • 路径 <path>

    • M = moveto:需要移动到的点的坐标(x y)
    • L = lineto:新位置的点(x y),生成上一个位置到当前位置的线段
    • H = horizontal lineto:平行线(x),一个参数,表示平移后的位置
    • V = vertical lineto:垂直线(y),一个参数,表示垂直平移后点的位置
    • C = curveto:三次贝塞尔曲线(x1 y1,x2 y2,x y)x1/y1和x2/y2是两个控制点,x/y是锚点,起点的命令是M(x y)
    • S = smooth curveto:简写的贝塞尔曲线,当一个点某一侧的控制点是它另一侧的控制点的对称(以保持斜率不变(x2 y2, x y),放在C命令后面时,画出来是C的斜率一样的反向曲线,单独用时就会假设两个控制点都是x2 y2
    • Q = quadratic Belzier curve:二次贝塞尔曲线(x1 y1, x y),只有一个控制点
    • T = smooth quadratic Belzier curveto:Q命令的简写,跟在Q后面,只写一个终点就好,会自动推算出控制点,如果前面没有Q,默认没有控制点,画出来是直线(x y)
    • A = elliptical Arc:椭圆弧,七个参数(rx ry x-axis-rotation large-arc-flag sweep-flag x y) (太复杂了有用到的时候再详细研究好了)
    • Z = closepath:闭合曲线:从当前点画一条直线到起点,不区分大小写,木有参数

      对应的命令大小写都可以,大写表示绝对定位,小写表示相对定位

2.svg滤镜

fe相关的属性,具体没咋研究,用<defs>和<filter>来标识

所有互联网的SVG滤镜定义在<defs>元素中。<defs>元素定义短并含有特殊元素(如滤镜)定义。

<filter>标签用来定义SVG滤镜。<filter>标签使用必需的id属性来定义向图形应用哪个滤镜

3.渐变

包括线性渐变(linearGradient)和辐射渐变(radialGradient),都要在defs的包裹下

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
  <defs>
    <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
      <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
    </linearGradient>
  </defs>
  <defs>
    <radialGradient id="grad2" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
      <stop offset="0%" style="stop-color:rgb(255,255,0);
      stop-opacity:0" />
      <stop offset="100%" style="stop-color:rgb(0,0,255);stop-opacity:1" />
    </radialGradient>
  </defs>
  <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad1)" />
  <text fill="url(#grad2)" font-size="45" font-family="Verdana" x="150" y="400">
  SVG</text>
</svg>
4.动画

svg动画的实现有两种方式,第一种是svg+SMIL animation,第二种是配合css相关属性以及css动画实现

  • svg+SMIL(Synchronized Multimedia Integration Language(同步多媒体集成语言))

    1.animate

    包含属性:attributeName(进行动画的属性名称),attributeType(auto,CSS,XML,属性在哪个命名空间里,一般可不填),from,to,dur,repeatCount

    <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
    <defs>
    <radialGradient id="grad2" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
          <stop offset="0%" style="stop-color:rgb(255,255,0);
          stop-opacity:1" />
          <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
        </radialGradient>
        </defs>
      <rect   fill="url(#grad2)">
        <animate attributeName="rx" values="50;0;50" dur="4s" repeatCount="indefinite" />
      </rect>
    </svg>

    2.animateMotion

    定义了一个元素如何沿着运动路径进行移动,必要时可以用mpath将path嵌入

    <svg viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
      <path 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>
    </svg>
    
    <svg viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
      <path fill="none" id="path1"  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">
            <mpath xlink:href="#path1" />
          <!-- 可以避免重复写path,但是要先声明xmlns:xlink -->
          </animateMotion>
      </circle>
    </svg>

    3.animateTransform

    变动了目标元素上的变形属性,使目标属性可以旋转,缩放,转换等等

    <svg    viewBox="0 0 120 120"
         xmlns="http://www.w3.org/2000/svg" version="1.1"
         xmlns:xlink="http://www.w3.org/1999/xlink" >
    
        <polygon points="60,30 90,90 30,90">
            <animateTransform attributeName="transform"
                              attributeType="XML"
                              type="rotate"
                              from="0 60 70"
                              to="360 60 70"
                              dur="3s"
                              repeatCount="indefinite"/>
        </polygon>
    </svg>
  • css动画实现

    引用css来实现动画,这个和css动画差不多,

    在此拿填充属性stroke-dasharray 进行举例,从虚线长为0,间隔一个圆周,渐变到虚线为圆周长,间隔一个圆周长,这样就能实现圆环的填充

<hgroup class="circle-load">
    <svg   version="1.1" xmlns="http://www.w3.org/2000/svg">
    <style>
.circle-load {
    position: absolute;
    width: 200px;
    height: 200px;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.circle-load-svg {
    stroke-dasharray: 0 570; 
    animation: rot 5s ease-out infinite;
}

@keyframes rot {
    100% {
        stroke-dasharray: 570 570;
    }
}

</style>
        <circle cx="110" cy="110" r="90" stroke- stroke="gainsboro" fill="none"></circle>
        <circle cx="110" cy="110" r="90" stroke- stroke="darkturquoise" fill="none" class="circle-load-svg"></circle>
    </svg>
</hgroup>

以上是关于初学svg的主要内容,如果未能解决你的问题,请参考以下文章

text 使用SVG的片段

初学svg

css 快速片段将svg与中心对齐并缩放到视口大小。

通过 webapp 提供时,SVG 片段标识符在 Safari 中被交换

可从 HTML 拖放到 SVG 上

在PaddlePaddle中的Notebook代码片段