javascript中的缓动效果实现程序

常见的动画有四种类型,介绍一下:
  linear:线性动画,即匀速
  easeIn:速度从小到大,即淡入
  easeOut :速度从大到小,即淡出
  easeInOut:开始时速度从小到大,结束时速度从大到小,即淡入淡出

其实说到缓动,就不得不提Robert Penner,他发明了N多缓动公式,举个例子

我还是解释一下吧:

  设当前变化量为X,则
  t / d = X / c,所以X = c * t / d,然后X + b就可以获得当前属性值

再看一个稍复杂的:
 
这个有淡入效果,也就是说动画开始时,值的变化量从小到大。
可以发现两者唯一的区别就是 t / d 和 (t /= d) * t,刚才说了t / d是一个>=0 && <=1的比值,暂取名为a,而(t /= d) * t就相当于Math.pow(a, 2)。

为什么要平方呢?

1. 首先a >= Math.pow(a, 2)是肯定的
2. 每次调用函数时,t / d 这个比值也是匀速变大的,比如第1次调用时是0.1(平方0.01),第2次调用时是0.2(平方0.04)等,那第10次调用时,肯定是1没错吧,这时候 c * 1 + b,动画就到此结束了
3. 第2点证明了比值越小,值的变化量就越小,比值越大,值的变化量就越大,如果不用平方而是三次方,那淡入效果就更明显了。

样式、结构及公共函数如下:

代码如下:

<style>
        #container {width:500px;height:100px;border:1px #d1d1d1 solid;position:relative;}
        #drag {width:100px;height:100px;background:#369;position:absolute;left:0;top:0;}
    </style>
<div id="container">
<div id="drag"></div>
</div>

<script type="text/javascript">
        function $(id) {
            return typeof id == 'string' ? document.getElementById(id) : id;
        }
        function getStyle(el,styleProp){
            return el.currentStyle ? el.currentStyle[styleProp] : document.defaultView.getComputedStyle(el,null).getPropertyValue(styleProp);
        }
    </script>

首先,从最简单的入手:设定开始位置和结束位置及步长,每次增加固定的值,直至终止条件


代码如下:

var timer = null;
        var begin = 0, end = 400, step = 5;
        var drag = $("drag");
        function run() {
            if((iLeft = parseInt(getStyle(drag,"left"))) < end){
                drag.style.left = iLeft + step + "px";
            }else{
                clearInterval(timer);
            }
        }
        var timer = setInterval(run, 20);

上面这种方法是匀速,每次运动的距离是固定的,下面来看另外一种实现方式:

代码如下:

var timer = null;
        var begin = 0, end = 400;
        var drag = $("drag");
        function run() {
            if((iLeft = parseInt(getStyle(drag,"left"))) < end){
                var step = Math.ceil((400 - iLeft)/7);
                drag.style.left = iLeft + step + "px";
            }else{
                clearInterval(timer);
            }
        }
        var timer = setInterval(run, 20);

上面这种方式是通过当前的位置距离目标的距离来计算此次位移的步长
在flash中有专门处理缓动的类tween,转化为javascript的代码为:

代码如下:

