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
|
/*
oktween.add({
obj: el.style,
units: "px",
from: { left: 0 },
to: { left: 100 },
duration: 1000,
easing: oktween.easing.circ_out,
finish: function(){
console.log("done")
}
})
*/
var oktween = (function(){
var oktween = {}
var tweens = oktween.tweens = []
var last_t = 0
var id = 0
oktween.speed = 1
oktween.then = oktween.add = function(tween){
tween.id = id++
tween.obj = tween.obj || {}
if (tween.easing) {
if (typeof tween.easing == "string") {
tween.easing = oktween.easing[tween.easing]
}
}
else {
tween.easing = oktween.easing.linear
}
if (! ('from' in tween) ) {
tween.from = {}
tween.keys = Object.keys(tween.to)
tween.keys.forEach(function(prop){
tween.from[prop] = parseFloat(tween.obj[prop])
})
}
else {
tween.keys = Object.keys(tween.from)
}
tween.delay = tween.delay || 0
tween.duration = tween.duration || 200
tween.start = last_t + tween.delay
tween.done = false
tween.then = function(fn){ tween.after = [fn] }
tween.finish = function(){ tween.start = 0 }
tween.cancel = function(){
var idx = tweens.indexOf(tween)
if (~idx) { tweens.splice(idx, 1) }
}
tween.tick = 0
tween.skip = tween.skip || 1
tweens.push(tween)
return tween
}
oktween.update = function(t) {
requestAnimationFrame(oktween.update)
last_t = t * oktween.speed
if (tweens.length == 0) return
var done = false
tweens.forEach(function(tween, i){
var dt = Math.min(1.0, (t - tween.start) / tween.duration)
tween.tick++
if (dt < 0 || (dt < 1 && (tween.tick % tween.skip != 0))) return
var ddt = tween.dt = tween.easing(dt)
tween.keys.forEach(function(prop){
val = lerp( ddt, tween.from[prop], tween.to[prop] )
if (tween.round) val = Math.round(val)
if (tween.units) val = (Math.round(val)) + tween.units
tween.obj[prop] = val
})
tween.update && tween.update(tween.obj, dt)
if (dt == 1) {
tween.finished && tween.finished(tween)
tween.after && tween.after.forEach(function(twn){
if (typeof twn == "function") { return twn() }
if (! twn.obj) { twn.obj = tween.obj }
oktween.add(twn)
})
if (tween.loop) {
tween.start = t + tween.delay
}
else {
done = tween.done = true
}
}
})
if (done) {
tweens = tweens.filter(function(tween){ return ! tween.done })
}
}
function lerp(n,a,b){ return (b-a)*n+a }
requestAnimationFrame(oktween.update)
oktween.easing = {
linear: function(t){
return t
},
circ_out: function(t) {
return Math.sqrt(1 - (t = t - 1) * t)
},
circ_in: function(t){
return -(Math.sqrt(1 - (t * t)) - 1)
},
circ_in_out: function(t) {
return ((t*=2) < 1) ? -0.5 * (Math.sqrt(1 - t * t) - 1) : 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1)
},
quad_in: function(n){
return Math.pow(n, 2)
},
quad_out: function(n){
return n * (n - 2) * -1
},
quad_in_out: function(n){
n = n * 2
if(n < 1){ return Math.pow(n, 2) / 2 }
return -1 * ((--n) * (n - 2) - 1) / 2
},
}
return oktween
})()
|