svg 学习系列-波浪背景

前言

最近想作一个波浪滚动的背景,查询资料后发现使用 svg 能够作。本身动手实践了下,效果以下: css

实现

技术选择
首先看到这些波浪是由一些曲线来绘制成的,使用 css 能够经过 border-radius 设置各类角度来实现。可是想一想也挺麻烦的,svg 中的 path 能够知足咱们的需求。bash

path 使用

<path>元素是SVG基本形状中最强大的一个。 你能够用它建立线条, 曲线, 弧形等等。ide

也就是说能够经过 path 来画出你想要的图形,来看看如何经过 path 来画出一个简单的图形。svg

path元素的形状是经过属性d定义的,属性d的值是一个“命令+参数”的序列wordpress

例如性能

<svg width='300' height='300' version='1.1' xmlns='http://www.w3.org/2000/svg'>
    <path d="M0 0 L30 30" stroke="red"/>
    <circle cx="250" cy="180" r="5" fill="red"></circle>
    <circle cx="100" cy="100" r="5" fill="black"></circle>
</svg>
复制代码

从上图能够得知

  1. 与咱们场景的 X-Y 坐标轴不一样的是,Y轴的方向相反。也就是你的y值越大,点的位置越下面。
  2. 先无论 M, L 这些表明什么意思(后续会说),咱们须要知道的点是 M,L 这样大写的字母表示命令,后面跟着的是坐标。

经常使用命令

移动一个点
这里的xy是坐标的位置,关于大小写的差异M后面跟着的坐标是坐标轴中的绝对坐标位置,m跟着的是坐标轴中的相对位置,根上一个点有关动画

  1. M x y
  2. m dx dy (命令小写的写法)

划线
会在当前位置和新位置之间画一条线,这里的xy是坐标的位置ui

  1. L x y
  2. l dx dy 简写方式以下
  • H x 画水平线 horizontal
  • V y 画垂直线 vertical
  • Z 闭合曲线

练习:使用path画一个矩形spa

<svg class="move-wrap" height='300' version='1.1' xmlns='http://www.w3.org/2000/svg'>
        <path d="M0 0 H100 V100 H0 Z" stroke="red" fill="transparent"/>
</svg>
复制代码

绘制曲线

绘制平滑曲线的命令有三个,其中两个用来绘制贝塞尔曲线(C,Q),另一个用来绘制弧形或者说是圆的一部分(A)。3d

二次贝塞尔曲线

命令用Q来表示,当咱们选择一个点做为控制点后,画的曲线会分别和两端与控制点连线相切。能够简单的理解为,控制点控制了曲线的凸的程度

x1 y1 表示控制点的位置,x y 表示曲线终点的坐标。

<path d="M100 100 Q x1 y1, x y" 
stroke-width="10" stroke="black" fill="transparent"/>
复制代码

三次贝塞尔曲线
命令用C来表示,使用以下 前面两个值(120 120 ,160 120)表示两个控制点的位置。最后一个坐标180 100是曲线终点的坐标。

<path d="M100 100 C120 120,160 120,180 100" 
stroke-width="10" stroke="black" fill="transparent"/>
复制代码

S命令能够用来建立与前面同样的贝塞尔曲线
适用于三次曲线,二次贝塞尔曲线有一个差很少的T命令。

<path d="M0 150 C30 135,60 135, 90 150 S150 165,180 150 S240 135,270 150 V300 H0 Z" fill="rgba(0, 0, 50, .1)"  stroke-width="1"/>
复制代码

S240 135 S指令后面须要指定一个控制点,S命令自动补出一个对称的控制点,270 150 表示曲线最终点。

补全
获得两个正弦曲线,想法就是绘制多个这样波浪,每一个波浪以一个正弦为周期,向左滑动的动画无限循环。

<path d="M0 150 C30 130,60 130, 90 150 S150 170,180 150 S240 130,270 150 S330 170,360 150 V300 H0 Z" fill="rgba(0, 0, 50, .2)"  stroke-width="3"/>
复制代码

动画

SVG的动画元素是和SMIL开发组合做开发的。SMIL开发组和SVG开发组合做开发了SMIL动画规范,在规范中制定了一个基本的XML动画特征集合。SVG吸取了SMIL动画规范当中的动画优势,并提供了一些SVG继承实现。

指定动画应用的对象

  1. 经过 xlink:href="#id", animate 和 指定元素要属于同一个 svg 标签下。
