前言

动画成果始终是人机交互的一个十分重要的局部,动画成果的引入,会让交互变得更加敌对,让用户取得更加愉悦的体验。而随着市场环境变动,手机性能越来越好,网速越来越快,以及用户视觉效果要求越来越高,作为一名网页开发者,动画也是一个必会的技能。由此本文和大家分享下动画方面的技术实践经验。

动画的造成

多张不同的图像连在一起就会变成了动静的图像。在网页端的世界里,浏览器在视觉暂留工夫内,连续不断的逐帧输入图像。每一帧输入一张图像,造成了用户视觉效果中的动画。那么怎么高效的通过一帧帧输入间断晦涩的动画,是有很多种动画技术能够都能够实现的。

动画技术

上面以当今支流的动画技术,分成四个局部给大家介绍下,别离为纯CssLottie库Svga库Creatjs库

一、纯CSS

1.1 Animation动画属性次要联合@keyframes规定来创立动画。

上面以语音喇叭声稳定效为例:
两头的小圆点是始终存在的,第一条和第二条线都是1/4的圆弧,别离距离0.2s去循环显示暗藏。

.second {    animation: fadeInOut 1s infinite 0.2s;}.third {   animation: fadeInOut 1s infinite 0.4s;}@keyframes fadeInOut {  0% {    opacity: 0;    /*初始状态 透明度为0*/  }  100% {    opacity: 1;    /*结尾状态 透明度为1*/  }}

咱们个别用阶跃函数step来做帧动画。
上面是linearstep的具体案例:

https://codepen.io/huihui/pen/ExPKbdj

学生成Sprite图片,再挪动X轴地位造成帧动画。

1.2 Transform属性利用于元素的2D或3D转换。该属性容许咱们对元素进行旋转、缩放、歪斜、挪动、透视以及应用矩阵函数。别离为rotatescaleskewtranslateperspective以及matrix。还能够通过transform-origin用来确定中心点的地位为X、Y、Z,默认值:50% 50% 0。
这里有个很好的例子来演示Transform属性:https://c.runoob.com/codedemo/3391

上面以翻牌动效为例,次要是通过透视perspective属性来实现:

要达到图中第一组翻牌的成果。首先设置transform-style: preserve-3d,使被转换的子元素保留其3D转换。如果不加透视间隔perspective,则会为第三组翻牌中的成果,扁平没有Z轴的立体感。其次增加了透视间隔后,如果Z轴雷同,三个卡片是会有重叠的景象,如第二组翻牌中的成果。最初特意给卡片一加大了Z轴间隔。这样通过透视,如果Z轴间隔越大,卡片就看上去越小。能够用scale放大了卡片一

.card-board{  perspective: 800;}.board-item-wrap1{  transform: scale(1.1) translateZ(-100px);}
提醒:个别用transform: translateZ(0),开启3D引擎,触发GPU减速,让网页动画更晦涩。

1.3 Transition属性是用来设置动画过渡成果的,能够设置动画的过渡工夫和延迟时间。还能够增加动画函数animation-timing-function,其默认值为ease。可用贝塞尔曲线来做为动画速度曲线,举荐一个贝塞尔曲线的可视化网址:cubic-bezier,


以地图页的动画为例:
品牌岛屿的挪动成果用了ease,因为前面的品牌须要含糊,设置了较晚含糊的贝塞尔曲线

transition: transform 1s ease,filter 1s cubic-bezier(.06,.45,.82,1.34);

https://cubic-bezier.com/#.06,.45,.82,1.34

1.4 Js动画事件监听:
动画事件有:

animationstart - CSS动画开始后触发

animationiteration- CSS 动画反复播放时触发

animationend - CSS动画实现后触发

过渡事件有:

transitionend- 该事件在 CSS 实现过渡后触发。

留神:transitionend存在个问题.如果transition中,变换的属性有多个,就会触发屡次。比方如果同时设置宽高的过渡成果(transition:width:.2s,height:.2s),那么transitionend事件就会触发2次。

2秒隐没提示框为例:

动画完结2秒后暗藏,用animationEnd事件来监听。

兼容性:
下面4个事件都存在兼容性问题,在Android5下或Ios9.3下都须要加webkit前缀能力兼容,例如animationstart事件在Android5下须要用webkitAnimationStart

兼容性这块自己封装了插件jdyfe-eventployfill,原理是用createElement创立一个元素然而不插入页面Dom,查找style中是否有动画事件,来作为webkit的兼容判断
应用办法

import { janimationstart, janimationiteration, janimationend, jtransitionend } from'jdyfe-eventPloyfill'    ...    dom.addEventListener(janimationstart, ()=>{})    dom.addEventListener(janimationiteration, ()=>{})    dom.addEventListener(janimationend, ()=>{})    dom.addEventListener(jtransitionend, ()=>{})    ...

二、Lottie

airbnb提供的开源动画库Lottie

反对多版本,React NativewebiOSAndroid 版本

用矢量图导出。

在浏览器中生成的是svg标签,不会失真

