javascript 45种缓动效果BY司徒正美

时间:2022-08-23 12:41:42

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帧,中国卡通24帧,赛车游戏60帧。
ease function 必需,缓动公式,参数为0~1之间的数。可参考我下面给出的45条公式。
onStart function 可选,在开始时执行。
onEnd function 可选,在结束时执行。

效果图:

javascript 45种缓动效果BY司徒正美

prototype流派的缓动公式,只需一个参数(增至45种)

<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=8">
<title>JavaScript 45种缓动效果</title>
<style type="text/css">
.taxiway {
width: 800px;
height: 100px;
background: #E8E8FF;
} .move {
width: 100px;
height: 100px;
background: #a9ea00;
} #panel {
float: left;
width: 810px
} #panel div {
float: left;
width: 88px;
border: 1px solid #;
height: 20px;
font-size: 11px;
} div.transition {
margin-top: 30px;
width: 200px;
height: 200px;
position: relative;
margin-bottom: 10px;
} div.transition div {
position: absolute;
height: 1px;
width: 1px;
background: #;
} div.transition span {
display: block;
position: absolute;
border-bottom: 1px solid #dadada;
font-size: 10px;
color: #;
width: 200px;
left: 0px;
} div.transition div#indicator {
position: absolute;
background-color: #a9ea00;
height: 200px;
top: 0px;
left: 0px;
} div.transition div#marker {
background-color: #f00;
height: 6px;
width: 6px;
border-radius: 3px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
left: 0px;
margin-bottom: -3px;
margin-left: -3px;
} div.transition div#label {
background: transparent;
color: #ABD474;
font-size: 20px;
height: 20px;
width: 200px;
text-align: center;
top: 80px;
left: 0px;
z-index: -;
}
</style>
<script type="text/javascript">
var getCoords = function(el) {
var box = el.getBoundingClientRect(),
doc = el.ownerDocument,
body = doc.body,
html = doc.documentElement,
clientTop = html.clientTop || body.clientTop || ,
clientLeft = html.clientLeft || body.clientLeft || ,
top = box.top + (self.pageYOffset || html.scrollTop || body.scrollTop) - clientTop,
left = box.left + (self.pageXOffset || html.scrollLeft || body.scrollLeft) - clientLeft
return {
'top': top,
'left': left
};
};
var getStyle = function(el, style) {
if(!+"\v1") {
style = style.replace(/\-(\w)/g, function(all, letter) {
return letter.toUpperCase();
});
var value = el.currentStyle[style];
(value == "auto") && (value = "0px");
return value;
} else {
return document.defaultView.getComputedStyle(el, null).getPropertyValue(style)
}
}
var tween = {
easeInQuad: function(pos) {
return Math.pow(pos, );
},
easeOutQuad: function(pos) {
return -(Math.pow((pos - ), ) - );
},
easeInOutQuad: function(pos) {
if((pos /= 0.5) < ) return 0.5 * Math.pow(pos, );
return -0.5 * ((pos -= ) * pos - );
},
easeInCubic: function(pos) {
return Math.pow(pos, );
},
easeOutCubic: function(pos) {
return(Math.pow((pos - ), ) + );
},
easeInOutCubic: function(pos) {
if((pos /= 0.5) < ) return 0.5 * Math.pow(pos, );
return 0.5 * (Math.pow((pos - ), ) + );
},
easeInQuart: function(pos) {
return Math.pow(pos, );
},
easeOutQuart: function(pos) {
return -(Math.pow((pos - ), ) - )
},
easeInOutQuart: function(pos) {
if((pos /= 0.5) < ) return 0.5 * Math.pow(pos, );
return -0.5 * ((pos -= ) * Math.pow(pos, ) - );
},
easeInQuint: function(pos) {
return Math.pow(pos, );
},
easeOutQuint: function(pos) {
return(Math.pow((pos - ), ) + );
},
easeInOutQuint: function(pos) {
if((pos /= 0.5) < ) return 0.5 * Math.pow(pos, );
return 0.5 * (Math.pow((pos - ), ) + );
},
easeInSine: function(pos) {
return -Math.cos(pos * (Math.PI / )) + ;
},
easeOutSine: function(pos) {
return Math.sin(pos * (Math.PI / ));
},
easeInOutSine: function(pos) {
return(-. * (Math.cos(Math.PI * pos) - ));
},
easeInExpo: function(pos) {
return(pos == ) ? : Math.pow(, * (pos - ));
},
easeOutExpo: function(pos) {
return(pos == ) ? : -Math.pow(, - * pos) + ;
},
easeInOutExpo: function(pos) {
if(pos == ) return ;
if(pos == ) return ;
if((pos /= 0.5) < ) return 0.5 * Math.pow(, * (pos - ));
return 0.5 * (-Math.pow(, - * --pos) + );
},
easeInCirc: function(pos) {
return -(Math.sqrt( - (pos * pos)) - );
},
easeOutCirc: function(pos) {
return Math.sqrt( - Math.pow((pos - ), ))
},
easeInOutCirc: function(pos) {
if((pos /= 0.5) < ) return -0.5 * (Math.sqrt( - pos * pos) - );
return 0.5 * (Math.sqrt( - (pos -= ) * pos) + );
},
easeOutBounce: function(pos) {
if((pos) < ( / 2.75)) {
return(7.5625 * pos * pos);
} else if(pos < ( / 2.75)) {
return(7.5625 * (pos -= (1.5 / 2.75)) * pos + .);
} else if(pos < (2.5 / 2.75)) {
return(7.5625 * (pos -= (2.25 / 2.75)) * pos + .);
} else {
return(7.5625 * (pos -= (2.625 / 2.75)) * pos + .);
}
},
easeInBack: function(pos) {
var s = 1.70158;
return(pos) * pos * ((s + ) * pos - s);
},
easeOutBack: function(pos) {
var s = 1.70158;
return(pos = pos - ) * pos * ((s + ) * pos + s) + ;
},
easeInOutBack: function(pos) {
var s = 1.70158;
if((pos /= 0.5) < ) return 0.5 * (pos * pos * (((s *= (1.525)) + ) * pos - s));
return 0.5 * ((pos -= ) * pos * (((s *= (1.525)) + ) * pos + s) + );
},
elastic: function(pos) {
return - * Math.pow(, - * pos) * Math.sin((pos * - ) * ( * Math.PI) / ) + ;
},
swingFromTo: function(pos) {
var s = 1.70158;
return((pos /= 0.5) < ) ? 0.5 * (pos * pos * (((s *= (1.525)) + ) * pos - s)) :
0.5 * ((pos -= ) * pos * (((s *= (1.525)) + ) * pos + s) + );
},
swingFrom: function(pos) {
var s = 1.70158;
return pos * pos * ((s + ) * pos - s);
},
swingTo: function(pos) {
var s = 1.70158;
return(pos -= ) * pos * ((s + ) * pos + s) + ;
},
bounce: function(pos) {
if(pos < ( / 2.75)) {
return(7.5625 * pos * pos);
} else if(pos < ( / 2.75)) {
return(7.5625 * (pos -= (1.5 / 2.75)) * pos + .);
} else if(pos < (2.5 / 2.75)) {
return(7.5625 * (pos -= (2.25 / 2.75)) * pos + .);
} else {
return(7.5625 * (pos -= (2.625 / 2.75)) * pos + .);
}
},
bouncePast: function(pos) {
if(pos < ( / 2.75)) {
return(7.5625 * pos * pos);
} else if(pos < ( / 2.75)) {
return - (7.5625 * (pos -= (1.5 / 2.75)) * pos + .);
} else if(pos < (2.5 / 2.75)) {
return - (7.5625 * (pos -= (2.25 / 2.75)) * pos + .);
} else {
return - (7.5625 * (pos -= (2.625 / 2.75)) * pos + .);
}
},
easeFromTo: function(pos) {
if((pos /= 0.5) < ) return 0.5 * Math.pow(pos, );
return -0.5 * ((pos -= ) * Math.pow(pos, ) - );
},
easeFrom: function(pos) {
return Math.pow(pos, );
},
easeTo: function(pos) {
return Math.pow(pos, 0.25);
},
linear: function(pos) {
return pos
},
sinusoidal: function(pos) {
return(-Math.cos(pos * Math.PI) / ) + 0.5;
},
reverse: function(pos) {
return - pos;
},
mirror: function(pos, transition) {
transition = transition || tween.sinusoidal;
if(pos < 0.5)
return transition(pos * );
else
return transition( - (pos - 0.5) * );
},
flicker: function(pos) {
var pos = pos + (Math.random() - 0.5) / ;
return tween.sinusoidal(pos < ? : pos > ? : pos);
},
wobble: function(pos) {
return(-Math.cos(pos * Math.PI * ( * pos)) / ) + 0.5;
},
pulse: function(pos, pulses) {
return(-Math.cos((pos * ((pulses || ) - .) * ) * Math.PI) / ) + .;
},
blink: function(pos, blinks) {
return Math.round(pos * (blinks || )) % ;
},
spring: function(pos) {
return - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * ));
},
none: function(pos) {
return
},
full: function(pos) {
return
}
}
var _ = function(id) {
return document.getElementById(id);
}
var transition = function(el) {
el.style.position = "absolute";
var options = arguments[] || {},
begin = options.begin, //开始位置
change = options.change, //变化量
duration = options.duration || , //缓动效果持续时间
field = options.field, //必须指定,基本上对top,left,width,height这个属性进行设置
ftp = options.ftp || ,
onEnd = options.onEnd || function() {},
ease = options.ease, //要使用的缓动公式
end = begin + change, //结束位置
startTime = new Date().getTime(); //开始执行的时间
(function() {
setTimeout(function() {
var newTime = new Date().getTime(), //当前帧开始的时间
timestamp = newTime - startTime, //逝去时间
delta = ease(timestamp / duration);
el.style[field] = Math.ceil(begin + delta * change) + "px"
if(duration <= timestamp) {
el.style[field] = end + "px";
onEnd();
} else {
setTimeout(arguments.callee, / ftp);
}
}, / ftp)
})()
}
if(typeof Array.prototype['max'] == 'undefined') {
Array.prototype.map = function(fn, thisObj) {
var scope = thisObj || window;
var a = [];
for(var i = , j = this.length; i < j; ++i) {
a.push(fn.call(scope, this[i], i, this));
}
return a;
};
Array.prototype.max = function() {
return Math.max.apply({}, this)
}
Array.prototype.min = function() {
return Math.min.apply({}, this)
}
}
var range = function(start, end) {
var _range = []
for(var i = start, l = end - start; i < l; i++) {
_range.push(i)
}
return _range
}
var draw = function(ease) {
var demo = _("transition");
demo.innerHTML = ""; //还原!
//***********绘制控制台********************
var values = range(, ).map(function(v) {
return tween[ease](v / ) * ;
}),
max = Math.max(, values.max()),
min = Math.min(, values.min());
if(min == max) {
min = ;
max = ;
}
var factor = / (max - min),
grid = '<span style="bottom:' + Math.round(( - min) * factor) + 'px">0</span>' +
'<span style="bottom:' + Math.round(( - min) * factor) + 'px">1</span>',
graph = range(, ).map(function(v) {
return '<div style="left:' + v + 'px;bottom:' + Math.round((values[v] - min) * factor) + 'px;height:1px"></div>';
}).join('') + '<div id="indicator" style="display:none">' +
'</div><div id="marker" style="display:none"></div><div id="label"></div>';
demo.innerHTML = grid + graph;
var indicator = _("indicator"),
marker = _("marker"),
label = _("label"),
demoTransition = function(pos) {
var value = tween[ease](pos);
indicator.style.display = "block";
marker.style.display = "block";
marker.style.left = Math.round(pos * ) + 'px';
marker.style.bottom = Math.round((value * - min) * factor) + 'px';
label.innerHTML = Math.round(pos * ) + 'px';
return value;
}
transition(indicator, {
field: "left",
begin: parseFloat(getCoords(demo).left),
change: ,
ease: demoTransition
})
}
window.onload = function() {
var panelHTML = function() {
var builder = [];
var _temp = 'Back Circ Cubic Expo Quad Quart Quint Sine'.split(' ');
var ease = _temp.map(function(v) {
return 'easeIn' + v;
});
ease = ease.concat(_temp.map(function(v) {
return 'easeOut' + v;
}));
ease = ease.concat(_temp.map(function(v) {
return 'easeInOut' + v;
}));
ease = ease.concat('blink bounce bouncePast easeFrom easeFromTo easeOutBounce easeTo elastic'.split(' '));
ease = ease.concat('flicker full linear mirror none pulse reverse sinusoidal spring swingTo swingFrom swingFromTo wobble'.split(' '))
for(var i = , l = ease.length; i < l; i++) {
builder.push("<div onclick='draw(this.innerHTML)'>");
builder.push(ease[i]);
builder.push("</div>");
}
return builder.join('');
}
var panel = document.createElement("div");
panel.id = "panel"
panel.innerHTML = panelHTML();
_("transition").parentNode.insertBefore(panel, _("transition").nextSibling);
}
</script>
</head> <body>
<div class="taxiway">
<div class="move" onclick="transition(this,{field:'left',begin:parseFloat(getCoords(this).left),change:700,ease:tween.bouncePast})"></div>
</div>
<div class="taxiway">
<div class="move" onclick="transition(this,{field:'width',begin:parseFloat(getStyle(this,'width')),change:300,ease:tween.spring})"></div>
</div>
<span class="clear"></span>
<h2>请点击下表的格子</h2>
<div id="transition" class="transition">
</div>
</body> </html>
 