<rect id="cool_shape" ... />

<animate xlink:href="#cool_shape" ... />
复制代码
  1. 嵌套在元素内
<rect id="cool_shape" ... >

  <animate ... />

</rect>
复制代码

须要应用动画的属性
经过 attributeName 来指定须要过渡的属性,可是它只能接收一个值,若是有多个值的时候须要使用多个 animate 标签来实现。

如移动一个圆点

<svg width='500' height='500' version='1.1' xmlns='http://www.w3.org/2000/svg'>
  <circle  cx="30" cy="30" r="5" fill="red">
    <animate dur="1s" attributeName="cx" to="130"/>
    <animate dur="1s" attributeName="cy" to="130"/>
  </circle>
</svg>
复制代码

经常使用属性

  • dur 持续时间 值:3s
  • fill 是否保留动画最后一帧 可选值:freeze/remove
  • begin 可选值: 2s/ click + 1s / 0s
  • restart 动画是否从新开始(出现于动画还在加载过程当中,是否运行它从新开始加载) 可选值:always/whenNotActive/never
  • repeatCount 值:2
  • keyTimes="0; 0.5; 0.8; 1" 指定 keyframe 对应的动画,配合 values 一块儿使用
// 若是 values 有多段值而 keyTimes 没有指定,那么每一个阶段都会被均分
<animate
    values="50; 490; 350; 450"
    keyTimes="0; 0.5; 0.8; 1"
    ... />
复制代码
  • calcMode 设置运动的速率 可选值:linear/paced/spline 具体要用可了解须要哪一个速率
  • additive 是否在原先的基础上累加 可选值:sum/replace
<svg width='500' height='500' version='1.1' xmlns='http://www.w3.org/2000/svg'>
  // 从 130 移动到 230
  <circle  cx="130" cy="30" r="15" fill="red">
    <animate dur="1s" attributeName="cx" to="230" restart="never" fill="freeze"></animate>
  </circle>
  // 从 130 移动到 360
  <circle  cx="130" cy="30" r="15" fill="green">
    <animate begin="1s" dur="1s" attributeName="cx" additive="sum" from="0" to="230"  restart="never" fill="freeze"></animate>
  </circle>
</svg>
复制代码
  • accumulate 在本身上一次动画结束到地方累加 可选值:sum/replace
<svg width='500' height='500' version='1.1' xmlns='http://www.w3.org/2000/svg'>
  // 第二次动画起点是 360 第三次是 460 
  <circle  cx="130" cy="30" r="15" fill="red">
    <animate accumulate="sum" dur="1s" attributeName="cx" to="230" repeatCount="3" fill="freeze"></animate>
  </circle>
</svg>
复制代码
  • transform 属性改变有专门的 animateTransform 元素 指定attributeName="transform" 而后经过设定 type :(可选值 translate/scale/rotate/skewX/skewY)
<animateTransform 
      xlink:href="#deepPink-rectangle"
      attributeName="transform" 
      attributeType="XML"
      type="rotate"
      from="0 75 75"
      to="360 75 75" 
      dur="2s"
      begin="0s"
      repeatCount="indefinite"
      fill="freeze" 
      />
复制代码

波浪动画

使用path 画出了波浪的样式,接下来使用 animateTransform 动起来。每次移动移动 180px 至关于画了2个正弦周期,每次动画到一个正弦周期而后回到圆点无限循环。为了让动画效果多样,能够添加多个波浪,而且每一个波浪的样式有些许不一样(速度、形状、透明度等)

<svg class="move-wrap" height='300' version='1.1' xmlns='http://www.w3.org/2000/svg'>
        <path d="M0 150 C30 130,60 130, 90 150 S150 170,180 150 S240 130,270 150 S330 170,360 150 V300 H0 Z" fill="rgba(0, 0, 50, .2)"  stroke-width="3">
          <animateTransform attributeName="transform" attributeType="XML" type="translate" from="0" to="-180" dur="3s" repeatCount="indefinite"></animateTransform>
      </path>
</svg>
复制代码

波浪背景图完整demo代码

最后

svg 在曲线以及曲线轨迹动画方面有这css没法实现的优点,给动画不少可能性,不知道它性能怎么样,无论了先学了再说吧。

参考
A Guide to SVG Animations (SMIL)

path

超级强大的SVG SMIL animation动画详解

深度掌握SVG路径path的贝塞尔曲线指令

相关文章
相关标签/搜索