-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathFlipper.js
149 lines (129 loc) · 4.53 KB
/
Flipper.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
/* 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 Transform = require('famous/core/Transform');
var Transitionable = require('famous/transitions/Transitionable');
var RenderNode = require('famous/core/RenderNode');
var OptionsManager = require('famous/core/OptionsManager');
/**
* Allows you to link two renderables as front and back sides that can be
* 'flipped' back and forth along a chosen axis. Rendering optimizations are
* automatically handled.
*
* @class Flipper
* @constructor
* @param {Options} [options] An object of options.
* @param {Transition} [options.transition=true] The transition executed when flipping your Flipper instance.
*/
function Flipper(options) {
this.options = Object.create(Flipper.DEFAULT_OPTIONS);
this._optionsManager = new OptionsManager(this.options);
if (options) this.setOptions(options);
this.angle = new Transitionable(0);
this.frontNode = undefined;
this.backNode = undefined;
this.flipped = false;
}
Flipper.DIRECTION_X = 0;
Flipper.DIRECTION_Y = 1;
var SEPERATION_LENGTH = 1;
Flipper.DEFAULT_OPTIONS = {
transition: true,
direction: Flipper.DIRECTION_X
};
/**
* Toggles the rotation between the front and back renderables
*
* @method flip
* @param {Object} [transition] Transition definition
* @param {Function} [callback] Callback
*/
Flipper.prototype.flip = function flip(transition, callback) {
var angle = this.flipped ? 0 : Math.PI;
this.setAngle(angle, transition, callback);
this.flipped = !this.flipped;
};
/**
* Basic setter to the angle
*
* @method setAngle
* @param {Number} angle
* @param {Object} [transition] Transition definition
* @param {Function} [callback] Callback
*/
Flipper.prototype.setAngle = function setAngle(angle, transition, callback) {
if (transition === undefined) transition = this.options.transition;
if (this.angle.isActive()) this.angle.halt();
this.angle.set(angle, transition, callback);
};
/**
* Patches the Flipper instance's options with the passed-in ones.
*
* @method setOptions
* @param {Options} options An object of configurable options for the Flipper instance.
*/
Flipper.prototype.setOptions = function setOptions(options) {
return this._optionsManager.setOptions(options);
};
/**
* Adds the passed-in renderable to the view associated with the 'front' of the Flipper instance.
*
* @method setFront
* @chainable
* @param {Object} node The renderable you want to add to the front.
*/
Flipper.prototype.setFront = function setFront(node) {
this.frontNode = node;
};
/**
* Adds the passed-in renderable to the view associated with the 'back' of the Flipper instance.
*
* @method setBack
* @chainable
* @param {Object} node The renderable you want to add to the back.
*/
Flipper.prototype.setBack = function setBack(node) {
this.backNode = node;
};
/**
* Generate a render spec from the contents of this component.
*
* @private
* @method render
* @return {Number} Render spec for this component
*/
Flipper.prototype.render = function render() {
var angle = this.angle.get();
var frontTransform;
var backTransform;
if (this.options.direction === Flipper.DIRECTION_X) {
frontTransform = Transform.rotateY(angle);
backTransform = Transform.rotateY(angle + Math.PI);
}
else {
frontTransform = Transform.rotateX(angle);
backTransform = Transform.rotateX(angle + Math.PI);
}
var result = [];
if (this.frontNode){
result.push({
transform: frontTransform,
target: this.frontNode.render()
});
}
if (this.backNode){
result.push({
transform: Transform.moveThen([0, 0, SEPERATION_LENGTH], backTransform),
target: this.backNode.render()
});
}
return result;
};
module.exports = Flipper;
});