javascript 45种缓动效果BY司徒正美的更多相关文章

  1. javascript的缓动效果

    这部分对原先的缓动函数进行抽象化,并结合缓动公式进行强化.成品的效果非常惊人逆天.走过路过不要错过. 好了,打诨到此为止.普通的加速减速是难以让人满意的,为了实现弹簧等让人眼花缭乱的效果必须动用缓动公 ...

  2. 《JavaScript 实战》:Tween 算法及缓动效果

    Flash 做动画时会用到 Tween 类,利用它可以做很多动画效果,例如缓动.弹簧等等.我这里要教大家的是怎么利用 Flash 的 Tween 类的算法,来做js的Tween算法,并利用它做一些简单 ...

  3. 过渡与动画 - 缓动效果&amp&semi;基于贝塞尔曲线的调速函数

    难题 给过渡和动画加上缓动效果是一种常见的手法(比如具有回弹效果的过渡过程)是一种流行的表现手法,可以让界面显得更加生动和真实:在现实世界中,物体A点到B点往往也是不完全匀速的 以纯技术的角度来看,回 ...

  4. animation js控制 缓动效果

    <!DOCTYPE html><html><head><meta charset="utf-8" /><title>缓动 ...

  5. WPF中ListBox滚动时的缓动效果

    原文:WPF中ListBox滚动时的缓动效果 上周工作中遇到的问题: 常规的ListBox在滚动时总是一格格的移动,感觉上很生硬. 所以想要实现类似Flash中的那种缓动的效果,使ListBox滚动时 ...

  6. &lbrack;ActionScript 3&period;0&rsqb; AS3 用于拖动对象时跟随鼠标的缓动效果

    package com.fylibs.components.effects { import flash.display.DisplayObject; import flash.events.Even ...

  7. Adobe Edge Animate –弹性的方块-使用tweenmax缓动效果

    Adobe Edge Animate –弹性的方块-使用tweenmax缓动效果 版权声明: 本文版权属于 北京联友天下科技发展有限公司. 转载的时候请注明版权和原文地址. 此前有Edge爱好者提出一 ...

  8. &lbrack; javascript &rsqb; 司徒正美的fadeOut-fadeIn效果&excl;

    首先感谢司徒正美的文章! 在司徒大神的博客看到一个简单的渐入渐出的效果.全然採用js实现. 例如以下: <!doctype html> <html dir="ltr&quo ...

  9. 软件项目技术点&lpar;1&rpar;——Tween算法及缓动效果

    AxeSlide软件项目梳理   canvas绘图系列知识点整理 Tween算法及缓动效果 软件里在切换步序时需要有过渡动画效果,从当前位置的画面缓动到目标位置的画面.动画效果可重新查看文章系列第一篇 ...

随机推荐

  1. conda安装包

    前面讲了有关conda改变镜像提高安装速度,这里来解决很多实用C写的酷,在Windows下不好安装的解决方案 1. 寻找wheel预编译文件 没有的话 2.使用conda命令安装 没有该包的话 3.实 ...

  2. susy 学习之进阶

    由于现在对susy的教程有限,只有官网指南性质的文档,然后就是w3cplus对她的翻译,所以我从零安装susy并调试项目到与从github上克隆susy项目同时进行,主要是为了参考susy放在git上 ...

  3. 在安卓下使用python连接蓝牙串口模块&lpar;HC-06&rpar;

    在安卓上安装Python: 请参考:https://github.com/kuri65536/python-for-android/blob/master/README.md下载程序文件需要访问 ht ...

  4. Python自动化运维之18、Python操作 MySQL、pymysql、SQLAchemy

    一.MySQL 1.概述 什么是数据库 ? 答:数据的仓库,和Excel表中的行和列是差不多的,只是有各种约束和不同数据类型的表格 什么是 MySQL.Oracle.SQLite.Access.MS ...

  5. Leetcode题解(八)

    26.Remove Duplicates from Sorted Array 题目 直接上代码,方法很简单: class Solution { public: int removeDuplicates ...

  6. FastDFS教程Ⅲ-文件服务器扩容

    1.简介     FastDFS文件服务器在设计时,为了支持大容量,存储节点(服务器)采用了分卷(或分组)的组织方式.存储系统由一个或多个卷组成,卷与卷之间的文件是相互独立的,所有卷的文件容量累加就是 ...

  7. 有关python下二维码识别用法及识别率对比分析

    最近项目中用到二维码图片识别,在python下二维码识别,目前主要有三个模块:zbar .zbarlight.zxing. 1.三个模块的用法: #-*-coding=utf-8-*- import ...

  8. Shell-16--函数

    函数的定义和调用放在一起(同一个shell)的好处是不会存在路径的问题:如果功能复杂,则应分开

  9. Exception in Spark

    1: Exception in thread "main" org.apache.spark.SparkException: org.apache.spark.streaming. ...

  10. R语言之正则表达式

    常见与正则表达式相关的函数: grep(pattern, x, ignore.case = FALSE, perl = FALSE, value = FALSE, fixed = FALSE, use ...