今天,小学生以自己浅薄的见地,在前辈大能的基础上写这篇文章,希望给大家打开一扇窥探JavaScript(以下简称JS)动画的窗户。

JS如何制造出动画效果?

  结合浏览器提供的 setInterval 或 setTimeout API,高频改变DOM元素的一些属性,即可创造一个肉眼可见的动画效果。一个看起来非常流畅的JS动画除了需要良好的变换算法外,与其执行宿主也是非不开的。程序写得再好,如果浏览器过于老旧,电脑CPU性能低下,也会出现卡顿,甚至卡死。

  执行一个动画函数对于浏览器来说是个苦差,设置动画一帧为多长时间才能既流畅又不损耗性能呢?浏览器不会傻到进行一个DOM操作,就去渲染一次页面。它会把一个周期内所有的DOM操作整合起来,统一进行一次渲染。这个周期大约在16.7ms左右,不同浏览器间会有几毫秒的差异。SetTimeout的第二个参数设置为1000/60是比较合乎情理的做法。不过了解过SetTimeout运行机制的都会清楚,这个时间并不可靠,其根据实际情况会有些许甚至相当大的延迟。那么有没有这样一个API?我不想知道你浏览器到底多久渲染一次,反正你渲染的时候给我的动画执行一帧就行了。答案是有,requestAnimationFrame,可以让函数随着浏览器渲染执行,并且执行时机是可靠的。注意,这个方法在现在浏览器及IE10+才被支持。

  现在可以封装起一个简单的requestAnimationFrame,下面的例子中将会使用到它。

window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();

  更加详细的封装可以在张鑫旭的博客中看到:张鑫旭:requestAnimFrame。下面让我们继续。

动画函数的编写

  有了requestAnimationFrame,下面该考虑一下如何让写动画函数了。一般来说我们会给出一个毫秒级的during值,限制这个动画必须要在这个时间内完成。下面以实现一个小球从离页面左侧100px处匀速运动到800px处为例,编写一个动画函数:戳我查看DEMO

            var ele = document.getElementById("block");
var start = Date.now();//获取动画开始的时间。
var during = 1000; //此动画要在1秒内执行完。
var p=0;//动画完成度 从0-1;
requestAnimationFrame(function f(){
if(p>=1){ ele.style.left="800px";}//如果发现动画已经执行完,将元素置到终点。
else{
p=(Date.now()-start)/during;
ele.style.left=100+700*p+"px"; //从100px开始,匀速向右移动,共移动700px;
requestAnimationFrame(f);
}
})

  上面函数中有一个关键变量:p,即percentage,我们可以称它为动画的完成度,它是根据当前时间计算得出的,并且从动画开始后,会从0~1匀速渐变。当其为1时,表示整个动画执行完毕。在这个函数中,让p乘以要运动的长度700,便会得到一个0-700匀速变化的值,将其加上开始的100,便可模拟小球从100px处匀速移动到800px处。

  设想一下,假如上面红色标出的运动方程改为“ele.style.left=100+700*p*p+"px"”呢?p以二次方渐增,小球向右移动的速度会越来越快。是的,稍加修改便可实现一个匀加速运动的小球。

  下面,我们就是要针对p来做文章。

Tween算法及缓动效果

  下面我将列举一些常用的缓动算法,根据这些算法去修改上面匀速运动函数的运动方程,即可实现很赞的动画效果。

  1. 2次方缓动:  p*p
  2. 3次方缓动:  p*p*p
  3. 4次方缓动:  p*p*p*p
  4. 5次方缓动:  p*p*p*p*p
  5. 正弦曲线缓动:  Math.sin(p*Math.PI/2)
  6. 指数曲线缓动:  Math.pow(2,10*(p-1))
  7. 圆形曲线缓动:  Math.sqrt(1-(p-1)*(p-1))
  8. 超范围三次方:  p*p*(2.70158*p-1.70158)

  验证一下吧,比如我现在想实现一个小球向右运动,有一个向左蓄力的动画,我只要把第一个demo的运动方程改为“ele.style.left=100+700*p*p*(2.70158*p-1.70158)+"px"”就行了,看看效果吧:戳我查看DEMO

  其实,每种缓动算法都可以进化为三种缓动方式,分别为ease-in(先慢后快),ease-out(先快后慢),ease-in-out(先慢后快再慢)。

  以2次方缓动为例,它本身就是一个匀加速的过程,所以ease-in就是p*p。其ease-out为-(p*(p-2))。关于缓动方式,像阳光一样在他的博客中有更加详细的解释:JavaScript动画、运动算法详细解释与分析

  接下来要放大招了,关于缓动的整合DEMO,戳我吧

