css 利用svg path绘制图形动画

802 阅读3分钟

svg语法

svg详细基础知识

1、<svg>

在单独svg文件中

xml和!DOCTYPE标签必须要保留,否则在ie上无法显示。 svg上的xmlns属性必须存在

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%"  viewBox="0 0 100% 100%"  xmlns="http://www.w3.org/2000/svg"   xmlns:xlink="http://www.w3.org/1999/xlink">
  
</svg>

嵌入在HTML文件中

svg上的xmlns属性必须存在

<svg class="ec-svg-container" width="700" height="600" viewBox="0 0 700 600" xmlns="http://www.w3.org/2000/svg">
</svg>

<svg>上的widthheight定义图像元素在HTML中占据的宽度和高度,viewBox属性包含四个值,分别是左上角横坐标、左上角纵坐标、视口宽度、视口高度。如果不指定width和height,则图像大小默认为300px*150px。如果只指定了width和height不指定viewBox,则图像的默认大小将等于所在的 HTML 元素的大小

2、<rect>

用于绘制矩形。
<svg width="100%" height="100%"  viewBox="0 0 100% 100%"  xmlns="http://www.w3.org/2000/svg"   xmlns:xlink="http://www.w3.org/1999/xlink">
   <rect x="0" y="0" width="200" height="100" fill="black" stroke-width="2" stroke="red" />
</svg>

x:左上角横坐标;y:左上角纵坐标;width:矩形的宽度;height:矩形的高度。

fill:填充色;stroke:描边色;stroke-width:边框宽度

image.png

3、<circle>

用于绘制圆形。
<svg width="100%" height="100%"  viewBox="0 0 100% 100%"  xmlns="http://www.w3.org/2000/svg"   xmlns:xlink="http://www.w3.org/1999/xlink">
   <circle cx="30"  cy="50" r="25" />
   <circle cx="90"  cy="50" r="25" fill="red" />
   <circle cx="150" cy="50" r="25" fill="blue" />
</svg>

cx:圆心横坐标;cy:圆心纵坐标;r:半径。

image.png

4、<ellipse>

用于绘制椭圆形。
<svg width="100%" height="100%"  viewBox="0 0 100% 100%"  xmlns="http://www.w3.org/2000/svg"   xmlns:xlink="http://www.w3.org/1999/xlink">
   <ellipse cx="80" cy="80" ry="70" rx="30" stroke="rgba(0,0,0,0.9)" stroke-width="5" fill="rgba(0,255,255,0.6)"/>
</svg>

cx:椭圆中心横坐标;cy:椭圆中心纵坐标;rx:椭圆横向轴半径;ry:椭圆纵向轴半径。

image.png

5、<line>

用于绘制直线。
<svg width="100%" height="100%"  viewBox="0 0 100% 100%"  xmlns="http://www.w3.org/2000/svg"   xmlns:xlink="http://www.w3.org/1999/xlink">
  <line x1="0" y1="0" x2="200" y2="0" stroke="rgba(0,255,255,0.8)" stroke-width="7" />
</svg>

x1:起点横坐标;y1:起点纵坐标;x2:终点横坐标;y2:终点纵坐标。

image.png

6、<polyline>

用于绘制折线。
<svg width="100%" height="100%"  viewBox="0 0 100% 100%"  xmlns="http://www.w3.org/2000/svg"   xmlns:xlink="http://www.w3.org/1999/xlink">
  <polyline points="3,3 30,28 3,53" fill="none" stroke="rgba(0,255,255,0.8)" stroke-width="7"/>
</svg>

points指定了每个端点的坐标,横坐标与纵坐标之间用逗号分隔,点与点之间用空格分隔。

image.png

7、<polygon>

用于绘制多边形。
<svg width="100%" height="100%"  viewBox="0 0 100% 100%"  xmlns="http://www.w3.org/2000/svg"   xmlns:xlink="http://www.w3.org/1999/xlink">
  <polygon fill="rgba(0,255,255,0.8)" stroke="rgba(0,0,0,0.8)" stroke-width="1" points="0,0 100,0 100,100 0,100 0,0"/>
</svg>

points指定了每个端点的坐标,横坐标与纵坐标之间用逗号分隔,点与点之间用空格分隔。

