一、JavaScript运动框架之速度版


1.1 运动框架的实现思路


运动,其实就是在一段时间内改变 left 、 right 、 width 、 height 、 opactiy 的值,到达目的地之后停止

  • 位移 top,left
  • 折叠 width,height
  • 淡入淡出 opacity
  • 时间有关系
    • setInterval
    • setTimeout
  • 用javascript直接获取行间样式很容易,但如果要获取非行间样式那我们只能借助函数了。我这里编写了一个名为getStyle的函数,专门处理取非行间的样式
1
2
3
function getStyle(obj,attr){
return getComputedStyle(obj)[attr]?getComputedStyle(obj)[attr]:obj.currentStyle[attr];
}

1.2 一些案例演示


1.2.1 运动之速

1
<div id="box"></div>
1
2
3
4
5
6
7
#box {
width: 100px;
height: 100px;
background: red;
position: relative;
left: 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var box = document.getElementById("box");
var speed = 0; //步长
var target = 600;
var timer = null;
timer = setInterval(function(){
var curr = parseInt(getStyle(box,"left")); //去除getStyle(box,"left")的单位
if(curr == target){
clearInterval(timer);
speed = 0;
alert("运动结束");
}else{
speed +=10;
box.style.left = speed + "px";
}
 
 
},1000/30);
 
//监控left的值的变化 怎么样拿到left的值
//alert(getComputedStyle(box)["width"]);
//alert(box.currentStyle["left"]);
// currentStyle --IE
// getComputedStyle -- 非IE
 
function getStyle(obj,attr){
return getComputedStyle(obj)[attr]?getComputedStyle(obj)[attr]:obj.currentStyle[attr];
}

在线演示

1.2.2 运动速度之封装1

1
<div id="ball"></div>
1
2
3
4
5
#ball {
width: 100px;
height: 100px;
background: blue;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var ball = document.getElementById("ball");
 
ball.onmouseover = function(){
//同时变换 用的最多
//move(this,"width",500,10);
//move(this,"height",500,10);
move(ball,{"width":400,"height":300},10);
}
ball.onmouseout = function(){
//move(this,"width",100,-10);
//move(this,"height",100,-10);
move(ball,{"width":100,"height":100},-10);
}
function move(obj,json,speed){
clearInterval(obj.timer);
var mark = true;
obj.timer = setInterval(function(){
for(var attr in json){
var curr = parseInt(getStyle(obj,attr));
var target = json[attr];
if(curr != target){
obj.style[attr] = curr+speed+"px";
mark = false;
}
}
if(mark){
clearInterval(obj.timer);
}
},1000/30);
}
 
 
function getStyle(obj,attr){
return getComputedStyle(obj)[attr]?getComputedStyle(obj)[attr]:obj.currentStyle[attr];
}
  • 需要注意的地方

    • 当需要两个动画的时候,会执行后面一个,解决办法如下,回调函数
    • 当需要两个以上的时候,需要考虑是否可写一行代码变换多个属性
    • 变换不一致的时候,定时器被提前清除

在线演示

1.2.3 运动速度之封装2–增加opacity
1
<div id="ball"></div>
1
2
3
4
5
6
7
8
9
#ball {
position: relative;
left: 0;
top: 0;
width: 100px;
height: 100px;
background: blue;
opacity: 1;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
var ball = document.getElementById("ball");
ball.onmouseover = function(){
move(ball,{"width":300,"height":300,"opacity":0.3});
}
// ball.onmouseout = function(){
// move(ball,{"width":100,"height":100},-10);
// }
function move(obj,json){
clearInterval(obj.timer);
var mark = true;
obj.timer = setInterval(function(){
for(var attr in json){
var curr = null;
var target = json[attr];
var speed = null;
if(attr == "opacity"){
curr = getStyle(obj,attr)*100;
speed = (target*100-curr)*0.15;
}else {
curr = parseInt(getStyle(obj,attr));
speed = (target - curr)*0.15;
}
speed = speed>0 ? Math.ceil(speed):Math.floor(speed);
if(curr != target){
if(attr == "opacity"){
obj.style[attr] = (curr+speed)/100;
}else {
obj.style[attr] = curr+speed+"px";
}
 
mark = false;
}
}
if(mark){
clearInterval(obj.timer);
}
},1000/30);
}
 
 
function getStyle(obj,attr){
return getComputedStyle(obj)[attr]?getComputedStyle(obj)[attr]:obj.currentStyle[attr];
}

