2 * (c) 2005-2007 Richard Cowin (http://openrico.org)
4 * Rico is licensed under the Apache License, Version 2.0 (the "License"); you may not use this
5 * file except in compliance with the License. You may obtain a copy of the License at
6 * http://www.apache.org/licenses/LICENSE-2.0
9 Rico.animate = function(effect){
10 new Rico.Effect.Animator().play(effect, arguments[1]);
14 Rico.Effect.easeIn = function(step){
15 return Math.sqrt(step)
17 Rico.Effect.easeOut = function(step){
21 Rico.Stepping.easeIn = Rico.Effect.easeIn;
22 Rico.Stepping.easeOut = Rico.Effect.easeOut;
24 Rico.Effect.Animator = Class.create();
25 Rico.Effect.Animator.prototype = {
26 initialize : function(effect) {
27 this.animateMethod = this.animate.bind(this);
28 this.options = arguments[1] || {};
31 this.reset(effect, arguments[1]);
33 reset: function(effect){
35 if (arguments[1]) this.setOptions(arguments[1]);
36 this.stepsLeft = this.options.steps;
37 this.duration = this.options.duration;
39 setOptions: function(options){
40 this.options = Object.extend({
43 rate: function(steps){ return steps;}
46 play: function(effect) {
47 this.setOptions(arguments[1])
50 this.reset(effect, arguments[1]);
52 $H(effect).keys().each((function(e){
53 var effectClass = {fadeOut:Rico.Effect.FadeOut}[e];
54 this.reset(new effectClass(effect[e]));
60 this.stepsLeft = this.options.steps;
66 this.interupt = false;
67 if (this.stepsLeft >0)
73 if (this.stepsLeft <=0) {
74 if (this.effect.finish) this.effect.finish();
75 if (this.options.onFinish) this.options.onFinish();
79 clearTimeout(this.timer);
80 this.effect.step(this.options.rate(this.stepsLeft));
83 startNextStep: function() {
84 var stepDuration = Math.round(this.duration/this.stepsLeft) ;
85 this.duration -= stepDuration;
87 this.timer = setTimeout(this.animateMethod, stepDuration);
89 isPlaying: function(){
90 return this.stepsLeft != 0 && !this.interupt;
94 Rico.Effect.Group = Class.create();
95 Rico.Effect.Group.prototype = {
96 initialize: function(effects){
97 this.effects = effects;
99 step: function(stepsToGo){
100 this.effects.each(function(e){e.step(stepsToGo)});
103 this.effects.each(function(e){if (e.finish) e.finish()});
107 Rico.Effect.SizeAndPosition = Class.create();
108 Rico.Effect.SizeAndPosition.prototype = {
109 initialize: function(element, x, y, w, h) {
110 this.element = $(element);
111 this.x = x || this.element.offsetLeft;
112 this.y = y || this.element.offsetTop;
113 this.w = w || this.element.offsetWidth;
114 this.h = h || this.element.offsetHeight;
116 step: function(stepsToGo) {
117 var left = this.element.offsetLeft + ((this.x - this.element.offsetLeft)/stepsToGo) + "px"
118 var top = this.element.offsetTop + ((this.y - this.element.offsetTop)/stepsToGo) + "px"
119 var width = this.element.offsetWidth + ((this.w - this.element.offsetWidth)/stepsToGo) + "px"
120 var height = this.element.offsetHeight + ((this.h - this.element.offsetHeight)/stepsToGo) + "px"
121 var style = this.element.style;
125 style.height = height;
129 Rico.AccordionEffect = Class.create();
130 Rico.AccordionEffect.prototype = {
131 initialize: function(toClose, toOpen, height) {
132 this.toClose = toClose;
133 this.toOpen = toOpen;
134 /* if (!navigator.appVersion.match(/\bMSIE\b/)) {*/
135 Element.makeClipping(toOpen);
136 Element.makeClipping(toClose);
138 Rico.Controls.disableNativeControls(toClose);
139 Element.show(toOpen);
140 this.toOpen.style.height = "0px";
141 this.endHeight = height;
143 step: function(framesLeft) {
144 var cHeight = Math.max(1,this.toClose.offsetHeight - parseInt((parseInt(this.toClose.offsetHeight))/framesLeft));
145 var closeHeight = cHeight + "px";
146 var openHeight = (this.endHeight - cHeight) + "px"
147 this.toClose.style.height = closeHeight;
148 this.toOpen.style.height = openHeight;
151 Element.hide(this.toClose)
152 this.toOpen.style.height = this.endHeight + "px";
153 this.toClose.style.height = "0px";
154 /* if (!navigator.appVersion.match(/\bMSIE\b/)) {*/
155 Element.undoClipping(this.toOpen);
156 Element.undoClipping(this.toClose);
159 Rico.Controls.enableNativeControls(this.toOpen);
163 Rico.Effect.SizeFromBottom = Class.create()
164 Rico.Effect.SizeFromBottom.prototype = {
165 initialize: function(element, y, h) {
166 this.element = $(element);
167 this.y = y || this.element.offsetTop;
168 this.h = h || this.element.offsetHeight;
169 this.options = arguments[3] || {};
171 step: function(framesToGo) {
172 var top = this.element.offsetTop + ((this.y - this.element.offsetTop)/framesToGo) + "px"
173 var height = this.element.offsetHeight + ((this.h - this.element.offsetHeight)/framesToGo) + "px"
174 var style = this.element.style;
175 style.height = height;
180 Rico.Effect.Position = Class.create();
181 Rico.Effect.Position.prototype = {
182 initialize: function(element, x, y) {
183 this.element = $(element);
184 this.x = x || this.element.offsetLeft;
185 this.destTop = y || this.element.offsetTop;
187 step: function(stepsToGo) {
188 var left = this.element.offsetLeft + ((this.x - this.element.offsetLeft)/stepsToGo) + "px"
189 var top = this.element.offsetTop + ((this.destTop - this.element.offsetTop)/stepsToGo) + "px"
190 var style = this.element.style;
196 Rico.Effect.FadeTo = Class.create()
197 Rico.Effect.FadeTo.prototype = {
198 initialize: function(element, value){
199 this.element = element;
200 this.opacity = Element.getStyle(this.element, 'opacity') || 1.0;
201 this.target = Math.min(value, 1.0);
203 step: function(framesLeft) {
204 var curOpacity = Element.getStyle(this.element, 'opacity');
205 var newOpacity = curOpacity + (this.target - curOpacity)/framesLeft
206 Rico.Effect.setOpacity(this.element, Math.min(Math.max(0,newOpacity),1.0));
210 Rico.Effect.FadeOut = Class.create()
211 Rico.Effect.FadeOut.prototype = {
212 initialize: function(element){
213 this.effect = new Rico.Effect.FadeTo(element, 0.0)
215 step: function(framesLeft) {
216 this.effect.step(framesLeft);
220 Rico.Effect.FadeIn = Class.create()
221 Rico.Effect.FadeIn.prototype = {
222 initialize: function(element){
223 var options = arguments[1] || {}
224 var startValue = options.startValue || 0
225 Element.setStyle(element, 'opacity', startValue);
226 this.effect = new Rico.Effect.FadeTo(element, 1.0)
228 step: function(framesLeft) {
229 this.effect.step(framesLeft);
233 Rico.Effect.setOpacity= function(element, value) {
234 element.style.filter = "alpha(opacity:"+Math.round(value*100)+")";
235 element.style.opacity = value;
238 Rico.Effect.SizeFromTop = Class.create()
239 Rico.Effect.SizeFromTop.prototype = {
240 initialize: function(element, scrollElement, y, h) {
241 this.element = $(element);
242 this.h = h || this.element.offsetHeight;
243 // element.style.top = y;
244 this.scrollElement = scrollElement;
245 this.options = arguments[4] || {};
246 this.baseHeight = this.options.baseHeight || Math.max(this.h, this.element.offsetHeight)
248 step: function(framesToGo) {
249 var rawHeight = this.element.offsetHeight + ((this.h - this.element.offsetHeight)/framesToGo);
250 var height = rawHeight + "px"
251 var scroll = (rawHeight - this.baseHeight) + "px";
252 this.scrollElement.style.top = scroll;
253 this.element.style.height = height;
258 Rico.Effect.Height = Class.create()
259 Rico.Effect.Height.prototype = {
260 initialize: function(element, endHeight) {
261 this.element = element
262 this.endHeight = endHeight
264 step: function(stepsLeft) {
265 if (this.element.constructor != Array){
266 var height = this.element.offsetHeight + ((this.endHeight - this.element.offsetHeight)/stepsLeft) + "px"
267 this.element.style.height = height;
269 var height = this.element[0].offsetHeight + ((this.endHeight - this.element[0].offsetHeight)/stepsLeft) + "px"
270 this.element.each(function(e){e.style.height = height})
275 Rico.Effect.SizeWidth = Class.create();
276 Rico.Effect.SizeWidth.prototype = {
277 initialize: function(element, endWidth) {
278 this.element = element
279 this.endWidth = endWidth
281 step: function(stepsLeft) {
282 delta = Math.abs(this.endWidth - parseInt(this.element.offsetWidth))/(stepsLeft);
283 this.element.style.width = (this.element.offsetWidth - delta) + "px";
287 //these are to support non Safari browsers and keep controls from bleeding through on absolute positioned element.
292 disableNativeControls: function(element) {
293 Rico.Controls.defaultDisabler.disableNative(element);
295 enableNativeControls: function(element){
296 Rico.Controls.defaultDisabler.enableNative(element);
298 prepareForSizing: function(element){
299 Element.makeClipping(element)
300 Rico.Controls.disableNativeControls(element)
302 resetSizing: function(element){
303 Element.undoClipping(element)
304 Rico.Controls.enableNativeControls(element)
306 registerScrollSelectors: function(selectorSet) {
307 selectorSet.each(function(s){Rico.Controls.scrollSelectors.push(Rico.selector(s))});
311 Rico.Controls.Disabler = Class.create();
312 Rico.Controls.Disabler.prototype = {
313 initialize: function(){
314 this.options = Object.extend({
316 hidables: Rico.Controls.editors
317 }, arguments[0] || {});
319 disableNative: function(element) {
320 if (!(/Konqueror|Safari|KHTML/.test(navigator.userAgent))){
321 if (!navigator.appVersion.match(/\bMSIE\b/))
322 this.blockControls(element).each(function(e){Element.makeClipping(e)});
324 this.hidableControls(element).each(function(e){e.disable()});
327 enableNative: function(element){
328 if (!(/Konqueror|Safari|KHTML/.test(navigator.userAgent))){
329 if (!navigator.appVersion.match(/\bMSIE\b/))
330 this.blockControls(element).each(function(e){Element.undoClipping(e)});
332 this.hidableControls(element).each(function(e){e.enable()});
335 blockControls: function(element){
338 if (this.options.includeSet)
339 includes = this.options.includeSet;
341 var selectors = this.options.includeSelectors || Rico.Controls.scrollSelectors;
342 includes = selectors.map(function(s){return s.findAll(element)}).flatten();
344 return includes.select(function(e){return (Element.getStyle(e, 'display') != 'none') && !this.options.excludeSet.include(e)}.bind(this));
345 }catch(e) { return []}
347 hidableControls: function(element){
349 return this.options.hidables.select(function(e){return Element.childOf(e, element)});
351 return this.options.hidables;
355 Rico.Controls.defaultDisabler = new Rico.Controls.Disabler();
356 Rico.Controls.blankDisabler = new Rico.Controls.Disabler({includeSet:[],hidables:[]});
358 Rico.Controls.HidableInput = Class.create();
359 Rico.Controls.HidableInput.prototype = {
360 initialize: function(field, view){
364 Rico.Controls.editors.push(this);
367 Element.hide(this.view);
368 Element.show(this.field);
371 this.view.value = $F(this.field);
372 if (this.field.offsetWidth > 1) {
373 this.view.style.width = parseInt(this.field.offsetWidth) + "px";
374 Element.hide(this.field);
375 Element.show(this.view);
382 Element.forceRefresh = function(item) {
384 var n = document.createTextNode(' ')
385 item.appendChild(n); item.removeChild(n);
389 Rico.includeLoaded('ricoEffects.js');