image.png

8、<text>

用于绘制文本。
<svg width="100%" height="100%"  viewBox="0 0 100% 100%"  xmlns="http://www.w3.org/2000/svg"   xmlns:xlink="http://www.w3.org/1999/xlink">
  <text x="50" y="25" fill="rgba(0,255,255,0.8)" stroke-width="2" stroke="rgba(0,255,255,0.8)">我是一个svg画出来的文本</text>
</svg>

x:文本区块基线起点的横坐标;y:文本区块基线起点的纵坐标;

image.png

9、<path>

用于绘制路径。
<svg width="100%" height="100%"  viewBox="0 0 100% 100%"  xmlns="http://www.w3.org/2000/svg"   xmlns:xlink="http://www.w3.org/1999/xlink">
  <path d=" M 18,3 L 46,3 L 46,40 L 61,40 L 32,68 L 3,40 L 18,40 Z " fill="rgba(0,255,255,0.8)"></path>
</svg>

image.png

10、<use>

用于复制一个图形。
<svg width="100%" height="100%"  viewBox="0 0 100% 100%"  xmlns="http://www.w3.org/2000/svg"   xmlns:xlink="http://www.w3.org/1999/xlink">
  <path d=" M 18,3 L 46,3 L 46,40 L 61,40 L 32,68 L 3,40 L 18,40 Z "  id="myPath"></path>
  <use href="#myPath" x="60" y="0" fill="blue" />
  <use href="#myPath" x="120" y="0" fill="white" stroke="blue" />
</svg>

herf为所要复制的节点的id;x:左上角横坐标;y:左上角纵坐标。

image.png

11、<g>

用于将多个形状组成一个组。
<svg width="100%" height="100%"  viewBox="0 0 100% 100%"  xmlns="http://www.w3.org/2000/svg"   xmlns:xlink="http://www.w3.org/1999/xlink">
 <g  id="myPath">
    <path d=" M 18,3 L 46,3 L 46,40 L 61,40 L 32,68 L 3,40 L 18,40 Z "></path>
    <text x="20" y="90">箭头</text>
  </g>
  <use href="#myPath" x="60" y="0" fill="blue" />
  <use href="#myPath" x="120" y="0" fill="white" stroke="blue" />
</svg>

image.png

12、<defs>

用于自定义形状,内部的代码不会显示,仅供引用。
<svg width="100%" height="100%"  viewBox="0 0 100% 100%"  xmlns="http://www.w3.org/2000/svg"   xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
   <g  id="myPath">
      <path d=" M 18,3 L 46,3 L 46,40 L 61,40 L 32,68 L 3,40 L 18,40 Z "></path>
      <text x="20" y="90">箭头</text>
    </g>
  </defs>
  <use href="#myPath" x="60" y="0" fill="blue" />
  <use href="#myPath" x="120" y="0" fill="white" stroke="blue" />
</svg>

image.png

13、<pattern>

用于用于自定义一个形状,该形状可以被引用来平铺一个区域。
<svg width="100%" height="100%"  viewBox="0 0 100% 100%"  xmlns="http://www.w3.org/2000/svg"   xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <pattern id="dots" x="0" y="0" width="100" height="100" patternUnits="userSpaceOnUse">
      <path d=" M 18,3 L 46,3 L 46,40 L 61,40 L 32,68 L 3,40 L 18,40 Z "></path>
    </pattern>
  </defs>
  <rect x="0" y="0" width="100%" height="100%" fill="url(#dots)" />
</svg>

patternUnits属性值为:userSpaceOnUse和objextBoundingBox;

objectBoundingBox(默认值):x、y、width和height的值都是占外框(包裹pattern的元素)的百分比。比如上面的例子中:将pattern中width、height设为1时,相当于pattern内的图案占rect的百分百,设置为0.2,相当于占rect的20%。

userSpaceOnUse:x、y、width和height表示的值都是当前用户坐标系统的值。也就是说,这些值没有缩放,都是绝对值。 image.png

14、<animate>

