SVG-动画的一把好手

栏目: 后端 · 前端 · 发布时间: 5年前

内容简介:我们首先需要理解一下我们先设置一个宽高和viewBox的尺寸是相同的,明显显示正常。当我们同比例放大或缩小时,画布上的内容也是同比例放大或缩小。

我们首先需要理解一下 viewBox (画布上可以显示的区域)和 width/height 的关系。在canvas中我们若改变宽高,那么图像是可能发生扭曲的,但是svg不会,还是会以正常比例显示。

1、当宽高与尺寸比例相同

我们先设置一个宽高和viewBox的尺寸是相同的,明显显示正常。

<svg viewBox="0 0 200 100" width="200" height="100">
    <rect width="100" height="50" fill="#7dc5ff"></rect>
</svg>
复制代码
SVG-动画的一把好手

当我们同比例放大或缩小时,画布上的内容也是同比例放大或缩小。

SVG-动画的一把好手

2、当宽度比例不够时的表现

缩小宽度,这时候发现 rect 这个元素变小了,其实是画布以原始布局居中在 svg 中,其余的空间直接补充画布区域。

<svg viewBox="0 0 200 100" width="100" height="100">
    <rect width="100" height="50" fill="#7dc5ff"></rect>
</svg>
复制代码
SVG-动画的一把好手
SVG-动画的一把好手

3、当高度比例不够时的表现

当高度不够时也是同理。居中,补充画布区域。

<svg viewBox="0 0 200 100" width="200" height="50">
    <rect width="100" height="50" fill="#7dc5ff"></rect>
</svg>
复制代码
SVG-动画的一把好手

这时候,比如要做一个固定在底部的宽度100%的波浪,我们只需要将 width 设置为 100vw ,而 height 则为同比例,即1/5的宽度即可。

<svg viewBox="0 0 1000 200"></svg>
复制代码
svg{
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100vw;
    height: 20vw;
}
复制代码
SVG-动画的一把好手

听说SVG动画被CSS动画所代替?

虽然svg元素看起来属性非常多,且复杂,但是其实都比较好理解,且目前大部分都可以放到css中定义。

rect{
    width: 200px;
    height: 200px; 
    x: 50px;
    y: 50px;
    fill: #000;
    stroke: red;
}
path{
    d:path('M 0 0 L 100 100 Z');
}
复制代码

实践中发现d:path在css中定义时,IE版本均无法支持。

既然这些属性都可以在css中定义,那么动画做起来就so easy啦, transformanimation 大法用起来。

咦,听说svg自己也有做动画的属性呀,是的是的,但是SMIL已经被chrome弃用了(虽然说弃用了,但是用还是能用),chrome爸爸鼓励大家用css动画的方式来处理svg原来的动画方案。

SVG-动画的一把好手

当然,也不是说替代就替代的,我们一一看下,css动画是否可以代替原来的SMIL方案。

第一种,变动一个元素的数字属性

<svg width="300px" height="100px">
    <circle cx="0" cy="50" r="15" fill="blue" stroke="black" stroke-width="1">
        <animate attributeName="cx" from="0" to="100" dur="5s" repeatCount="indefinite" />
    </circle>
</svg>
复制代码

上面的 animate 元素的作用,翻译过来就是改变 circlecx 这个属性,从0到100,动画时间5s,重复次数无限次。

翻译成css就是下面的代码,完美无误。

circle{
    animation: circleMove 5s infinite;
}
@keyframes circleMove{
    0%{
        cx: 0;
    }
    100%{
        cx: 100px;
    }
}
复制代码

第二种,变形属性

transform 也是css的拿手好戏,想怎么变就怎么变。

<svg width="300px" height="100px">
   <rect x="0" y="50" width="15" height="34" fill="blue" stroke="black" stroke-width="1" transform="rotation">
        <animateTransform    
            attributeName="transform"
            begin="0s"
            dur="20s"
            type="rotate"
            from="0 60 60"
            to="360 100 60"
            repeatCount="indefinite" />
   </rect>
 </svg>
复制代码
rect{
    animation: rectMove 20s infinite;
}
@keyframes rectMove{
    0%{
        transform: rotate(0);
    }
    100%{
        transform: rotate(360deg);
    }
}
复制代码

第三种,颜色属性

css大哥表示太简单了,不讲了。

第四种,运动路径动画

尽管chrome46和opera33开始支持 css motion path 了,但是这一大片触目惊心的红,溜了溜了,还是先抱住SVG大哥的大腿。

SVG-动画的一把好手
SVG-动画的一把好手

svg的动画大戏

上述的几个svg动画虽然有svg的好处,但是很多情况下纯css也可以实现,但是下列这三种动画就是svg动画的拿手好戏了,需要这几个的时候祭出svg妥妥的。示例

  1. 描边动画
  2. 改变形状路径动画
  3. 沿着路径运动

描边动画

svg描边动画主要运用了svg特有的两个属性, stroke-dasharraystroke-dashoffset

stroke-dasharray : 该属性用于创建虚线:

stroke-dashoffset :指定每个实线线段的起始偏移量。正数从路径起始点向前偏移,负数则向后。

也就是说,获取到svg元素或者path的总长度之后,我们就可以做出一个描边绘制的动画。

<svg viewBox="0 0 300 300" width="300" height="300">
    <rect width="100" height="100" x="50" y="50"></rect>
