-
Notifications
You must be signed in to change notification settings - Fork 3
/
StateModifier.js
265 lines (246 loc) · 9 KB
/
StateModifier.js
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
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Owner: [email protected]
* @license MPL 2.0
* @copyright Famous Industries, Inc. 2014
*/
define(function(require, exports, module) {
var Modifier = require('famous/core/Modifier');
var Transform = require('famous/core/Transform');
var Transitionable = require('famous/transitions/Transitionable');
var TransitionableTransform = require('famous/transitions/TransitionableTransform');
/**
* A collection of visual changes to be
* applied to another renderable component, strongly coupled with the state that defines
* those changes. This collection includes a
* transform matrix, an opacity constant, a size, an origin specifier, and an alignment specifier.
* StateModifier objects can be added to any RenderNode or object
* capable of displaying renderables. The StateModifier's children and descendants
* are transformed by the amounts specified in the modifier's properties.
*
* @class StateModifier
* @constructor
* @param {Object} [options] overrides of default options
* @param {Transform} [options.transform] affine transformation matrix
* @param {Number} [options.opacity]
* @param {Array.Number} [options.origin] origin adjustment
* @param {Array.Number} [options.align] align adjustment
* @param {Array.Number} [options.size] size to apply to descendants
*/
function StateModifier(options) {
this._transformState = new TransitionableTransform(Transform.identity);
this._opacityState = new Transitionable(1);
this._originState = new Transitionable([0, 0]);
this._alignState = new Transitionable([0, 0]);
this._sizeState = new Transitionable([0, 0]);
this._modifier = new Modifier({
transform: this._transformState,
opacity: this._opacityState,
origin: null,
align: null,
size: null
});
this._hasOrigin = false;
this._hasAlign = false;
this._hasSize = false;
if (options) {
if (options.transform) this.setTransform(options.transform);
if (options.opacity !== undefined) this.setOpacity(options.opacity);
if (options.origin) this.setOrigin(options.origin);
if (options.align) this.setAlign(options.align);
if (options.size) this.setSize(options.size);
}
}
/**
* Set the transform matrix of this modifier, either statically or
* through a provided Transitionable.
*
* @method setTransform
*
* @param {Transform} transform Transform to transition to.
* @param {Transitionable} [transition] Valid transitionable object
* @param {Function} [callback] callback to call after transition completes
* @return {StateModifier} this
*/
StateModifier.prototype.setTransform = function setTransform(transform, transition, callback) {
this._transformState.set(transform, transition, callback);
return this;
};
/**
* Set the opacity of this modifier, either statically or
* through a provided Transitionable.
*
* @method setOpacity
*
* @param {Number} opacity Opacity value to transition to.
* @param {Transitionable} transition Valid transitionable object
* @param {Function} callback callback to call after transition completes
* @return {StateModifier} this
*/
StateModifier.prototype.setOpacity = function setOpacity(opacity, transition, callback) {
this._opacityState.set(opacity, transition, callback);
return this;
};
/**
* Set the origin of this modifier, either statically or
* through a provided Transitionable.
*
* @method setOrigin
*
* @param {Array.Number} origin two element array with values between 0 and 1.
* @param {Transitionable} transition Valid transitionable object
* @param {Function} callback callback to call after transition completes
* @return {StateModifier} this
*/
StateModifier.prototype.setOrigin = function setOrigin(origin, transition, callback) {
if (origin === null) {
if (this._hasOrigin) {
this._modifier.originFrom(null);
this._hasOrigin = false;
}
return this;
}
else if (!this._hasOrigin) {
this._hasOrigin = true;
this._modifier.originFrom(this._originState);
}
this._originState.set(origin, transition, callback);
return this;
};
/**
* Set the alignment of this modifier, either statically or
* through a provided Transitionable.
*
* @method setAlign
*
* @param {Array.Number} align two element array with values between 0 and 1.
* @param {Transitionable} transition Valid transitionable object
* @param {Function} callback callback to call after transition completes
* @return {StateModifier} this
*/
StateModifier.prototype.setAlign = function setOrigin(align, transition, callback) {
if (align === null) {
if (this._hasAlign) {
this._modifier.alignFrom(null);
this._hasAlign = false;
}
return this;
}
else if (!this._hasAlign) {
this._hasAlign = true;
this._modifier.alignFrom(this._alignState);
}
this._alignState.set(align, transition, callback);
return this;
};
/**
* Set the size of this modifier, either statically or
* through a provided Transitionable.
*
* @method setSize
*
* @param {Array.Number} size two element array with values between 0 and 1.
* @param {Transitionable} transition Valid transitionable object
* @param {Function} callback callback to call after transition completes
* @return {StateModifier} this
*/
StateModifier.prototype.setSize = function setSize(size, transition, callback) {
if (size === null) {
if (this._hasSize) {
this._modifier.sizeFrom(null);
this._hasSize = false;
}
return this;
}
else if (!this._hasSize) {
this._hasSize = true;
this._modifier.sizeFrom(this._sizeState);
}
this._sizeState.set(size, transition, callback);
return this;
};
/**
* Stop the transition.
*
* @method halt
*/
StateModifier.prototype.halt = function halt() {
this._transformState.halt();
this._opacityState.halt();
this._originState.halt();
this._alignState.halt();
this._sizeState.halt();
};
/**
* Get the current state of the transform matrix component.
*
* @method getTransform
* @return {Object} transform provider object
*/
StateModifier.prototype.getTransform = function getTransform() {
return this._transformState.get();
};
/**
* Get the destination state of the transform component.
*
* @method getFinalTransform
* @return {Transform} transform matrix
*/
StateModifier.prototype.getFinalTransform = function getFinalTransform() {
return this._transformState.getFinal();
};
/**
* Get the current state of the opacity component.
*
* @method getOpacity
* @return {Object} opacity provider object
*/
StateModifier.prototype.getOpacity = function getOpacity() {
return this._opacityState.get();
};
/**
* Get the current state of the origin component.
*
* @method getOrigin
* @return {Object} origin provider object
*/
StateModifier.prototype.getOrigin = function getOrigin() {
return this._hasOrigin ? this._originState.get() : null;
};
/**
* Get the current state of the align component.
*
* @method getAlign
* @return {Object} align provider object
*/
StateModifier.prototype.getAlign = function getAlign() {
return this._hasAlign ? this._alignState.get() : null;
};
/**
* Get the current state of the size component.
*
* @method getSize
* @return {Object} size provider object
*/
StateModifier.prototype.getSize = function getSize() {
return this._hasSize ? this._sizeState.get() : null;
};
/**
* Return render spec for this StateModifier, applying to the provided
* target component. This is similar to render() for Surfaces.
*
* @private
* @method modify
*
* @param {Object} target (already rendered) render spec to
* which to apply the transform.
* @return {Object} render spec for this StateModifier, including the
* provided target
*/
StateModifier.prototype.modify = function modify(target) {
return this._modifier.modify(target);
};
module.exports = StateModifier;
});