|
1 YUI.add('widget-anim', function (Y, NAME) { |
|
2 |
|
3 /** |
|
4 * Provides a plugin which can be used to animate widget visibility changes. |
|
5 * |
|
6 * @module widget-anim |
|
7 */ |
|
8 var BOUNDING_BOX = "boundingBox", |
|
9 HOST = "host", |
|
10 NODE = "node", |
|
11 OPACITY = "opacity", |
|
12 EMPTY_STR = "", |
|
13 VISIBLE = "visible", |
|
14 DESTROY = "destroy", |
|
15 HIDDEN = "hidden", |
|
16 |
|
17 RENDERED = "rendered", |
|
18 |
|
19 START = "start", |
|
20 END = "end", |
|
21 |
|
22 DURATION = "duration", |
|
23 ANIM_SHOW = "animShow", |
|
24 ANIM_HIDE = "animHide", |
|
25 |
|
26 _UI_SET_VISIBLE = "_uiSetVisible", |
|
27 |
|
28 ANIM_SHOW_CHANGE = "animShowChange", |
|
29 ANIM_HIDE_CHANGE = "animHideChange"; |
|
30 |
|
31 /** |
|
32 * A plugin class which can be used to animate widget visibility changes. |
|
33 * |
|
34 * @class WidgetAnim |
|
35 * @extends Plugin.Base |
|
36 * @namespace Plugin |
|
37 */ |
|
38 function WidgetAnim(config) { |
|
39 WidgetAnim.superclass.constructor.apply(this, arguments); |
|
40 } |
|
41 |
|
42 /** |
|
43 * The namespace for the plugin. This will be the property on the widget, which will |
|
44 * reference the plugin instance, when it's plugged in. |
|
45 * |
|
46 * @property NS |
|
47 * @static |
|
48 * @type String |
|
49 * @default "anim" |
|
50 */ |
|
51 WidgetAnim.NS = "anim"; |
|
52 |
|
53 /** |
|
54 * The NAME of the WidgetAnim class. Used to prefix events generated |
|
55 * by the plugin class. |
|
56 * |
|
57 * @property NAME |
|
58 * @static |
|
59 * @type String |
|
60 * @default "pluginWidgetAnim" |
|
61 */ |
|
62 WidgetAnim.NAME = "pluginWidgetAnim"; |
|
63 |
|
64 /** |
|
65 * Pre-Packaged Animation implementations, which can be used for animShow and animHide attribute |
|
66 * values. |
|
67 * |
|
68 * @property ANIMATIONS |
|
69 * @static |
|
70 * @type Object |
|
71 * @default "pluginWidgetAnim" |
|
72 */ |
|
73 WidgetAnim.ANIMATIONS = { |
|
74 |
|
75 fadeIn : function() { |
|
76 |
|
77 var widget = this.get(HOST), |
|
78 boundingBox = widget.get(BOUNDING_BOX), |
|
79 |
|
80 anim = new Y.Anim({ |
|
81 node: boundingBox, |
|
82 to: { opacity: 1 }, |
|
83 duration: this.get(DURATION) |
|
84 }); |
|
85 |
|
86 // Set initial opacity, to avoid initial flicker |
|
87 if (!widget.get(VISIBLE)) { |
|
88 boundingBox.setStyle(OPACITY, 0); |
|
89 } |
|
90 |
|
91 // Clean up, on destroy. Where supported, remove |
|
92 // opacity set using style. Else make 100% opaque |
|
93 anim.on(DESTROY, function() { |
|
94 this.get(NODE).setStyle(OPACITY, (Y.UA.ie) ? 1 : EMPTY_STR); |
|
95 }); |
|
96 |
|
97 return anim; |
|
98 }, |
|
99 |
|
100 fadeOut : function() { |
|
101 return new Y.Anim({ |
|
102 node: this.get(HOST).get(BOUNDING_BOX), |
|
103 to: { opacity: 0 }, |
|
104 duration: this.get(DURATION) |
|
105 }); |
|
106 } |
|
107 }; |
|
108 |
|
109 /** |
|
110 * Static property used to define the default attribute |
|
111 * configuration for the plugin. |
|
112 * |
|
113 * @property ATTRS |
|
114 * @type Object |
|
115 * @static |
|
116 */ |
|
117 WidgetAnim.ATTRS = { |
|
118 |
|
119 /** |
|
120 * Default duration in seconds. Used as the default duration for the default animation implementations |
|
121 * |
|
122 * @attribute duration |
|
123 * @type Number |
|
124 * @default 0.2 (seconds |
|
125 */ |
|
126 duration : { |
|
127 value: 0.2 |
|
128 }, |
|
129 |
|
130 /** |
|
131 * Default animation instance used for showing the widget (opacity fade-in) |
|
132 * |
|
133 * @attribute animShow |
|
134 * @type Anim |
|
135 * @default WidgetAnim.ANIMATIONS.fadeIn |
|
136 */ |
|
137 animShow : { |
|
138 valueFn: WidgetAnim.ANIMATIONS.fadeIn |
|
139 }, |
|
140 |
|
141 /** |
|
142 * Default animation instance used for hiding the widget (opacity fade-out) |
|
143 * |
|
144 * @attribute animHide |
|
145 * @type Anim |
|
146 * @default WidgetAnim.ANIMATIONS.fadeOut |
|
147 */ |
|
148 animHide : { |
|
149 valueFn: WidgetAnim.ANIMATIONS.fadeOut |
|
150 } |
|
151 }; |
|
152 |
|
153 Y.extend(WidgetAnim, Y.Plugin.Base, { |
|
154 |
|
155 /** |
|
156 * The initializer lifecycle implementation. Modifies the host widget's |
|
157 * visibililty implementation to add animation. |
|
158 * |
|
159 * @method initializer |
|
160 * @param {Object} config The user configuration for the plugin |
|
161 */ |
|
162 initializer : function(config) { |
|
163 this._bindAnimShow(); |
|
164 this._bindAnimHide(); |
|
165 |
|
166 this.after(ANIM_SHOW_CHANGE, this._bindAnimShow); |
|
167 this.after(ANIM_HIDE_CHANGE, this._bindAnimHide); |
|
168 |
|
169 // Override default _uiSetVisible method, with custom animated method |
|
170 this.beforeHostMethod(_UI_SET_VISIBLE, this._uiAnimSetVisible); |
|
171 }, |
|
172 |
|
173 /** |
|
174 * The initializer destructor implementation. Responsible for destroying the configured |
|
175 * animation instances. |
|
176 * |
|
177 * @method destructor |
|
178 */ |
|
179 destructor : function() { |
|
180 this.get(ANIM_SHOW).destroy(); |
|
181 this.get(ANIM_HIDE).destroy(); |
|
182 }, |
|
183 |
|
184 /** |
|
185 * The injected method used to override the host widget's _uiSetVisible implementation with |
|
186 * an animated version of the same. |
|
187 * |
|
188 * <p>This method replaces the default _uiSetVisible handler |
|
189 * Widget provides, by injecting itself before _uiSetVisible, |
|
190 * and preventing the default behavior. </p> |
|
191 * |
|
192 * @method _uiAnimSetVisible |
|
193 * @protected |
|
194 * @param {boolean} val true, if making the widget visible. false, if hiding it. |
|
195 */ |
|
196 _uiAnimSetVisible : function(val) { |
|
197 if (this.get(HOST).get(RENDERED)) { |
|
198 if (val) { |
|
199 this.get(ANIM_HIDE).stop(); |
|
200 this.get(ANIM_SHOW).run(); |
|
201 } else { |
|
202 this.get(ANIM_SHOW).stop(); |
|
203 this.get(ANIM_HIDE).run(); |
|
204 } |
|
205 return new Y.Do.Prevent(); |
|
206 } |
|
207 }, |
|
208 |
|
209 /** |
|
210 * The original Widget _uiSetVisible implementation. This currently needs to be replicated, |
|
211 * so it can be invoked before or after the animation starts or stops, since the original |
|
212 * methods is not available to the AOP implementation. |
|
213 * |
|
214 * @method _uiSetVisible |
|
215 * @param {boolean} val true, if making the widget visible. false, if hiding it. |
|
216 * @private |
|
217 */ |
|
218 _uiSetVisible : function(val) { |
|
219 var host = this.get(HOST), |
|
220 hiddenClass = host.getClassName(HIDDEN); |
|
221 |
|
222 host.get(BOUNDING_BOX).toggleClass(hiddenClass, !val); |
|
223 }, |
|
224 |
|
225 /** |
|
226 * Binds a listener to invoke the original visibility handling when the animShow animation is started |
|
227 * |
|
228 * @method _bindAnimShow |
|
229 * @private |
|
230 */ |
|
231 _bindAnimShow : function() { |
|
232 // Setup original visibility handling (for show) before starting to animate |
|
233 this.get(ANIM_SHOW).on(START, |
|
234 Y.bind(function() { |
|
235 this._uiSetVisible(true); |
|
236 }, this)); |
|
237 }, |
|
238 |
|
239 /** |
|
240 * Binds a listener to invoke the original visibility handling when the animHide animation is complete |
|
241 * |
|
242 * @method _bindAnimHide |
|
243 * @private |
|
244 */ |
|
245 _bindAnimHide : function() { |
|
246 // Setup original visibility handling (for hide) after completing animation |
|
247 this.get(ANIM_HIDE).after(END, |
|
248 Y.bind(function() { |
|
249 this._uiSetVisible(false); |
|
250 }, this)); |
|
251 } |
|
252 }); |
|
253 |
|
254 Y.namespace("Plugin").WidgetAnim = WidgetAnim; |
|
255 |
|
256 |
|
257 }, '@VERSION@', {"requires": ["anim-base", "plugin", "widget"]}); |