在线演示

  • 需要注意的地方

    • 当需要两个动画的时候,会执行后面一个,解决办法如下,回调函数
    • 当需要两个以上的时候,需要考虑是否可写一行代码变换多个属性
    • 变换不一致的时候,定时器被提前清除
    • 速度speed不要写死

1.3 运动框架之应用

1.3.1 分享按钮
1
2
3
4
<div id="ball"></div>
<div id="box1">
<div id="box2">分享到</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
var box1 = document.getElementById("box1");
var ball = document.getElementById("ball");
 
box1.onmouseover = function(){
move(this,"left",0,10);
}
box1.onmouseout = function(){
move(this,"left",-100,-10);
}
//问题一:当需要两个动画的时候,会执行后面一个,解决办法如下,回调函数
ball.onmouseover = function(){
//同时变换 用的最多
//move(this,"width",500,10);
//move(this,"height",500,10);
//列队在执行
move(ball,"width",500,10,function(){
move(ball,"height",500,10);
});
}
ball.onmouseout = function(){
//move(this,"width",100,-10);
//move(this,"height",100,-10);
move(ball,"width",100,-10,function(){
move(ball,"height",100,-10);
});
}
var timer = null;
function move(obj,attr,target,speed,callback){
clearInterval(timer); //obj.timer缓存到各自的obj下
timer = setInterval(function(){
var curr = parseInt(getStyle(obj,attr));
if(curr == target){
clearInterval(timer);
callback && callback();
}else {
obj.style[attr] = curr+speed+"px";
}
},1000/30);
}
 
 
 
 
function getStyle(obj,attr){
return getComputedStyle(obj)[attr]?getComputedStyle(obj)[attr]:obj.currentStyle[attr];
}

在线演示

1.3.2运动框架之轮播图应用
1.3.2.1 焦点轮播–左右-无缝-速度版实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<div id="box">
<ul id="imgBox">
<li>![](//upload-images.jianshu.io/upload_images/1480597-c72819402fb928e8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</li>
<li>![](//upload-images.jianshu.io/upload_images/1480597-6830ca74fe1e6fcd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</li>
<li>![](//upload-images.jianshu.io/upload_images/1480597-5d38376e63ffd0b0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</li>
<li>![](//upload-images.jianshu.io/upload_images/1480597-2aa932ffbba4091e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</li>
<li>![](//upload-images.jianshu.io/upload_images/1480597-c72819402fb928e8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</li>
</ul>
<ol id="btn">
<li class="active">1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ol>
</div>
<script src="http://7xq6al.com1.z0.glb.clouddn.com/Animate.min.js"></script>
<script type="text/javascript">
var box = document.querySelector("#box");
var imgUl = document.querySelector("#imgBox");
var btns = document.querySelector("#btn").querySelectorAll("li");
var len = btns.length;
var lenImg = imgUl.querySelectorAll("li").length;
var index = 0; //控制img的索引
var cindex = 0;//控制按钮的索引
var timer = null;
 
for (var i=0;i<len;i++) {
(function(index){
btns[index].onmouseover = function(){
for (var j=0;j<len;j++){
btns[j].className = "";
}
cindex = index;//保持索引同步
animateSpeed(imgUl,{"left":-970*index});
this.className = "active";
}
})(i);
}
function autoPlay(){
index++;
cindex++;
cindex %=len;//限制长度
for (var j=0;j<len;j++){
btns[j].className = "";
}
animateSpeed(imgUl,{"left":-970*index},function(){
 
if(index == lenImg-1){
this.style.left = 0;
index = 0;
}
});
btns[cindex].className = "active";
}
timer = setInterval(autoPlay,2000);
box.onmouseover = function(){
clearInterval(timer);
}
box.onmouseout = function(){
timer = setInterval(autoPlay,2000);
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
*{
padding: 0;
margin: 0;
}
body{
font-size: 14px;
font-family: "微软雅黑";
}
ul,li{
list-style: none;
}
#box {
position: relative;
width: 970px;
height: 350px;
margin: 30px auto;
overflow: hidden;
}
#imgBox {
width:1000%;/*自动计算百分比*/
position: absolute;
left: 0;
}
#imgBox li{
width: 970px;
height: 350px;
float: left;
}
 
#imgBox li img {
width: 970px;
height: 350px;
}
#btn {
width: 120px;
position: absolute;
right: 10px;
bottom: 10px;
}
#btn li {
width: 20px;
height: 20px;
line-height: 20px;
border-radius: 50%;
text-align: center;
cursor: pointer;
background: #fff;
margin: 0 2px;
float: left;
}
#btn li.active {
background: #F17A5C;
color: #fff;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
 