JS动画可以做什么?

  除了上面的缓动效果,利用常见的数学公式还可以实现一些周期性运动效果,例如小球匀速圆周运动,小球匀速简谐振动等,如果感兴趣请猛戳DEMO

  那么JS动画可以做什么呢?这就需要发挥我们的个人想象力了,上面的DEMO大部分都在操控单一的属性,比如left,让DOM元素发生位移。事实上在运动方程中,元素的任何style都可以被渐变。试想一下,设置一个DOM元素的opacity从0~1进行2次方缓动,便是一个简单的jQuery fadeOut函数;让一个DOM元素高度从无到有,便是一个简单的jQuery slideDown函数。更加不要忘记的是,在动画过程中不仅仅可以操作一项属性,这为动画带来了无限的可能性,事情变得越来越有趣了:DEMO:一个从小到大变化的球

  再试想一下,使用CSS3属性,例如box-shadow,transform,作出的效果必将会更加绚丽。

总结

  上面提到使用CSS3属性,其实如果这个浏览器支持CSS3属性的话,其实可以考虑完全使用CSS3实现一个动画。CSS3自有Animation动画属性,可以简单快捷地实现酷炫的动画效果,并且可以启用GPU加速。美中不足的是仅现代浏览器支持,而JS实现动画胜在可以兼容低版本浏览器。

  (作者于2015年6月19号增加)上面将JavaScript动画与CSS3动画的比较并不是特别严谨,更严谨的说法请移步我的博客:实现了一个百度首页的彩蛋——CSS3Animation简介

  动画仅仅是JS操作DOM魅力之冰山一角,而数学与计算机总是能碰撞出耀眼的火花。继续学习JS吧,这是一门神奇的语言,同时也应该了解一些数学知识,往往能够为解决事情带来捷径。

  (完)

JavaScript动画知多少?的更多相关文章

  1. 梅须逊雪三分白,雪却输梅一段香——CSS动画与JavaScript动画

    CSS动画并不是绝对比JavaScript动画性能更优越,开源动画库Velocity.js等就展现了强劲的性能. 一.两者的主要区别 先开门见山的说说两者之间的区别. 1)CSS动画: 基于CSS的动 ...

  2. javascript动画系列第三篇——碰撞检测

    前面的话 前面分别介绍了拖拽模拟和磁性吸附,当可视区域内存在多个可拖拽元素,就出现碰撞检测的问题,这也是javascript动画的一个经典问题.本篇将详细介绍碰撞检测 原理介绍 碰撞检测的方法有很多, ...

  3. javascript动画系列第一篇——模拟拖拽

    × 目录 [1]原理介绍 [2]代码实现 [3]代码优化[4]拖拽冲突[5]IE兼容 前面的话 从本文开始,介绍javascript动画系列.javascript本身是具有原生拖放功能的,但是由于兼容 ...

  4. Javascript动画效果(三)

    Javascript动画效果(三) 前面我们已经介绍了速度动画.透明度动画.多物体运动和任意值变化,并且我们在Javascript动画效果(二)中介绍到我们封装了一个简单的插件雏形,接下来我们对前面的 ...

  5. Javascript动画效果(一)

    Javascript动画效果(一) 前面我们介绍了Javascript的回到顶部效果,今天呢,我们对Javascript动画做进一步的研究.在这篇博文中我们只介绍简单的匀速运动.简单的缓冲运动和简单的 ...

  6. Javascript动画效果(二)

    Javascript动画效果(二) 在前面的博客中讲了简单的Javascript动画效果,这篇文章主要介绍我在改变之前代码时发现的一些问题及解决方法. 在前面的多物体宽度变化的例子中,我们给其增加代码 ...

  7. Javascript动画效果(四)

    Javascript动画效果(四) 前面我们自己写了一个小小的关于js动画的插件,下面我们来使用之前的框架来完成我们想要的动画效果.我们经常在淘宝网中看到,鼠标经过某一图片时,该图片有从上滚出而又从下 ...

  8. 给力的轻量级JavaScript动画框架 - jsMorph

    jsMorph 是一个独立的轻量级 JavaScript 动画框架,可以用它来操纵多个 HTML 元素的样式,实现动画效果.此框架会自动检测起始位置.转换单位.调整渲染的速度,以此来获得更流畅的渲染体 ...

  9. 10 个顶级 JavaScript 动画框架推荐

    使用JavaScript可以做出一些引人注目的动画效果,但通常不太容易实现.本文为你整理了10个非常优秀的JavaScript动画框架,使用它们你可以轻松实现动画效果.1. RaphaëlRaphaë ...