</svg>
复制代码
rect{
  fill: transparent;
  stroke: #000;
  stroke-width: 4px;
  stroke-dasharray: 400 400; 
  stroke-dashoffset: -400px;
  animation: strokeMove 2s infinite linear;
}

@keyframes strokeMove {
  0%{
    stroke-dashoffset: -400px;
  }
  50%{
    stroke-dashoffset: 0;
  }
  100%{
    stroke-dashoffset: 400px;
  }
}
复制代码

stroke-dasharray: 400 400; :描边的是一段400实线+400透明的样式。如上,我们设置的是一个周长为400的长方形,那么前面400的实线段刚好填充了整个长方形。

stroke-dashoffset: -400px; :实线段往前偏移-400,也就是现在用来填充长方形的刚好是后面400的透明线段。改变该值就能实现一个简单的描边动画了。

SVG-动画的一把好手

描边动画其实应用很广,只要能把svg导出比较正常的路径,都可以通过 getTotalLength() 获取到长度,然后运用上面的原理,就能实现看起来很酷炫的描边效果了,比如描个logo、字形、科技效果都可以。

SVG-动画的一把好手

改变形状路径动画

svg形状都可以用path来写,例如下面的 rectpath 结果出来都是一个宽100高100,左上角位于(50,50)坐标点的正方形。

<svg viewBox="0 0 300 300" width="300" height="300">
  <rect width="100" height="100" x="50" y="50"></rect>
  <path d="M 50 50 L 150 50 L 150 150 L 50 150 Z"></path>
</svg>
复制代码

既然path可以在css中定义(除IE),那么就可以更改path来改变svg图片的形状,从而实现改变形状路径的动画。但是要注意一点,path的点改变前后要一致,不能多了或者少了。

<svg viewBox="0 0 300 300" width="300" height="300">
  <path class="path-change"></path>
</svg>
复制代码
.path-change{
  fill: rgba(74,152,255,0.8);
  animation: pathChange 4s infinite;
}

@keyframes pathChange{
  0%{
    d:path('M -100 100 C 200,-50 400,300 800,100 L 800 200 L -200 200 Z');
  }

  50%{
    d:path('M -100 100 C 200,180 450,0   800,100 L 800 200 L -200 200 Z');
  }

  100%{
    d:path('M -100 100 C 200,-50 400,300 800,100 L 800 200 L -200 200 Z');
  }
}
复制代码
SVG-动画的一把好手

沿着路径运动

这里的 animateMotion 定义的就是 text 中元素的动画的属性。

begin
dur
repeatCount
path

这样我们就能实现一个元素沿着特定路径运动的动画。

<svg viewBox="0 0 300 300" width="300" height="300">
  <text font-size="40" x="0" y="0" fill="pink">人
    <animateMotion path="M100 50 A 20 20 0 0 1 100 200 A 20 20 0 0 1 100 50" begin="0s" dur="3s" repeatCount="indefinite"/>
  </text>
  <path d="M100 50 A 20 20 0 0 1 100 200 A 20 20 0 0 1 100 50" fill="none" stroke="#000" stroke-width="4"/>
</svg>
复制代码
SVG-动画的一把好手

我们可以看到上图的人字一直是正立的状态,那么如果想要各自然地有种沿着地球转动的感觉呢,我们就需要实时改变该元素的旋转角度,这个很容易实现,只需要加上一个属性:

  • rotate :auto;表示自动跟随路径旋转
<svg viewBox="0 0 300 300" width="300" height="300">
  <text font-size="40" x="0" y="0" fill="pink">人
    <animateMotion path="M100 50 A 20 20 0 0 1 100 200 A 20 20 0 0 1 100 50" begin="0s" dur="3s" repeatCount="indefinite" rotate="auto"/>
  </text>
  <path d="M100 50 A 20 20 0 0 1 100 200 A 20 20 0 0 1 100 50" fill="none" stroke="#000" stroke-width="4"/>
</svg>
复制代码
SVG-动画的一把好手

小结

  1. 当svg的宽高比例与原画布比例不相同时,会保持 原比例居中 显示并补充空白处;
  2. SMIL动画 虽然已经被部分浏览器弃用,但目前还属于可使用状态,但建议如简单的属性变化,动画部分建议用css动画替代,但是 沿着特定路径动画 依然需要使用 animateMotion ,如果是简单的svg形状甚至可以直接用 html+css 代替;
  3. 描边动画形状改变动画沿着特定路径动画 都是目前css比较难以直接替代的一些动画操作,这几种类型的动画svg都是一把好手。

参考链接

  1. 超级强大的SVG SMIL animation动画详解
  2. chrome弃用了SVG?
  3. CSS的motion-path属性

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Essential C++中文版

Essential C++中文版

[美] Stanley B. Lippman / 侯捷 / 华中科技大学出版社 / 2001-8 / 39.80元

书中以4个面向来表现C++的本质:procedural(程序性的)、generic(泛型的)、object-based(个别对象的)、object-oriented(面向对象的),全书围绕着一系列逐渐繁复的程序问题,以及用以解决这些问题的语言特性。循此方式,读者不只学到C++的函数和结构,也会学习到它们的设计目的和基本原理。一起来看看 《Essential C++中文版》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

随机密码生成器
随机密码生成器

多种字符组合密码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具