//速度版本
(function(win){
function move(obj,json,callback){
clearInterval(obj.timer);
obj.timer = setInterval(function(){
var mark = true;
for(var attr in json){
var cur = null;
if(attr == "opacity"){
cur = getStyle(obj,attr)*100;
}else{
//如果没写 默认填充成0
cur = parseInt(getStyle(obj,attr))||0;
}
var target = json[attr];
var speed = (target - cur)*0.2;
speed = speed>0?Math.ceil(speed):Math.floor(speed);
if(cur != target){
if(attr == "opacity"){
//IE opacity兼容问题
obj.style.filter = "alpha(opacity="+(cur+speed)+")";
obj.style[attr] = (cur + speed)/100;
}else{
obj.style[attr] = cur + speed + "px";
}
mark = false;
 
};
}
if(mark){
clearInterval(obj.timer);
callback && callback.call(obj);
}
},1000/30);
}
win.animateSpeed = move;
})(window);
 
 
function getStyle(obj,attr){
return getComputedStyle(obj)[attr]?getComputedStyle(obj)[attr]:obj.currentStyle[attr];
}
 
function getId(id){
return document.getElementById(id);
}

二、JavaScript运动框架之时间版


2.1 关于运动


  • 速度的运动 通过速度来控制元素的 位移 / 折叠 / 淡入淡出
  • 时间的运动 通过时间来控制元素的 位移 / 折叠 / 淡入淡出(jQuery)
  • 时间的运动 基于一些数学公式 匀速运动 在路程的每一个点 速度都一样
2.2 一些案例演示

2.3 运动框架之时间版本-借助animate一些函数实现–综合完整版


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<div id="box2"></div>
<div id="box3"></div>
<div id="box4"></div>
<div id="box5"></div>
<script type="text/javascript">
 
//时间版本
getId("box2").onclick = function(){
animateTime(getId("box2"),{
"left":500,
"opacity":100
},1000,"elasticOut",function(){
this.innerHTML = "我是时间版本";
});
}
getId("box3").onclick = function(){
animateTime(getId("box3"),{
"left":500,
"opacity":100
},1000,"backIn",function(){
this.innerHTML = "我是时间版本";
});
}
getId("box4").onclick = function(){
animateTime(getId("box4"),{
"left":500,
"opacity":100
},1000,"bounceIn",function(){
this.innerHTML = "我是时间版本";
});
}
getId("box5").onclick = function(){
animateTime(getId("box5"),{
"left":500,
"opacity":100
},1000,"bounceBoth",function(){
this.innerHTML = "我是时间版本";
});
}
 
 
 
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#box1,#box2,#box3,#box4,#box5 {
position: relative;
width: 100px;
height: 100px;
line-height: 100px;
text-align: center;
background: red;
color: #fff;
font-size: 12px;
opacity: 0.5;
filter:alpha(opcity=20);/**兼容IE*/
margin: 10px;
 
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
 