随机推荐

  1. TODO:macOS上ThinkPHP5和Semantic-UI集成

    TODO:macOS上ThinkPHP5和Semantic-UI集成 1. 全局安装 (on OSX via homebrew)Composer 是 homebrew-php 项目的一部分 2. 把X ...

  2. 利用Oracle RUEI+EM12c进行应用的“端到端”性能诊断

    概述 我们知道,影响一个B/S应用性能的因素,粗略地说,有以下几个大的环节: 1. 客户端环节 2. 网络环节(可能包括WAN和LAN) 3. 应用及中间层环节 4. 数据库层环节 能够对各个环节的问 ...

  3. 流程开发Activiti 与SpringMVC整合实例

    流程(Activiti) 流程是完成一系列有序动作的概述.每一个节点动作的结果将对后面的具体操作步骤产生影响.信息化系统中流程的功能完全等同于纸上办公的层级审批,尤其在oa系统中各类电子流提现较为明显 ...

  4. 个人网站对xss跨站脚本攻击(重点是富文本编辑器情况)和sql注入攻击的防范

    昨天本博客受到了xss跨站脚本注入攻击,3分钟攻陷--其实攻击者进攻的手法很简单,没啥技术含量.只能感叹自己之前竟然完全没防范. 这是数据库里留下的一些记录.最后那人弄了一个无限循环弹出框的脚本,估计 ...

  5. C#制作简易屏保

    前言:前段时间,有个网友问我C#制作屏保的问题,我瞬间懵逼了(C#还可以制作屏保!).于是我去查阅相关资料,下面把C#如何制作屏保的过程及我学习过程的心得也记录下来,希望对需要的人能有帮助. 基本思路 ...

  6. Winserver2012下mysql 5.7解压版(zip)配置安装

    一.安装 下载mysqlzip版本mysql不需要运行可执行文件,解压即可,下载zip版本mysqlmsi版本mysql双击文件即可安装,相对简单,本文不介绍此版本安装 配置环境变量打开环境变量配置页 ...

  7. Idea下用SBT搭建Spark Helloworld

    没用过IDEA工具,听说跟Eclipse差不多,sbt在Idea其实就等于maven在Eclipse.Spark运行在JVM中,所以要在Idea下运行spark,就先要安装JDK 1.8+ 然后加入S ...

  8. 端盘子的服务生到月薪一万五的IT精英,你能相信吗

    一直以来,我都觉得自己不是一个有故事的人. 以前的我,是个乖宝宝,对父母言听计从,特别内向,甚至一度感觉到自卑.不上学之后,我干过送货员,去工地除泥搬砖,当过油漆工,去过工厂,还去饭店当过端盘子的服务 ...

  9. 我的MYSQL学习心得(十) 自定义存储过程和函数

    我的MYSQL学习心得(十) 自定义存储过程和函数 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心 ...

  10. 【Knockout.js 学习体验之旅】(1)ko初体验

    前言 什么,你现在还在看knockout.js?这货都已经落后主流一千年了!赶紧去学Angular.React啊,再不赶紧的话,他们也要变out了哦.身旁的90后小伙伴,嘴里还塞着山东的狗不理大蒜包, ...