Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/webroot/rsrc/externals/javelin/ext/fx/FX.js
12242 views
1
/**
2
* @provides javelin-fx
3
* @requires javelin-color javelin-install javelin-util
4
* @javelin
5
*
6
* Based on moo.fx (moofx.mad4milk.net).
7
*/
8
9
JX.install('FX', {
10
11
events: ['start', 'complete'],
12
13
construct: function(element) {
14
this._config = {};
15
this.setElement(element);
16
this.setTransition(JX.FX.Transitions.sine);
17
},
18
19
properties: {
20
fps: 50,
21
wait: true,
22
duration: 500,
23
element: null,
24
property: null,
25
transition: null
26
},
27
28
members: {
29
_to: null,
30
_now: null,
31
_from: null,
32
_start: null,
33
_config: null,
34
_interval: null,
35
36
start: function(config) {
37
if (__DEV__) {
38
if (!config) {
39
throw new Error('What styles do you want to animate?');
40
}
41
if (!this.getElement()) {
42
throw new Error('What element do you want to animate?');
43
}
44
}
45
if (this._interval && this.getWait()) {
46
return;
47
}
48
var from = {};
49
var to = {};
50
for (var prop in config) {
51
from[prop] = config[prop][0];
52
to[prop] = config[prop][1];
53
if (/color/i.test(prop)) {
54
from[prop] = JX.Color.hexToRgb(from[prop], true);
55
to[prop] = JX.Color.hexToRgb(to[prop], true);
56
}
57
}
58
this._animate(from, to);
59
return this;
60
},
61
62
stop: function() {
63
clearInterval(this._interval);
64
this._interval = null;
65
return this;
66
},
67
68
then: function(func) {
69
var token = this.listen('complete', function() {
70
token.remove();
71
func();
72
});
73
return this;
74
},
75
76
_animate: function(from, to) {
77
if (!this.getWait()) {
78
this.stop();
79
}
80
if (this._interval) {
81
return;
82
}
83
setTimeout(JX.bind(this, this.invoke, 'start'), 10);
84
this._from = from;
85
this._to = to;
86
this._start = JX.now();
87
this._interval = setInterval(
88
JX.bind(this, this._tween),
89
Math.round(1000 / this.getFps()));
90
91
// Immediately update to the initial values.
92
this._tween();
93
},
94
95
_tween: function() {
96
var now = JX.now();
97
var prop;
98
if (now < this._start + this.getDuration()) {
99
this._now = now - this._start;
100
for (prop in this._from) {
101
this._config[prop] = this._compute(this._from[prop], this._to[prop]);
102
}
103
} else {
104
setTimeout(JX.bind(this, this.invoke, 'complete'), 10);
105
106
// Compute the final position using the transition function, in case
107
// the function applies transformations.
108
this._now = this.getDuration();
109
for (prop in this._from) {
110
this._config[prop] = this._compute(this._from[prop], this._to[prop]);
111
}
112
this.stop();
113
}
114
this._render();
115
},
116
117
_compute: function(from, to) {
118
if (JX.isArray(from)) {
119
return from.map(function(value, ii) {
120
return Math.round(this._compute(value, to[ii]));
121
}, this);
122
}
123
var delta = to - from;
124
return this.getTransition()(this._now, from, delta, this.getDuration());
125
},
126
127
_render: function() {
128
var style = this.getElement().style;
129
for (var prop in this._config) {
130
var value = this._config[prop];
131
if (prop == 'opacity') {
132
value = parseInt(100 * value, 10);
133
if (window.ActiveXObject) {
134
style.filter = 'alpha(opacity=' + value + ')';
135
} else {
136
style.opacity = value / 100;
137
}
138
} else if (/color/i.test(prop)) {
139
style[prop] = 'rgb(' + value + ')';
140
} else {
141
style[prop] = value + 'px';
142
}
143
}
144
}
145
},
146
147
statics: {
148
fade: function(element, visible) {
149
return new JX.FX(element).setDuration(250).start({
150
opacity: visible ? [0, 1] : [1, 0]
151
});
152
},
153
154
highlight: function(element, color) {
155
color = color || '#fff8dd';
156
return new JX.FX(element).setDuration(1000).start({
157
backgroundColor: [color, '#fff']
158
});
159
},
160
161
/**
162
* Easing equations based on work by Robert Penner
163
* http://www.robertpenner.com/easing/
164
*/
165
Transitions: {
166
linear: function(t, b, c, d) {
167
return c * t / d + b;
168
},
169
170
sine: function(t, b, c, d) {
171
return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
172
},
173
174
sineIn: function(t, b, c, d) {
175
if (t == d) {
176
return c + b;
177
}
178
return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
179
},
180
181
sineOut: function(t, b, c, d) {
182
if (t == d) {
183
return c + b;
184
}
185
return c * Math.sin(t / d * (Math.PI / 2)) + b;
186
},
187
188
elastic: function(t, b, c, d, a, p) {
189
if (t === 0) { return b; }
190
if ((t /= d) == 1) { return b + c; }
191
if (!p) { p = d * 0.3; }
192
if (!a) { a = 1; }
193
var s;
194
if (a < Math.abs(c)) {
195
a = c;
196
s = p / 4;
197
} else {
198
s = p / (2 * Math.PI) * Math.asin(c / a);
199
}
200
return a * Math.pow(2, -10 * t) *
201
Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b;
202
},
203
204
bounce: function(t, b, c, d) {
205
if ((t /= d) < (1 / 2.75)) {
206
return c * (7.5625 * t * t) + b;
207
} else if (t < (2 / 2.75)) {
208
return c * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + b;
209
} else if (t < (2.5 / 2.75)) {
210
return c * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + b;
211
} else {
212
return c * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + b;
213
}
214
}
215
}
216
}
217
});
218
219