/*t b c d
t current time :nTime-sTime
b begining time :curr
c chang in value :变化量end-curr
d duration :持续时间 time */
/**
*
* @param {Object} obj 元素对象
* @param {Object} json 多个属性
* @param {Object} time 变化时间
* @param {Object} prop 运动函数
* @param {Object} callback 回调函数
*/
//时间版本
(function(win){
function move(obj,json,time,prop,callback){
//一般定时器结束后最好清除
clearInterval(obj.timer);
var curr = {};
var end = {};
//通过for in 在上车前把所有东西装到包里
for(var attr in json){
if(attr == "opacity"){//opacity特殊东西特殊对待
curr[attr] = getStyle(obj,attr)*100;//化为整数好计算
}else{
curr[attr] = parseInt(getStyle(obj,attr))||0;
}
end[attr] = json[attr];
 
}
 
 
//如果没写默认值 默认就是0 不然在IE出问题
//var curr = parseInt(getStyle(obj,attr))||0;
//var end = target;
var sTime = new Date();//开始时间T0
//开始变换了
obj.timer = setInterval(function(){
var nTime = new Date();//当前时间Tt
var t = nTime -sTime;
var d = time;
//St = (Tt-T0)/Time*(S-S0)+S0
//(nTime-sTime)/time 比例最多为1
/*var prop = (nTime-sTime)/time; */
if(t >=d){
t = d;
clearInterval(obj.timer);
callback && callback.call(obj);
}
for(var attr in json){
var b = curr[attr];
var c = end[attr] - b;
if(attr == "opacity"){
//var s = prop*(end[attr]-curr[attr])+curr[attr];
var s = Tween[prop](t,b,c,d);
obj.style[attr] = s/100;
obj.style.filter = "alpha(opacity="+s+")";
}else{
//var s = prop*(end[attr]-curr[attr])+curr[attr];
var s = Tween[prop](t,b,c,d);
obj.style[attr] = s+"px";
}
 
}
 
 
},13);
var Tween = {
linear: function (t, b, c, d){ //匀速
return c*t/d + b; // t/d = prop;
},
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;
},
easeBoth: function(t, b, c, d){ //加速减速曲线
if ((t/=d/2) < 1) {
return c/2*t*t + b;
}
return -c/2 * ((--t)*(t-2) - 1) + b;
},
easeInStrong: function(t, b, c, d){ //加加速曲线
return c*(t/=d)*t*t*t + b;
},
easeOutStrong: function(t, b, c, d){ //减减速曲线
return -c * ((t=t/d-1)*t*t*t - 1) + b;
},
easeBothStrong: 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;
},
elasticIn: function(t, b, c, d, a, p){ //正弦衰减曲线(弹动渐入)
if (t === 0) {
return b;
}
if ( (t /= d) == 1 ) {
return b+c;
}
if (!p) {
p=d*0.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;
},
elasticOut: function(t, b, c, d, a, p){ //正弦增强曲线(弹动渐出)
if (t === 0) {
return b;
}
if ( (t /= d) == 1 ) {
return b+c;
}
if (!p) {
p=d*0.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;
},
elasticBoth: function(t, b, c, d, a, p){
if (t === 0) {
return b;
}
if ( (t /= d/2) == 2 ) {
return b+c;
}
if (!p) {
p = d*(0.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 - 0.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 )*0.5 + c + b;
},
backIn: function(t, b, c, d, s){ //回退加速(回退渐入)
if (typeof s == 'undefined') {
s = 1.70158;
}
return c*(t/=d)*t*((s+1)*t - s) + b;
},
backOut: function(t, b, c, d, s){
if (typeof s == 'undefined') {
s = 3.70158; //回缩的距离
}
return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
},
backBoth: function(t, b, c, d, s){
if (typeof 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;
},
bounceIn: function(t, b, c, d){ //弹球减振(弹球渐出)
return c - Tween['bounceOut'](d-t, 0, c, d) + b;
},
bounceOut: 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 + 0.75) + b;
} else if (t < (2.5/2.75)) {
return c*(7.5625*(t-=(2.25/2.75))*t + 0.9375) + b;
}
return c*(7.5625*(t-=(2.625/2.75))*t + 0.984375) + b;
},
bounceBoth: function(t, b, c, d){
if (t < d/2) {
return Tween['bounceIn'](t*2, 0, c, d) * 0.5 + b;
}
return Tween['bounceOut'](t*2-d, 0, c, d) * 0.5 + c*0.5 + b;
}
};
}
win.animateTime = move;
})(window);