用于产生动画效果。
<svg width="100%" height="100%"  viewBox="0 0 100% 100%"  xmlns="http://www.w3.org/2000/svg"   xmlns:xlink="http://www.w3.org/1999/xlink">
 <rect x="0" y="0" width="100" height="100" fill="rgba(0,255,255,0.8)">
    <animate attributeName="x" from="0" to="500" dur="2s" repeatCount="indefinite" />
  </rect>
</svg>

attributeName:发生动画效果的属性名;from:单次动画的初始值;to:单次动画的结束值;dur:单次动画的持续时间;repeatCount:动画的循环模式;

15、<animateTransform>

用于产生图形变形的动画效果。
<svg width="100%" height="100%"  viewBox="0 0 100% 100%"  xmlns="http://www.w3.org/2000/svg"   xmlns:xlink="http://www.w3.org/1999/xlink">
    <animateTransform attributeName="transform" type="rotate" begin="0s" dur="3s" from="0 200 200" to="360 200 200" repeatCount="indefinite" />
</svg>

attributeName:发生动画效果的属性名;from和to:动画属性的初始值和结束值,三个值分别为角度值、旋转中心的横坐标、旋转中心的纵坐标;dur:单次动画的持续时间;repeatCount:动画的循环模式;type:变形类型,属性值有:translate | scale | rotate | skewX | skewY

16、<animateMotion>

用于产生路径动画效果。
<svg width="100%" height="100%"  viewBox="0 0 100% 100%"  xmlns="http://www.w3.org/2000/svg"   xmlns:xlink="http://www.w3.org/1999/xlink">
 <rect x="0" y="0" width="300" height="100" fill="rgba(0,255,255,0.5)" stroke-width="1" stroke="red" />
  <circle cx="0" cy="50" r="15" fill="black" stroke="black" stroke-width="1">
    <animateMotion path="M 0 0 L300 0 Z" dur="3s" repeatCount="indefinite" />
  </circle>
</svg>

<mpath>是一个辅助元素。<animateMotion>等元素可以引用一个外部的定义的<path>。让图像元素按这个<path>轨迹运动。

17、<radialGradient>、<linearGradient>

用于产生径向渐变、线性渐变效果。
<svg xmlns="http://www.w3.org/2000/svg" width="250" height="200">
  <linearGradient id="linearGradient" 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>
  <text x="10" y="30" font-size="30px" fill="url(#linearGradient)">这是线性渐变</text>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="250" height="200">
  <radialGradient id="radialGradient" 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="50%" style="stop-color:rgb(255,0,0);stop-opacity:0.5" />
    <stop offset="100%" style="stop-color:rgb(0,0,255);stop-opacity:1" />
  </radialGradient>
  <text x="10" y="30" font-size="30px" fill="url(#radialGradient)">这是径向渐变</text>
</svg>

image.png

实践

