最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • SVG基础及其动画应用浅析

    正文概述 掘金(网易云音乐大前端团队)   2021-06-23   469

    一、我们为什么使用svg

    1. 和高清png来做个对比

      SVG基础及其动画应用浅析 SVG基础及其动画应用浅析

      继续对比

      SVG基础及其动画应用浅析 SVG基础及其动画应用浅析

      同样高清的质地,矢量图不畏惧放大,体积小。这里要说明一点就是,因为 SVG 中保存的是点、线、面的信息,与分辨率和图形大小无关,只是跟图像的复杂程度有关,所以图像文件所占的存储空间通常会比 png 小。

    2. 优化 SEO 和无障碍的利器,因为 SVG 图像是使用XML(可扩展标记语言【英语:Extensible Markup Language,简称:XML】标记指计算机所能理解的信息符号,通过此种标记,计算机之间可以处理包含各种信息的文章等)来标记构建的,浏览器通过绘制每个点和线来打印它们,而不是用预定义的像素填充某些空间。这确保 SVG 图像可以适应不同的屏幕大小和分辨率。

    3. 由于是在 XML 中定义的,SVG 图像比 JPG 或 PNG 图像更灵活,而且我们可以使用 CSS 和 JavaScript 与它们进行交互。SVG 图像设置可以包含 CSS 和 JavaScript。在 react、vue 这种数据驱动视图的框架下,对于 SVG 操作就更加如鱼得水了。(下文会跟大家分享一些小的 SVG 动画在我们项目中的实践)

    4. 在运用层面上,SVG 提供了一些图像编辑效果,比如屏蔽和剪裁、应用过滤器等等。并且SVG 只是文本,因此可以使用 GZip 对其进行有效压缩。

    二、了解 SVG 常用元素及其使用

    2-1. 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">
    <svg  width="300" height="300" viewBox="0, 0, 100, 200"  xmlns="http://www.w3.org/2000/svg" version="1.1">
        <circle cx="100" cy="50" r="49" stroke="black"
        stroke-width="2" fill="red" />
    </svg>
    

    SVG基础及其动画应用浅析

    这就是我们从设计手里拿到的 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">
    <svg width="300" height="300" viewBox="0, 0, 100, 200"  xmlns="http://www.w3.org/2000/svg" version="1.1">
    </svg>
    

    这是99% SVG 都会表现出来的形式和及一些属性,其中包含 width、height 这两个视口属性,viewBox 视图属性,xmlns 属性。我们一行一行看

    <!DOCTYPE html>
    

    SVG 的文档声明方式(划重点:一般如果 SVG 运用在 HTML 里,我们可以不写这样的文档声明,但如果是单独的 SVG 文件,那就需要写了,否则浏览器可能会不认识)

    <?xml version="1.0" standalone="no"?>
    

    我们看到的 standalone 属性是在表明该 xml 声明是否是独立的,如果不是即 standalone="no",那后面会引入外部的 dtd ,如第二行第三行所示。 version 属性用于指明 SVG 文档遵循规范的版本。 它只允许在根元素<svg> 上使用。 它纯粹是一个说明,对渲染或处理没有任何影响。虽然它接受任何数字,但是只有1.0 和 1.1.这两个有效的选择。

    <svg width="300" height="300" viewBox="0, 0, 100, 200"  xmlns="http://www.w3.org/2000/svg" version="1.1">
    </svg>
    
    • xmlns 属性是 SVG 的 XML 声明空间,这一部分类似于 HTML 中的 xmlns="www.w3.org/1999/xhtml"
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    
    • width & height 属性,可以理解成画布的大小。没错是画布的大小。举个例子:
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width=100 height="100">
        <circle cx="50" cy="50" r="49" stroke="black"
        stroke-width="1" fill="red" />
    </svg>
    

    SVG基础及其动画应用浅析

    当前这个 SVG 的画布大小是 100 * 100 的画布,我们画上一个半径为 49 再加 1 个单位的描边的圆。刚好撑满没毛病。所见即所得。那我们试一下改变 width 和 height。发现

    <svg  
        style="background:#007fff"
        xmlns="http://www.w3.org/2000/svg"
        version="1.1"
        width="300"
        height="300">
        <circle cx="50" cy="50" r="49" stroke="black"
        stroke-width="1" fill="red" />
    </svg>
    

    SVG基础及其动画应用浅析

    我们可以看到蓝色区域就是我们定的 width 和 height ,图形部分依然是那个圆没有变化。这样我们就理解了 width 和 height 的作用。

    • viewBox 属性,接下来配合 viewBox 这个属性我们再来修改下代码
    <svg 
        style="background:#007fff"
        xmlns="http://www.w3.org/2000/svg"
        version="1.1"
        <!-- viewBox定义-->
        viewBox="0, 0, 100, 100"
        width="300"
        height="300" >
        <circle cx="50" cy="50" r="49" stroke="black"
        stroke-width="1" fill="red" />
    </svg>
    

    SVG基础及其动画应用浅析

    我们可以看到蓝色区域大小不变,而我们的圆却变得很大,大到撑满了整个画布。没错,你的想法是对的,所谓 viewBox 这个属性可以理解为我们微信聊天时的截图操作。viewBox 属性的四个参数,前两个表示截图起点,后面两个表示截图终点,均是以左上角定点为原点。最后把截图再拉伸放在 SVG 画布上,就成了我们上面看到的 SVG 了。下面我们再修改一次 viewBox 成 0, 0, 50, 50 帮助理解

    <svg 
        style="background:#007fff"
        xmlns="http://www.w3.org/2000/svg"
        version="1.1"
        viewBox="0, 0, 50, 50" 
        width="300"
        height="300" >
        <circle cx="50" cy="50" r="49" stroke="black"
        stroke-width="1" fill="red" />
    </svg>
    

    SVG基础及其动画应用浅析

    所以整个逻辑大概是这样的

    SVG基础及其动画应用浅析

    2-2.path 标签

    在 SVG 里,你可以把 path 看成是最基本的绘制元素,正因为它是最基本的,万变不离其宗,他能演化出各种复杂的绘制效果。所以 path 是最基本也是最复杂的绘制元素。

    path 的基础属性和其代表的意义

    我们知道一个 path 标签,最重要的属性是 d 属性,它是一组指令和参数的集合。在 d 属性的值里,我们能看到一堆非常复杂的指令字符串。

    <path d="
        M73.8616812,68.8664775
        L74.5015359,74.5939423
        L68.1746283,71.7969507
        C66.2299599,72.4159872 64.1377269,72.7711218 61.9444643,72.7711218
        C51.9719158,72.7711218 43.8883163,65.7823167 43.8883163,57.1611168
        C43.8883163,48.5399169 51.9719158,41.5511118 61.9444643,41.5511118
        C71.9164005,41.5511118 80,48.5399169 80,57.1611168
        C80,61.8286883 77.6181486,66.006419 73.8616812,68.8664775" id="Fill-1" fill="#FFFFFF"></path>
    

    SVG基础及其动画应用浅析

    其实完全不用觉得恶心,这里继续掰开揉碎了说

    • d 属性里的那些指令
    指令参数含义
    Mx y将画笔移动到点(x,y)Lx y画笔从当前的点绘制线段到点(x,y)Hx画笔从当前的点绘制水平线段到点(x,y0),y0 表示绘制前画笔所在 y 轴坐标,也就是 y 轴不变Vy画笔从当前的点绘制竖直线段到点(x0,y),x0 表示绘制前画笔所在 x 轴坐标,也就是 x 轴不变Arx ry x-axis-rotation large-arc-flag sweep-flag x y画笔从当前的点绘制一段圆弧到点(x,y)Cx1 y1, x2 y2, x y画笔从当前的点绘制一段三次贝塞尔曲线到点(x,y)Sx2 y2, x y特殊版本的三次贝塞尔曲线(省略第一个控制点)Qx1 y1, x y绘制二次贝塞尔曲线到点(x,y)Tx y特殊版本的二次贝塞尔曲线(省略控制点)Z无参数绘制闭合图形,如果 d 属性不指定Z命令,则绘制线段,而不是封闭图形

    以上是 path 路径中的全部指令,其中加粗部分为常用基础指令,相对来说比较好理解。每个指令都有对应的小写指令。例如M 10,10 有对应的 m 10,10 。大写代表绝对位置,所谓绝对位置即对 SVG 画布左上角原点的绝对。小写代表相对位置,所谓相对位置是以当前画笔所在位置进行定位

    • A(arc)画弧指令
    A rx ry x-axis-rotation large-arc-flag sweep-flag x y
    
    <svg width="100%" height="100%">
        <path d="M0 0 A 45 45, 0, 0, 0, 45 45 L 45 0 Z" fill="green"/>
    </svg>
    

    SVG基础及其动画应用浅析

    画了张图,帮助理解

    SVG基础及其动画应用浅析

    按照图中的步骤,我们可以画出两个圆都满足,于是再看到其中A指令有三个0我们没有解释,回顾下 A 指令,并结合这张图我们可以更好的理解

    A rx ry x-axis-rotation large-arc-flag sweep-flag x y

    SVG基础及其动画应用浅析

    • 贝塞尔曲线

    关于贝塞尔曲线,张老师这篇文章已经说得非常清楚了,说得非常易懂深度理解 SVG 路径,推荐给希望更多了解 svg 路径的同学

    2-3.基本图形

    基本图形这块相对比较好理解,我们直接一张表总结下,不做过多赘述

    图形标签模板含义
    矩形< rect ><rect x="60" y="10" rx="10" ry="10" width="30" height="30"/>x:起点横坐标,y:起点纵坐标,rx:倒角x轴方向半径,ry:倒角x轴方向半径,width:宽度,height:高度圆形< circle ><circle cx="100" cy="100" r="50" fill="#fff"></circle>cx:圆心横坐标,cy:圆心纵坐标,r:半径椭圆< ellipse ><ellipse cx="75" cy="75" rx="20" ry="5"/>cx:椭圆心横坐标,cy:椭圆心纵坐标,rx:椭圆x轴方向半径,ry:椭圆y轴方向半径直线< line ><line x1="10" x2="50" y1="110" y2="150"/>x1,y1:起点,x2,y2:终点折线< polyline ><polyline points="60 110, 65 120, 70 115, 75 130, 80 125, 85 140, 90 135, 95 150, 100 145"/>每两个点以空格配对为一个坐标点,逗号隔开形成坐标集合。连成折线。多边形< polygon ><polygon points="50 160, 55 180, 70 180, 60 190, 65 205, 50 195, 35 205, 40 190, 30 180, 45 180"/>类似折线,不同的是,最后一个点会自动闭合第一个点,形成闭环。

    2-4.symbol标签

    symbol 标签是我们直播团队 icon 管理平台实现的核心技术点,它的作用说白话点就是相当于是一个元件,放在我们的工具箱里,就像下面这样:

    <svg class="svg-sprite">[工具箱]
    	<symbol id="icon-wave_add" viewBox="0 0 76 76"><path d="M38 0a4 4 0 014 4v30h30a4 4 0 110 8H41.999L42 72a4 4 0 11-8 0l-.001-30H4a4 4 0 110-8h30V4a4 4 0 014-4z" fill="currentColor" fill-rule="evenodd" opacity="none"></path></symbol>
    	<symbol id="icon-time" viewBox="0 0 10 10"><path d="M5 0a5 5 0 110 10A5 5 0 015 0zm0 1.5a.5.5 0 00-.5.5v3.02l.008.088a.5.5 0 00.238.343L7.02 6.794l.082.039a.5.5 0 00.603-.215l.039-.082a.5.5 0 00-.216-.603L5.5 4.735V2l-.008-.09A.5.5 0 005 1.5z" fill="rgba(153,153,153,1)" fill-rule="evenodd" class=" "></path></symbol>
    	<symbol id="icon-wave_delete" viewBox="0 0 40 40"><g fill="none" fill-rule="evenodd"><circle fill="#000" opacity="0.2" cx="20" cy="20" r="20"></circle><path stroke="#FFF" stroke-width="4" stroke-linecap="round" d="M13 13l14 14M27 13L13 27"></path></g></symbol>
    </svg>
    

    放一份就可以无限引用。当它在工具箱里时,我们是看不到它的(页面不会渲染它),只有我们使用了<use>标签对其进行实例引用时,我们才可以在页面上看到它:

    <use xlink:href="#icon-time"></use>
    

    SVG基础及其动画应用浅析

    我们使用<symbol> + <use>的组合,来实现svg雪碧图,是不是觉得很easy。

    有的同学会有疑问,symbol 标签和 g 标签,放在 defs 里仿佛都是在定义一个可复用的模块,那么两者之间有什么区别呢?在我的理解里,symbol 相对于g 标签最大的不同在于 symbol 可以给可复用代码块增加视图属性和视口属性。方便在服用的时候直接调整到合适的运用(打印)尺寸。

    三、svg 动画及其运用

    3-1.svg 动画概要

    技术描述备注
    SMIL很强大且纯粹的标签化动画虽然 Chrome 45以后弃用了SMIL,但是依然支持,各大浏览器的支持度都挺好的CSSCSS 还只能实现简单的动画offset-path 的兼容性很差。css 动画不适合做交互性很强的动画JavaScript复杂动画就要用到 JS 了,包括世面上的一些 SVG 动画库,也都是 JS 去实现的

    SVG 是基于 XML 的矢量图形描述语言,可以近似理解成 HTML,所以能和 JS 以及 CSS 进行交互。 特 别是 CSS,我们可以使用 CSS3 来对 SVG 做动画处理。但是要记住的是仅当 HTML 内联包含 SVG 文件 时,我们才可以使用 CSS 对其做样式开发。本文我们针对平时 CSS3 + HTML不容易实现, 而利用 SVG 可以快速简便实现的几种场景做相应介绍

    3-2.SVG 动画实践

    3-2-1、直线的变化

    下面这张图是一个 GIF 的 icon,体积大约是 156KB,压缩之后。

    SVG基础及其动画应用浅析

    如果我们用 SVG 去实现的话。应该怎么做呢。我们分为以下两种方式,亲测兼容性都 OK

    CSS+SVG 实现的代码实践

    基于 SMIL 实现的代码实践

    知识点1: SVG 中有很多属性我们是可以用 CSS 去描述的。在基于 CSS 动画三剑客(animation, transform, transition)的基础上。我们对一些属性进行控制,就达到我们想要的动画效果。下面两点值得说明:

    • transform:transform 有两种用法,一个是在 SVG 标签里写的 transform 属性、另一种是在 CSS 文件里写的 transform,他们有着本质的区别。
    <rect transform="rotate(45deg) ..."  ... />
    
    rect {
        transform: rotate(45deg)
    }
    /** 行内的 transform 属性,他的执行基点是在我们 svg 元素的左上角也就是 svg 的坐标原点。**/
    /** 而 CSS 的 transform 原点则在元素本身的中心点。**/
    
    • CSS可描述属性: 很多文章告诉我们 CSS 可以控制 SVG 去做动画,但是实际开发过程中我们会更想知道,到底哪些属性我们可以做css控制,这里给大家列出一些常用属性并且可以放心使用的属性
    CSS 可控属性名可实现场景
    理论上所有的显示属性,都可以使用 CSS 控制包括:比如 stroke-width、color、fill 等等 SVG 的显示属性大部分的显示样式动态变化x我们知道矩形有 x、y 属性,其含义是起始点,控制 x,我们可以动态控制矩形的X轴位移y控制 y,我们可以动态控制矩形的 Y 轴向位移cx<circle cx="100" cy="100" r="50" fill="#fff" />这是一个圆形,控制 cx 可以控制圆形(或者椭圆)的 X 轴位移cy控制 cy 可以控制圆形(或者椭圆)的 Y 轴位移rr 是圆的半径,控制 r 可以控制圆形的大小rxrx 是椭圆的 X 轴方向半径,控制 rx 可以控制椭圆的大小ryry 是椭圆的 Y 轴方向半径,控制 ry 可以控制椭圆的大小dpath 标签的 d 属性,控制 d 的路径信息,可以控制图形的变幻(d 属性在 safari 上是不支持 css 描述的。我们下文会详细的说明PS:如果各位看官们在日常开发中,不清楚该属性是否可以通过 css 去控制,这边给大家提供一个查询链接不支持 CSS 控制的 SVG 相关属性
     export default function App() {
       return (
         <div className="App">
           <svg width="100%" height="100%" viewBox="0 0 100% 100%">
             {[1, 2, 3, 4, 5].map((it, index) => (
               <line
                 key={index}
                 stroke="#000"
                 strokeWidth="2"
                 x1={15 + index * 5}
                 y1="8"
                 x2={15 + index * 5}
                 y2="22"
               >
                 <animate
                   attributeName="y1"
                   values="8; 15; 8"
                   dur="1s"
                   begin={`${(5 % (index + 1)) * 0.2}s`}
                   repeatCount="indefinite"
                 />
                 <animate
                   attributeName="y2"
                   values="22; 15; 22"
                   dur="1s"
                   begin={`${(5 % (index + 1)) * 0.2}s`}
                   repeatCount="indefinite"
                 />
               </line>
             ))}
           </svg>
         </div>
       );
     }
    

    那么 什么是 SVG 的 SMIL 呢?
    这里不想再对其做大篇幅的赘述,因为网上有很多文章都已经说得比较详细了SMIL 动画指栏、SVG SMIL animation 动画详解。 本文更想和大家交流的是在SMIL驱动和CSS驱动如何做选择的问题。
    虽然说早在 Chrome 45,chrome 就已经官宣要弃用 SMIL,但是到目前位置,各大浏览器厂商对它的支持度是这样的

    SVG基础及其动画应用浅析 Chrom 宣布弃用 SMIL 是因为要支持 CSS Animation 与 Web Animation 的发展,所以我们可以理解为当前是在一个过渡状态,确实有一些暂时CSS 还没法支持或者支持度很差的动画效果,SMIL 可以轻松完成。但是基于 web 动画技术发展的大趋势,还是建议我们 SVG 动画实现方案的选择优先级是CSS 驱动 -> JS 驱动(我们可以采用一些框架,文末会给大家推荐一些好用的框架) -> SMIL 驱动

    3-2-2、path 路径的变化(图形平滑变化)

    SVG基础及其动画应用浅析 SVG基础及其动画应用浅析

    CSS+SVG 实现的代码实践 Logo 变化

    基于 SMIL 实现的代码实践 Logo 变化

    CSS+SVG 实现的代码实践播放暂停

    基于 SMIL 实现的代码实践播放暂停

    知识点1: 通过对<path/> d 属性的控制,我们可以实现很多动画效果,对于 d 属性的控制目前有两种方式,一种是通过 CSS 控制,另一种是通过 SMIL 控制,但是目前由于 safari 不支持用 CSS 来描述<path>标签的 d 属性。所以在实现这种平滑的形状变形效果上不推荐使用 CSS。更加推荐使用SMIL或者第三方库去实现

    基于 CSS:

        path {
          transition: ease all 0.3s; // 就像对dom一样的对待svg
    
          &.play { //这里是播放状态下的<path />路径
            d: path("M 12,26 18.5,22 18.5,14 12,10 z M 18.5,22 25,18 25,18 18.5,14 z");
          }
    
          &.pause { //这里是播放状态下的<path />路径
            d: path(
              "M 12,26 16.33,26 16.33,10 12,10 z M 20.66,26 25,26 25,10 20.66,10 z"
            );
          }
        }
    

    基于 SMIL(即通过<animate>实现对<path> d 属性的动态控制):

      const pathMap = {
        from: "M 12,26 16.33,26 16.33,10 12,10 z M 20.66,26 25,26 25,10 20.66,10 z",
        to: "M 12,26 18.5,22 18.5,14 12,10 z M 18.5,22 25,18 25,18 18.5,14 z"
      };
      <svg class="icon" viewBox="0 0 120 120" width="400" height="400">
        <path
          d="M 12,26 16.33,26 16.33,10 12,10 z M 20.66,26 25,26 25,10 20.66,10 z"
          fill="#000000"
        >
          <animate
            attributeName="d"
            from={play ? pathMap.from : pathMap.to}
            to={play ? pathMap.to : pathMap.from}
            dur="0.3s"
            begin="indefinite" // 这里设置开始时间为无限以达到不自动播放的效果
            fill="freeze"
          />
        </path>
      </svg>
    

    以上两个 path 路径的切换,就可以带来这种平滑过渡的效果。

    SVG基础及其动画应用浅析

    知识点2:
    我们看到的图形变幻,都需要遵循一个原则就是点数对齐原则,什么意思呢?我们可以看下面的demo,五角星到 10 边形(多边形画的不好,抱歉...?)。,都是 10 个控制点到 10 个控制点的过度。所以效果平滑

    SVG基础及其动画应用浅析

    SVG基础及其动画应用浅析

    而下图的 10 个点到 3 个点就没有这种平滑的过渡效果了(当然现在很多的 SVG 动画框架已经解决了这个问题。见文末的框架推荐 )

    SVG基础及其动画应用浅析

    3-2-3、描边动画的应用

    SVG基础及其动画应用浅析

    SVG基础及其动画应用浅析

    CSS+SVG 实现的代码实践-星环

    CSS+SVG 实现的代码实践- LOGO 描边

    基于 SMIL 实现的代码实践-进度环

    知识点1:
    类似的描边动画我们可以拿来做很多效果,比如各种形状的进度条、比如文字的描边、比如霓虹灯流水灯光等等流动动画效果。而描边动画的核心点就在于 SVG 的两个显示属性分别是 stroke-dasharray、stroke-dashoffset,我们上文说了,几乎所有的显示属性都可以用 CSS 去控制,所以这种动画,建议使用 CSS 去开发。

    属性值举例描述支持范围
    stroke-dasharray1 3 4 4它的值是一个序列,可以传入多个值,分别指定描边短线的长度和描边线间距,多个值依次循环,如果传入3个值,类似于 stroke-dasharray: 1,2,3。则会自动复制一份再生效<circle>, <ellipse>, <line>, <mesh>, <path>, <polygon>, <polyline>, <rect> <altGlyph>, <altGlyphDef>, <altGlyphItem>, <glyph>, <glyphRef>, <textPath>, <text>, <tref>, <tspan>stroke-dashoffset10描边线段的起始位置距离图形绘制起点的偏移量。正负值可以决定顺时针还是逆时针走向跟stroke-dasharray一致

    设想一个场景,一个倒计时需要从 100 到 0,对应的视觉效果也就是从全描边到无描边。那么我们初始状态将 stroke-dasharray 的第一个值设为 2πr (周长),第二个值设也设为 2πr (周长)。那么我们会得到一个整圆。

    SVG基础及其动画应用浅析

    这时如果我们把圆展开就能看到这样的场景

    SVG基础及其动画应用浅析 所以要实现进度的动态变化其实有两种方案
    第一种是将stroke-dasharray的第一个值从2πr(周长)调整到0。原展开图中的黑色部分没有了(可以理解为变成了一个点如下图,看不见了),只剩下虚线部分是空白间隙了。

    第二种是将stroke-dashoffset的值从0调整到-2πr(或者增加到2πr)。对比第一张图成下图的样子
    SVG基础及其动画应用浅析

    知识点2:
    在实际开发中,我们会遇到一些比较复杂的图形需要做描边,这个时候我们没办法去得到它的周长是多少,这时候分两种场景处理。一种是在CSS里我们可以将stroke-dasharray的第二个值设置成一个非常大的数字,然后再去调整第一个值比如:

        path {
            stroke-dasharray: 0(调整到合适的值) 99999999999999
        }
    

    如果在js里我们需要动态去获取周长的话,SVG提供了原生的api可以去获取path的周长。

        const inPath = document.getElementById("inner-path");
        console.log(inPath.getTotalLength());
    

    ps:有些资料说该方法只能用于<path />,但是笔者亲测了在safair和chrome上,基本可以支持所有的基础图形以及<path />,但是<text />不支持,浏览器会报not a function。

    既然说到了getTotalLength(),那么顺带说下getPointAtLength()。getPointAtLength,顾名思义就是根据距离获取点坐标。意思就是根据到起始点的距离,获取该指定距离对应的点的坐标。坐标系原点为该图形的起始点。在一些指向型的动画上我们可能会运用到这个api。

    3-2-4、轨迹运动动画的应用

    SVG基础及其动画应用浅析

    基于SMIL实现的代码实践-轨迹运动

    {/* 我们将整个飞机图形元件用g标签包起 */}
    <g transform="translate(-100, -35) scale(0.1)">
      <path
        d="M164.485419 578.709313L196.274694 794.731891c0.722484 5.53904 8.188147 7.224835 11.078081 2.408278l75.860772-121.377234 740.063969-363.409219L164.485419 578.709313z"
        fill="#F68206"
      ></path>
      <path
        d="M2.167451 440.233302l159.668861 132.214487 857.828787-260.334901zM289.475071 679.375353l191.217309 153.407337 542.344309-518.743179z"
        fill="#FF9900"
      ></path>
      <path
        d="M204.222013 800.030103l125.23048-80.677328-48.888053-39.014111-76.342427 118.4873"
        fill="#D3650B"
      ></path>
      {/* 然后在这里,我们利用animateMotion,去做这个轨迹运动 */}
      <animateMotion
        path="M 0 450 Q 150 50 250 50 Q 350 0 400 50 Q 500 50 450 200 C 300 350 250 200 500 50 C 600 50 750 200 650 250 A 50 50 0 1 1 800 50 "
        begin="0s"
        rotate="auto"
        dur="20s"
        repeatCount="indefinite"
      />
    </g>
    

    这里我们用到了SMIL里的<animateMotion />,animateMotion里的path属性,我们也可以像这样去使用

        <defs>
            <path id="theMotionPath" d="xxx" />
        </defs>
        <animateMotion>
            <mpath xlink:href="#theMotionPath"/>
        </animateMotion>
    

    实际生产中,我们这种轨迹运动的需求,是建议使用SMIL去实现的,当然CSS也是有实现方案的《使用CSS offset-path让元素沿着不规则路径运动》。但是CSS的兼容实在不敢恭维,劝退一波。

    四、写在最后

    1、 建议将CSS动画用于无变形的过渡或简单动画。尤其是在硬件加速时。CSS不需要加载其他资源(一般指三方库),并且悬停时的小变换可以为交互带来更好的效果。特别是当你不需要3d、物理体感、或进行大量堆叠动画效果时建议选用CSS。另外,CSS方便调试也是很大的一个优势。

    2、对于较长的动画,开发时会变得非常复杂且需要花精力去调试,而CSS调整时间尺度很困难,尤其是当你需要操纵一些细微帧时,个人觉得SMIL更合适做有序的,复杂的堆叠动画群的场景。

    3、对于变形的动画,建议使用SMIL或者第三方库。推荐的比较优秀的三方库有以下几个。

    库名描述
    GSAP全称是GreenSock Animation Platform,以前流行用 flash 的时候,GSAP就叱咤江湖的存在,GSAP有两个版本一个是 flash 版本,一个是 javascript 版本,也就是我们说的 GSAP js。GSAP 速度快。GSAP专门优化了动画性能,使之实现和css一样的高性能动画效果;轻量与模块化;Snap.svg、SVG.js、Velocity.js这三个库一直会被开发者拿来对比,基本上会用jQuery,就会使用这三个库,也就是说入手友好,Snap.svg 更偏向于支持现代浏览器,所以它的体量也会小一些。对比 Snap.svg 来看 SVG.js ,SVG.js 的写法更加的清晰,使用时会有更好的体验,且自称提供接近完整的 SVG 规范覆盖。Snap.svg 风格就更像一个侠客,写起来会很潇洒但是不好读,Velocity 也很强大,简单易用、高性能、功能丰富anime.jsanime.js 虽然功能没有 GASP 强大,但是体积很乐观,gzip压缩完只有9kb左右,满足日常需求开发还是足够的D3Data-Driven Documents 顾名思义,更加适合用于创建数据可视化图形场景去使用

    4、如何使用 SMIL 进行硬件加速,使用 代替,并设置 x、y、z 值(z 为 0)。原理与 CSS 类似,这会将元素移到它自己的层,从而在其发生运动时不会重新绘制。

    参考资料

    • SVG 动画指栏(SMIL)
    • SVG 教程
    • CSS 支持的 SVG 属性查寻
    • 以及文章内提及的一些文章

    起源地下载网 » SVG基础及其动画应用浅析

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元