在线演示

三、运动框架之时间速度版完整封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
/*t b c d
t current time :nTime-sTime
b begining time :curr
c chang in value :变化量end-curr
d duration :持续时间 time */
/**
*
* @param {Object} obj 元素对象
* @param {Object} json 多个属性
* @param {Object} time 变化时间
* @param {Object} prop 运动函数
* @param {Object} callback 回调函数
*/
//时间版本
(function(win){
function move(obj,json,time,prop,callback){
//一般定时器结束后最好清除
clearInterval(obj.timer);
var curr = {};
var end = {};
//通过for in 在上车前把所有东西装到包里
for(var attr in json){
if(attr == "opacity"){//opacity特殊东西特殊对待
curr[attr] = getStyle(obj,attr)*100;//化为整数好计算
}else{
curr[attr] = parseInt(getStyle(obj,attr))||0;
}
end[attr] = json[attr];
 
}
 
 
//如果没写默认值 默认就是0 不然在IE出问题
//var curr = parseInt(getStyle(obj,attr))||0;
//var end = target;
var sTime = new Date();//开始时间T0
//开始变换了
obj.timer = setInterval(function(){
var nTime = new Date();//当前时间Tt
var t = nTime -sTime;
var d = time;
//St = (Tt-T0)/Time*(S-S0)+S0
//(nTime-sTime)/time 比例最多为1
/*var prop = (nTime-sTime)/time; */
if(t >=d){
t = d;
clearInterval(obj.timer);
callback && callback.call(obj);
}
for(var attr in json){
var b = curr[attr];
var c = end[attr] - b;
if(attr == "opacity"){
//var s = prop*(end[attr]-curr[attr])+curr[attr];
var s = Tween[prop](t,b,c,d);
obj.style[attr] = s/100;
obj.style.filter = "alpha(opacity="+s+")";
}else{
//var s = prop*(end[attr]-curr[attr])+curr[attr];
var s = Tween[prop](t,b,c,d);
obj.style[attr] = s+"px";
}
 
}
 
 
},13);
var Tween = {
linear: function (t, b, c, d){ //匀速
return c*t/d + b; // t/d = prop;
},
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;
},
easeBoth: function(t, b, c, d){ //加速减速曲线
if ((t/=d/2) < 1) {
return c/2*t*t + b;
}
return -c/2 * ((--t)*(t-2) - 1) + b;
},
easeInStrong: function(t, b, c, d){ //加加速曲线
return c*(t/=d)*t*t*t + b;
},
easeOutStrong: function(t, b, c, d){ //减减速曲线
return -c * ((t=t/d-1)*t*t*t - 1) + b;
},
easeBothStrong: 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;
},
elasticIn: function(t, b, c, d, a, p){ //正弦衰减曲线(弹动渐入)
if (t === 0) {
return b;
}
if ( (t /= d) == 1 ) {
return b+c;
}
if (!p) {
p=d*0.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;
},
elasticOut: function(t, b, c, d, a, p){ //正弦增强曲线(弹动渐出)
if (t === 0) {
return b;
}
if ( (t /= d) == 1 ) {
return b+c;
}
if (!p) {
p=d*0.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;
},
elasticBoth: function(t, b, c, d, a, p){
if (t === 0) {
return b;
}
if ( (t /= d/2) == 2 ) {
return b+c;
}
if (!p) {
p = d*(0.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 - 0.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 )*0.5 + c + b;
},
backIn: function(t, b, c, d, s){ //回退加速(回退渐入)
if (typeof s == 'undefined') {
s = 1.70158;
}
return c*(t/=d)*t*((s+1)*t - s) + b;
},
backOut: function(t, b, c, d, s){
if (typeof s == 'undefined') {
s = 3.70158; //回缩的距离
}
return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
},
backBoth: function(t, b, c, d, s){
if (typeof 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;
},
bounceIn: function(t, b, c, d){ //弹球减振(弹球渐出)
return c - Tween['bounceOut'](d-t, 0, c, d) + b;
},
bounceOut: 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 + 0.75) + b;
} else if (t < (2.5/2.75)) {
return c*(7.5625*(t-=(2.25/2.75))*t + 0.9375) + b;
}
return c*(7.5625*(t-=(2.625/2.75))*t + 0.984375) + b;
},
bounceBoth: function(t, b, c, d){
if (t < d/2) {
return Tween['bounceIn'](t*2, 0, c, d) * 0.5 + b;
}
return Tween['bounceOut'](t*2-d, 0, c, d) * 0.5 + c*0.5 + b;
}
};
}
win.animateTime = move;
})(window);
 
 
//速度版本
(function(win){
function move(obj,json,callback){
clearInterval(obj.timer);
obj.timer = setInterval(function(){
var mark = true;
for(var attr in json){
var cur = null;
if(attr == "opacity"){
cur = getStyle(obj,attr)*100;
}else{
//如果没写 默认填充成0
cur = parseInt(getStyle(obj,attr))||0;
}
var target = json[attr];
var speed = (target - cur)*0.2;
speed = speed>0?Math.ceil(speed):Math.floor(speed);
if(cur != target){
if(attr == "opacity"){
//IE opacity兼容问题
obj.style.filter = "alpha(opacity="+(cur+speed)+")";
obj.style[attr] = (cur + speed)/100;
}else{
obj.style[attr] = cur + speed + "px";
}
mark = false;
 
};
}
if(mark){
clearInterval(obj.timer);
callback && callback.call(obj);
}
},1000/30);
}
win.animateSpeed = move;
})(window);
 
 
function getStyle(obj,attr){
return getComputedStyle(obj)[attr]?getComputedStyle(obj)[attr]:obj.currentStyle[attr];
}
 