svg.svg

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- rgba(0,255,255,0.8) -->
<svg width="100%" height="100%"  viewBox="0 0 100% 100%"  xmlns="http://www.w3.org/2000/svg"   xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <!-- 径向渐变 -->
    <radialGradient id="radialGradient" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
      <stop offset="0%" stop-color="#fff" stop-opacity="1" />
      <stop offset="100%" stop-color="#fff" stop-opacity="0" />
    </radialGradient>
    <!-- 动画路径 -->
    <path id="animationPath" d="M250 5 L 323 5 L 351 17 L 548 17 L 554 5 L 641 5 L 662 28 L 682 28 L 682 88 L 665 100 L 665 394 L 682 404 L 682 435 L670 455 L400 455 L385 445 L200 445 L180 455 L5 455 L 5 30 L 30 5" fill="transparent"></path>
    <!-- 动画 -->
    <mask id="mask">
      <circle  cx="0" cy="0" r="50" fill="url(#radialGradient)">
        <animateMotion dur="6s" rotate="auto" repeatCount="indefinite">
          <mpath xlink:href="#animationPath"></mpath>
        </animateMotion>
      </circle>
    </mask>
  </defs>
  <use stroke-width="5" xlink:href="#animationPath" mask="url(#mask)"  stroke="rgba(0,255,255,0.7)"></use>
  <!-- 外框 -->
  <path fill="transparent" stroke="rgba(0,255,255,0.7)" stroke-width="2" d="M30 5 L60 5 Z"> </path>
  <path fill="transparent" stroke="rgba(0,255,255,0.7)" stroke-width="2" d="M250 5 L323 5 L351 17 L548 17 L554 5 L641 5 L662 28 L682 28 L682 88 L665 100 L665 394 L682 404 L682 435 L670 455 L400 455 L385 445 L200 445 L180 455 L5 455 L5 30 L30 5"> </path>
  <!--上方的线-->
  <path d="M 352 6 L 540 6" stroke="rgba(0,255,255,0.7)" stroke-width="2" stroke-linejoin="round" stroke-dasharray="8" />
  <!--右侧小方块-->
  <path d="M 673 102 L 678 102 L 678 122 L 673 122 z" fill="transparent" stroke="rgba(0,255,255,0.7)" stroke-width="2" stroke-linejoin="round" />
  <path d="M 673 135 L 678 135 L 678 155 L 673 155 z" fill="transparent" stroke="rgba(0,255,255,0.7)" stroke-width="2" stroke-linejoin="round" />
  <path d="M 673 168 L 678 168 L 678 188 L 673 188 z" fill="transparent" stroke="rgba(0,255,255,0.7)" stroke-width="2" stroke-linejoin="round" />
  <path d="M 673 201 L 678 201 L 678 221 L 673 221 z" fill="transparent" stroke="rgba(0,255,255,0.7)" stroke-width="2" stroke-linejoin="round" />
  <path d="M 673 234 L 678 234 L 678 254 L 673 254 z" fill="transparent" stroke="rgba(0,255,255,0.7)" stroke-width="2" stroke-linejoin="round" />
  <path d="M 673 267 L 678 267 L 678 287 L 673 287 z" fill="transparent" stroke="rgba(0,255,255,0.7)" stroke-width="2" stroke-linejoin="round" />
  <path d="M 673 300 L 678 300 L 678 320 L 673 320 z" fill="transparent" stroke="rgba(0,255,255,0.7)" stroke-width="2" stroke-linejoin="round" />
  <path d="M 673 333 L 678 333 L 678 353 L 673 353 z" fill="transparent" stroke="rgba(0,255,255,0.7)" stroke-width="2" stroke-linejoin="round" />
  <path d="M 673 366 L 678 366 L 678 386 L 673 386 z" fill="transparent" stroke="rgba(0,255,255,0.7)" stroke-width="2" stroke-linejoin="round" />
  <!--右侧小线段-->
  <path d="M 680 92 L 680 101 z" stroke="rgba(0,255,255,0.7)" stroke-width="2" stroke-linejoin="round" />
  <path d="M 680 123 L 680 134 z" stroke="rgba(0,255,255,0.7)" stroke-width="2" stroke-linejoin="round" />
  <path d="M 680 156 L 680 167 z" stroke="rgba(0,255,255,0.7)" stroke-width="2" stroke-linejoin="round" />
  <path d="M 680 189 L 680 200 z" stroke="rgba(0,255,255,0.7)" stroke-width="2" stroke-linejoin="round" />
  <path d="M 680 222 L 680 233 z" stroke="rgba(0,255,255,0.7)" stroke-width="2" stroke-linejoin="round" />
  <path d="M 680 255 L 680 266 z" stroke="rgba(0,255,255,0.7)" stroke-width="2" stroke-linejoin="round" />
  <path d="M 680 288 L 680 299 z" stroke="rgba(0,255,255,0.7)" stroke-width="2" stroke-linejoin="round" />
  <path d="M 680 321 L 680 332 z" stroke="rgba(0,255,255,0.7)" stroke-width="2" stroke-linejoin="round" />
  <path d="M 680 354 L 680 365 z" stroke="rgba(0,255,255,0.7)" stroke-width="2" stroke-linejoin="round" />
  <path d="M 680 387 L 680 400 z" stroke="rgba(0,255,255,0.7)" stroke-width="2" stroke-linejoin="round" />
  <!--三角-->
  <path d="M 5 5 L 20 5 L 5 20 z" fill="transparent" stroke-linejoin="round" stroke="rgba(0,255,255,0.7)" stroke-width="2" />
</svg>

使用

<img src="./svg.svg" alt="" style="display:block;width:690px;height:500px;background:#000">

效果 path.gif