var Tween = {
 Linear: function(t,b,c,d){ return c*t/d + b; },
 Quad: {
  easeIn: function(t,b,c,d){
   return c*(t/=d)*t + b;
  },
  easeOut: function(t,b,c,d){
   return -c *(t/=d)*(t-2) + b;
  },
  easeInOut: function(t,b,c,d){
   if ((t/=d/2) < 1) return c/2*t*t + b;
   return -c/2 * ((--t)*(t-2) - 1) + b;
  }
 },
 Cubic: {
  easeIn: function(t,b,c,d){
   return c*(t/=d)*t*t + b;
  },
  easeOut: function(t,b,c,d){
   return c*((t=t/d-1)*t*t + 1) + b;
  },
  easeInOut: function(t,b,c,d){
   if ((t/=d/2) < 1) return c/2*t*t*t + b;
   return c/2*((t-=2)*t*t + 2) + b;
  }
 },
 Quart: {
  easeIn: function(t,b,c,d){
   return c*(t/=d)*t*t*t + b;
  },
  easeOut: function(t,b,c,d){
   return -c * ((t=t/d-1)*t*t*t - 1) + b;
  },
  easeInOut: function(t,b,c,d){
   if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
   return -c/2 * ((t-=2)*t*t*t - 2) + b;
  }
 },
 Quint: {
  easeIn: function(t,b,c,d){
   return c*(t/=d)*t*t*t*t + b;
  },
  easeOut: function(t,b,c,d){
   return c*((t=t/d-1)*t*t*t*t + 1) + b;
  },
  easeInOut: function(t,b,c,d){
   if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
   return c/2*((t-=2)*t*t*t*t + 2) + b;
  }
 },
 Sine: {
  easeIn: function(t,b,c,d){
   return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
  },
  easeOut: function(t,b,c,d){
   return c * Math.sin(t/d * (Math.PI/2)) + b;
  },
  easeInOut: function(t,b,c,d){
   return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
  }
 },
 Expo: {
  easeIn: function(t,b,c,d){
   return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
  },
  easeOut: function(t,b,c,d){
   return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
  },
  easeInOut: function(t,b,c,d){
   if (t==0) return b;
   if (t==d) return b+c;
   if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
   return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
  }
 },
 Circ: {
  easeIn: function(t,b,c,d){
   return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
  },
  easeOut: function(t,b,c,d){
   return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
  },
  easeInOut: function(t,b,c,d){
   if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
   return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
  }
 },
 Elastic: {
  easeIn: function(t,b,c,d,a,p){
   if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
   if (!a || a < Math.abs(c)) { a=c; var s=p/4; }
   else var s = p/(2*Math.PI) * Math.asin (c/a);
   return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
  },
  easeOut: function(t,b,c,d,a,p){
   if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
   if (!a || a < Math.abs(c)) { a=c; var s=p/4; }
   else var s = p/(2*Math.PI) * Math.asin (c/a);
   return (a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b);
  },
  easeInOut: function(t,b,c,d,a,p){
   if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
   if (!a || a < Math.abs(c)) { a=c; var s=p/4; }
   else var s = p/(2*Math.PI) * Math.asin (c/a);
   if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
   return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
  }
 },
 Back: {
  easeIn: function(t,b,c,d,s){
   if (s == undefined) s = 1.70158;
   return c*(t/=d)*t*((s+1)*t - s) + b;
  },
  easeOut: function(t,b,c,d,s){
   if (s == undefined) s = 1.70158;
   return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
  },
  easeInOut: function(t,b,c,d,s){
   if (s == undefined) s = 1.70158;
   if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
   return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
  }
 },
 Bounce: {
  easeIn: function(t,b,c,d){
   return c - Tween.Bounce.easeOut(d-t, 0, c, d) + b;
  },
  easeOut: function(t,b,c,d){
   if ((t/=d) < (1/2.75)) {
    return c*(7.5625*t*t) + b;
   } else if (t < (2/2.75)) {
    return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
   } else if (t < (2.5/2.75)) {
    return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
   } else {
    return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
   }
  },
  easeInOut: function(t,b,c,d){
   if (t < d/2) return Tween.Bounce.easeIn(t*2, 0, c, d) * .5 + b;
   else return Tween.Bounce.easeOut(t*2-d, 0, c, d) * .5 + c*.5 + b;
  }
 }
}

其中每种缓动方式中对应3种类型
easeIn:从0开始加速的缓动;
easeOut:减速到0的缓动;
easeInOut:前半段从0开始加速,后半段减速到0的缓动
参数说明:
t:当前时间
b:初始值
c:变化量
d:持续时间
调用方式:

代码如下:

var timer = null;
        var b=0,c=400,d=100,t=0;
        var drag = $("drag");
        function run() {
            drag.style.left = Math.ceil(Tween.Circ.easeInOut(t,b,c,d)) + "px";
            if(t<d){
                t++;
            }else{
                clearInterval(timer);
            }
        }
var timer = setInterval(run, 20);

时间: 2012-12-27

javascript 45种缓动效果 非常酷

参数 类型 说明 el element 必需,为页面元素 begin number 必需,开始的位置 change number 必需,要移动的距离 duration number 可选,缓动效果持续时间,默认是500ms.建议取300~1000ms. field string 必需,要发生变化的样式属性.请在top,left,bottom,right,width与height中选择. ftp number 可选,每秒进行多少帧动画,默认50帧,保证流畅播放.一些参考资料,日本动画1秒36帧,中

javascript简易缓动插件(源码打包)

要求如下: 可以开始.暂停(线性.非线性tween都支持).继续.结束 支持多个样式并行 最好不依赖于某个框架下运行 文件尺寸越小越好 他找了一下现有的一些插件或者库,鲜有能满足或者比较均衡的,我在这个要求下,写了一个比较简陋的动画组件,基本满足了这个需求.先上代码 在线演示:http://demo.jb51.net/js/2012/animate/打包下载:animate_jquery.rarhtml部分: 复制代码 代码如下: <!DOCTYPE html> <html> &l

JS轮播图中缓动函数的封装

轮播图的根本其实就是缓动函数的封装,如果说轮播图是一辆跑动的汽车,那么缓动函数就是它的发动机,今天本文章就带大家由简入繁,封装属于自己的缓动函数~~ 我们从需求的角度开始,首先给出一个简单需求: 1.我想让页面中的一个盒子从开始的位置匀速向右运动到200px的地方,该怎么实现? 分析: 1)我们需要知道盒子在哪个地方,这个可以通过offsetLeft属性去获取: 2)要让盒子匀速运动,对于js肯定需要setInterval了: 3)要让盒子向右边跑起来?那就是需要不停改变盒子与左边起始点的距离,

JavaScript Tween算法及缓动效果第1/2页

我这里要教大家的是怎么利用flash的Tween类的算法,来做js的Tween算法,并利用它做一些简单的缓动效果. Tween Tween类型: Linear Quadratic Cubic Quartic Quintic Sinusoidal Exponential Circular Elastic Back Bounce ease类型: easeIn easeOut easeInOut /* 算法来源:http://www.robertpenner.com/easing/ */ var Tw