案例为:
https://codepen.io/airnan/pen/MPmQQB

var svgContainer = document.getElementById('svgContainer')var animItem = bodymovin.loadAnimation({  wrapper: svgContainer,//div的id  animType: 'svg'  loop: true,  path: 'https://labs.nearpod.com/bodymovin/demo/markus/halloween/markus.json'})

更多Lottie案例:https://codepen.io/collection/nVYWZR/

Lottie还和京东的JDReact框架联合,推出了JDLottieLoadingViewJDLottieView组件。其中JDLottieLoadingView次要是显示加载中的动效,会默认援用loading动画款式。JDLottieViewLottieJDReact上的封装,用法不变。

案例代码如下:

<JDLottieLoadingView    autoSize={false}     source={"loading.json"}/><JDLottieView    autoPlay={true}    autoSize={true}    style={{width: 100, backgroundColor: 'black'}}    source={require('./animations/LottieWalkthrough')}    progress={0}    loop={true}/>

三、Svga

SVGA 是一种跨平台的开源动画格局,集成 svga player 之后可间接应用,装置svgaplayerweb包即可,

反对多版本,兼容 iOS / Android / Flutter / Web 多个平台的动画格局

反对位图和矢量图

在浏览器中生成的是canvas标签

案例代码如下:

import * as SVGA from 'svgaplayerweb'function AniSvga(props) {  useEffect(() => {    var player = new SVGA.Player('#demoCanvas1')    var parser = new SVGA.Parser('#demoCanvas1') // Must Provide same selector eg:#demoCanvas IF support IE6+    parser.load('./plugin/mengniu.svga', function(videoItem) {        player.setVideoItem(videoItem)        player.startAnimation()    })    return ()=>{      player.clear()    }  }, [])  return (    <div className="jdyfe-svgaPage">      <div id="demoCanvas1" ></div>    </div>  )}export default AniSvga

svga在线预览:https://svga.io/svga-preview.html

某些Android操作系统短少Blob反对,所以须要自行添加Blob Polyfill

<script src="//cdn.bootcss.com/blob-polyfill/1.0.20150320/Blob.min.js"></script>

四、Createjs

CreateJS是基于HTML5开发的一套模块化的工具库。
基于这些库,能够十分快捷地开发出基于HTML5的游戏、动画和交互利用。

4.1 EaselJS

EaselJS提供了JavaScript库,可轻松操作HTML5 Canvas元素。

能够绘制Stage舞台、Container容器和Sprite精灵的大小地位等,还提供很多事件能够做交互,很适宜纯互动游戏制作。
精灵能够用TexturePacker 软件来生成雪碧图,导出Createjsjson文件。

4.2 TweenJs

TweenJs次要是调整动画属性,例如

target.alpha = 1createjs.Tween.get(target).wait(500).to({alpha:0, visible:false}, 1000).call(handleComplete)function handleComplete() {        //突变实现执行}
这个突变将会先期待0.5秒,突变指标的alpha属性从0到1,并且visible属性从true变为false,这个过程用时1秒,最初调用handleComplete函数。
4.3 SoundJs

SoundJs次要用来加载解决音频的。

暂停,复原 声音

管制声音的音量,静音

监听声音实例中的事件,如实现,循环,或失败事件

 createjs.Sound.alternateExtensions = ["mp3"] createjs.Sound.on("fileload", this.loadHandler, this) createjs.Sound.registerSound("path/to/mySound.ogg", "sound") function loadHandler(event) {     // 这会引发针对每个已注册的声音。     var instance = createjs.Sound.play("sound")  // 施展应用ID。也能够应用残缺的源门路或event.src。     instance.on("complete", this.handleComplete, this)     instance.volume = 0.5 }
4.4 PreloadJS

PreloadJS是一个用来治理和协调相干资源加载的类库,它能够帮忙你事后加载相干资源。比照本人写监听load事件来确认实现加载,PreloadJS更不便,并且反对预加载多种类型的数据,例如:图片、文件、音频、数据等等。
PreloadJS次要是用URL. createObjectURL 创立了Blob对象,而后赋值给URL,移除的时候用 URL.revokeObjectURL办法移除Blob对象。所以会在network中看到Blob对象。

import createjs from 'jdyfe-createjs'const loader = new createjs.LoadQueue(true)loader.loadManifest([bgAry[0], ...imgAry])loader.on('complete', function () {       console.log('complete')//全副加载实现})loader.on('fileload', function (e) {       console.log('fileload---', e.target.progress)//进度条})

案例

createjs官网不反对npm形式应用,咱们用webpack从新打包生成了一个umd模块jdyfe-createjs,可供大家下载和应用。

上面案例蕴含了下面说的4个模块,也用到了jdyfe-createjs,具体可看:Belly跑步案例

Happy coding .. :)

相干链接

https://developer.mozilla.org/en-US/docs/Web/API/Animation/play

http://www.createjs.cc/src/docs/tweenjs/classes/CSSPlugin.html

原文地址