function getId(id){
return document.getElementById(id);
}

from:http://blog.poetries.top/2017/01/12/js-animate/?utm_source=tuicool&utm_medium=referral

【repost】JavaScript运动框架之速度时间版本的更多相关文章

  1. javascript运动框架(三)

    迟到了好几天,不好意思哈!继续来优化一下javascript运动框架的代码.之前的代码存在bug,当重复点击时速度会加快,那么怎么解决这个bug呢? 现在我们就来解决一下,其实很简单,在开始运动时,关 ...

  2. 好程序员技术教程分享JavaScript运动框架

    好程序员技术教程分享JavaScript运动框架,有需要的朋友可以参考下. JavaScript的运动,即让某元素的某些属性由一个值变到另一个值的过程.如让div的width属性由200px变到400 ...

  3. 【原生JS组件】javascript 运动框架

    大家都知道JQuerry有animate方法来给DOM元素进行运动,CSS3中也有transition.transform来进行运动.而使用原生的Javascript来控制元素运动,须要写非常多运动的 ...

  4. JavaScript 运动框架 Step by step(转)

    1,运动原理 Js运动,本质来说,就是让 web 上 DOM 元素动起来.而想要 DOM 动起来,改变其自身的位置属性,比如高宽,左边距,上边距,透明度等.动画的原理就是把不同状态的物体,串成连续的样 ...

  5. javascript运动框架

    下面这个一个运动框架可以控制元素在一个属性上的运动,同时,可以调用回调函数. /* 获取元素某个属性的值 @obj: 对象 @attr: 属性值 */ function getStyle(obj, a ...

  6. javaScript运动框架之匀速运动

    运动框架 1.在开始运动时,关闭已有定时器 2.把运动和停止隔开(if/else) 匀速运动的停止条件 运动终止条件:距离足够近 Demo代码 <!DOCTYPE html> <ht ...

  7. JavaScript 运动框架

    <script> window.onload=function (){ var oDiv=document.getElementById("div1"); oDiv.o ...

  8. javascript运动框架(二)

    紧接着上面写的... 给div加一个边框,border:1px solid black window.onload = function(){      var div = document.getE ...

  9. javaScript运动框架之缓冲运动

    缓冲运动 逐渐变慢,最后停止 距离越远速度越大   速度由距离决定 速度=(目标值-当前值)/缩放系数 存在Bug 速度取整 跟随页面滚动的缓冲侧边栏 潜在问题:目标值不是整数时 缓冲运动的停止条件 ...

随机推荐

  1. VS2010,VS2012,VS2013中,无法嵌入互操作类型“……”,请改用适用的接口的解决方法

    在VS2013开发环境下,C#引用COM组件遇到的两个问题: 一开始是COM组件没有注册导致代码引用报错,那么我就使用管理员的命令行方式下,入册COM组件: C:\WINDOWS\system32&g ...

  2. oracle 直接复制表内容到新表

    不知道为什么,刚建的oracle数据库删除数据很慢,表里面有120多万数据,非常地慢 于是采用的复制的方法,命令如下: create table students_backup as select * ...

  3. JS-Date心得

    写在前面的话:我觉得JavaScript以后也要出像Java1.8新增的Date类,这个月份要是从1开始多好,强迫症很难受.......也就发发牢骚,没出来之前还得这么用..... 属性: const ...

  4. 未能找到 CodeDom 提供程序类型“Microsoft.VJSharp.VJSharpCodeProvider,

    错误 1 未能找到 CodeDom 提供程序类型“Microsoft.VJSharp.VJSharpCodeProvider, VJSharpCodeProvider, Version=2.0.0.0 ...

  5. nginx + fastdfs 的开机自启动

    虚拟机每次启动之后都要重新启动一下fastdfs 和 nginx服务,比较麻烦,所以增加开机自启动: 编辑 /etc/rc.d/rc.local 文件,增加启动项: 1.编辑文件 vim /etc/r ...

  6. c#while循环注意continue的地方

    在使用while 时发现一个很大的问题,continue最好慎用! private void do() { int i = 0; while (true) { //continue;//绝对的死循环 ...

  7. Java中 i++ 是线程安全的么?为什么?

    问题 在 int i = 0; i = i++; 语句中,i = i++是线程安全的么?如果不安全,请说明上面操作在JVM中的执行过程,为什么不安全?说出JDK中哪个类能达到以上的效果,并且是线程安全 ...

  8. ListView item中有button或EditText时 点击事件失效问题的解决

    加入:android:descendantFocusability="blocksDescendants" 代码如下: <LinearLayout xmlns:android ...

  9. log4j日志整合输出(slf4j+commonslog+log4j+jdklogger)

    log4j日志整合输出(slf4j+commonslog+log4j+jdklogger) 博客分类: 日志   J2EE项目中,经常会用到很多第三方的开源组件和软件,这些组件都使用各自的日志组件,比 ...

  10. 利用Delphi-cross-socket 库提升kbmmw 跨平台开发

    以前我写过了,通过httpsys 提升windows 下,delphi 多层应用.随着delphi 10.2 对linux 的支持,很多人也想在linux 下 发布kbmmw 服务器,但是官方仅通过i ...