让div运动起来 js实现缓动效果

本文实例为大家分享了js实现缓动效果的具体代码,供大家参考,具体内容如下 var tween = { linear:function(t,b,c,d){ return c*t/d + b; }, easeIn:function(t,b,c,d){ return c * ( t /= d ) * t + b; }, strongEaseIn:function(t,b,c,d){ return c * ( t /= d ) * t * t * t * t + b; }, strongEaseOut:

js实现带缓动动画的导航栏效果

话不多说,请看实例代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <style type="text/css"> ul,li { padding: 0; margin: 0; } li { list-style: none; } #box{ height: 48px; width: 900px; bac

JS+HTML5手机开发之滚动和惯性缓动实现方法分析

本文实例讲述了JS+HTML5手机开发之滚动和惯性缓动实现方法.分享给大家供大家参考,具体如下: 1. 滚动 以下是三种实现方式: 1) 利用原生的css属性 overflow: scroll div id= parent style = overflow:scroll; divid='content'内容区域/div /div Notice: 在android 有bug, 滚动完后会回退到最顶端的内容区域,解决办法是使用后两种方式实现 2)js 编程实现 思路:对比手指在屏幕上移动前后位置变化

js判断手机和pc端选择不同执行事件的方法

本文实例讲述了js判断手机和pc端选择不同执行事件的方法.分享给大家供大家参考.具体如下: 判断是否为手机: function isMobile(){ var sUserAgent= navigator.userAgent.toLowerCase(), bIsIpad= sUserAgent.match(/ipad/i) == "ipad", bIsIphoneOs= sUserAgent.match(/iphone os/i) == "iphone os", bI

JS限定手机版中图片大小随分辨率自动调整的方法

实例如下: <script type="text/javascript"> var ObjImg = jQuery(".Dy_Content img"); for (var i = 0; i < ObjImg.length; i++) { loadImage(ObjImg.eq(i)); } function loadImage(Obj) { var b_width = 320; var img = new Image(); img.src = j

js HTML5手机刮刮乐代码

手机刮刮乐HTML5代码, 使用原型prototype扩展了一个clearArc 清除圆内像素的功能, 此功能未完成扇形清除功能, 此外,在清除圆内的像素时,还有点瑕疵,右边和下边还不够圆滑,有明显的齿状.如果你找到修复方法请一定要告诉我哟.不过此清除方法用于刮刮乐已经完全满足需求了. <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="view

AngularJS中使用HTML5手机摄像头拍照

1. 项目背景 公司开发一个网站,在做用户头像修改的时候领导提到增加一个由摄像头拍照实现修改头像的功能.因为我们网站是基于Html5进行开发,所以就直接采用H5来实现拍照.起初觉得这个功能很简单,但是做的时候才发现并不是那么简单的. 这是在AngularJs中成功实现调用摄像头拍照并截图上传的例图: 2. 如何调用摄像头 $scope.photoErr = false; $scope.photoBtnDiable = true; var mediaStream = null,track = nu

html5手机触屏touch事件介绍

HTML5中新添加了很多事件,但是由于他们的兼容问题不是很理想,应用实战性不是太强,所以在这里基本省略,咱们只分享应用广泛兼容不错的事件,日后随着兼容情况提升以后再陆续添加分享. 今天为大家介绍的事件主要是触摸事件: touchstart:触摸开始的时候触发 touchmove:手指在屏幕上滑动的时候触发 touchend:触摸结束的时候触发 而每个触摸事件都包括了三个触摸列表,每个列表里包含了对应的一系列触摸点(用来实现多点触控): touches:当前位于屏幕上的所有手指的列表. targe

js+html5实现可在手机上玩的拼图游戏

本文实例讲述了js+html5实现可在手机上玩的拼图游戏.分享给大家供大家参考.具体如下: 手机版的拼图.pc上用Chrome 或者 Firefox var R=(function(){ /*右边菜单*/ function fa(){ if(mo.style.right!='0px'){ mo.style.right='0px'; mco.rcss('','cmck'); }else{ mo.style.right='-100px'; mco.rcss('cmck',''); } } on(mc

JS实现文字向下滚动完整实例

本文实例讲述了JS实现文字向下滚动的方法.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: <!DOCTYPE> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>京东.淘宝晒单</title> <style> @charset "

Android+Html5混合开发仿微信朋友圈

开发之前 大约从去年开始吧, 也可能是前年 Html5好像火得不得了, 不得了...总能从网上听说到 XXX混合开发, 为了紧跟潮流(虽然有点儿晚了), 咱们也看看Android+Html5混合开发是怎样的! 今天带来的案例是微信的朋友圈, 因为我觉得是微信把H5给"捧红了". 不过丑话说在前头, 咱们的仿朋友圈可是"低仿", 只是把混合开发的大致流程说说, 界面可能不堪入目...见谅.. 开发环境 Android Studio 2.2.2 JDK1.7 API 2

javascript+html5实现仿flash滚动播放图片的方法

本文实例讲述了javascript+html5实现仿flash滚动播放图片的方法.分享给大家供大家参考.具体如下: html部分: <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="move.js" type="text/jav