source: sipes/libraries/openlayers/examples/animator.js @ 92f109b

stableversion-3.0
Last change on this file since 92f109b was 307d09d, checked in by José Gregorio Puentes <jpuentes@…>, 8 años ago

se agregaron las librerias

  • Propiedad mode establecida a 100644
File size: 22.8 KB
Línea 
1/* 
2        Animator.js 1.1.9
3       
4        This library is released under the BSD license:
5
6        Copyright (c) 2006, Bernard Sumption. All rights reserved.
7       
8        Redistribution and use in source and binary forms, with or without
9        modification, are permitted provided that the following conditions are met:
10       
11        Redistributions of source code must retain the above copyright notice, this
12        list of conditions and the following disclaimer. Redistributions in binary
13        form must reproduce the above copyright notice, this list of conditions and
14        the following disclaimer in the documentation and/or other materials
15        provided with the distribution. Neither the name BernieCode nor
16        the names of its contributors may be used to endorse or promote products
17        derived from this software without specific prior written permission.
18       
19        THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20        AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21        IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22        ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
23        ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24        DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25        SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26        CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27        LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28        OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
29        DAMAGE.
30
31*/
32
33
34// Applies a sequence of numbers between 0 and 1 to a number of subjects
35// construct - see setOptions for parameters
36function Animator(options) {
37        this.setOptions(options);
38        var _this = this;
39        this.timerDelegate = function(){_this.onTimerEvent()};
40        this.subjects = [];
41        this.target = 0;
42        this.state = 0;
43        this.lastTime = null;
44};
45Animator.prototype = {
46        // apply defaults
47        setOptions: function(options) {
48                this.options = Animator.applyDefaults({
49                        interval: 20,  // time between animation frames
50                        duration: 400, // length of animation
51                        onComplete: function(){},
52                        onStep: function(){},
53                        transition: Animator.tx.easeInOut
54                }, options);
55        },
56        // animate from the current state to provided value
57        seekTo: function(to) {
58                this.seekFromTo(this.state, to);
59        },
60        // animate from the current state to provided value
61        seekFromTo: function(from, to) {
62                this.target = Math.max(0, Math.min(1, to));
63                this.state = Math.max(0, Math.min(1, from));
64                this.lastTime = new Date().getTime();
65                if (!this.intervalId) {
66                        this.intervalId = window.setInterval(this.timerDelegate, this.options.interval);
67                }
68        },
69        // animate from the current state to provided value
70        jumpTo: function(to) {
71                this.target = this.state = Math.max(0, Math.min(1, to));
72                this.propagate();
73        },
74        // seek to the opposite of the current target
75        toggle: function() {
76                this.seekTo(1 - this.target);
77        },
78        // add a function or an object with a method setState(state) that will be called with a number
79        // between 0 and 1 on each frame of the animation
80        addSubject: function(subject) {
81                this.subjects[this.subjects.length] = subject;
82                return this;
83        },
84        // remove all subjects
85        clearSubjects: function() {
86                this.subjects = [];
87        },
88        // forward the current state to the animation subjects
89        propagate: function() {
90                var value = this.options.transition(this.state);
91                for (var i=0; i<this.subjects.length; i++) {
92                        if (this.subjects[i].setState) {
93                                this.subjects[i].setState(value);
94                        } else {
95                                this.subjects[i](value);
96                        }
97                }
98        },
99        // called once per frame to update the current state
100        onTimerEvent: function() {
101                var now = new Date().getTime();
102                var timePassed = now - this.lastTime;
103                this.lastTime = now;
104                var movement = (timePassed / this.options.duration) * (this.state < this.target ? 1 : -1);
105                if (Math.abs(movement) >= Math.abs(this.state - this.target)) {
106                        this.state = this.target;
107                } else {
108                        this.state += movement;
109                }
110               
111                try {
112                        this.propagate();
113                } finally {
114                        this.options.onStep.call(this);
115                        if (this.target == this.state) {
116                                window.clearInterval(this.intervalId);
117                                this.intervalId = null;
118                                this.options.onComplete.call(this);
119                        }
120                }
121        },
122        // shortcuts
123        play: function() {this.seekFromTo(0, 1)},
124        reverse: function() {this.seekFromTo(1, 0)},
125        // return a string describing this Animator, for debugging
126        inspect: function() {
127                var str = "#<Animator:\n";
128                for (var i=0; i<this.subjects.length; i++) {
129                        str += this.subjects[i].inspect();
130                }
131                str += ">";
132                return str;
133        }
134};
135// merge the properties of two objects
136Animator.applyDefaults = function(defaults, prefs) {
137        prefs = prefs || {};
138        var prop, result = {};
139        for (prop in defaults) result[prop] = prefs[prop] !== undefined ? prefs[prop] : defaults[prop];
140        return result;
141};
142// make an array from any object
143Animator.makeArray = function(o) {
144        if (o == null) return [];
145        if (!o.length) return [o];
146        var result = [];
147        for (var i=0; i<o.length; i++) result[i] = o[i];
148        return result;
149};
150// convert a dash-delimited-property to a camelCaseProperty (c/o Prototype, thanks Sam!)
151Animator.camelize = function(string) {
152        var oStringList = string.split('-');
153        if (oStringList.length == 1) return oStringList[0];
154       
155        var camelizedString = string.indexOf('-') == 0
156                ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1)
157                : oStringList[0];
158       
159        for (var i = 1, len = oStringList.length; i < len; i++) {
160                var s = oStringList[i];
161                camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
162        }
163        return camelizedString;
164};
165// syntactic sugar for creating CSSStyleSubjects
166Animator.apply = function(el, style, options) {
167        if (style instanceof Array) {
168                return new Animator(options).addSubject(new CSSStyleSubject(el, style[0], style[1]));
169        }
170        return new Animator(options).addSubject(new CSSStyleSubject(el, style));
171};
172// make a transition function that gradually accelerates. pass a=1 for smooth
173// gravitational acceleration, higher values for an exaggerated effect
174Animator.makeEaseIn = function(a) {
175        return function(state) {
176                return Math.pow(state, a*2); 
177        }
178};
179// as makeEaseIn but for deceleration
180Animator.makeEaseOut = function(a) {
181        return function(state) {
182                return 1 - Math.pow(1 - state, a*2); 
183        }
184};
185// make a transition function that, like an object with momentum being attracted to a point,
186// goes past the target then returns
187Animator.makeElastic = function(bounces) {
188        return function(state) {
189                state = Animator.tx.easeInOut(state);
190                return ((1-Math.cos(state * Math.PI * bounces)) * (1 - state)) + state; 
191        }
192};
193// make an Attack Decay Sustain Release envelope that starts and finishes on the same level
194//
195Animator.makeADSR = function(attackEnd, decayEnd, sustainEnd, sustainLevel) {
196        if (sustainLevel == null) sustainLevel = 0.5;
197        return function(state) {
198                if (state < attackEnd) {
199                        return state / attackEnd;
200                }
201                if (state < decayEnd) {
202                        return 1 - ((state - attackEnd) / (decayEnd - attackEnd) * (1 - sustainLevel));
203                }
204                if (state < sustainEnd) {
205                        return sustainLevel;
206                }
207                return sustainLevel * (1 - ((state - sustainEnd) / (1 - sustainEnd)));
208        }
209};
210// make a transition function that, like a ball falling to floor, reaches the target and/
211// bounces back again
212Animator.makeBounce = function(bounces) {
213        var fn = Animator.makeElastic(bounces);
214        return function(state) {
215                state = fn(state); 
216                return state <= 1 ? state : 2-state;
217        }
218};
219 
220// pre-made transition functions to use with the 'transition' option
221Animator.tx = {
222        easeInOut: function(pos){
223                return ((-Math.cos(pos*Math.PI)/2) + 0.5);
224        },
225        linear: function(x) {
226                return x;
227        },
228        easeIn: Animator.makeEaseIn(1.5),
229        easeOut: Animator.makeEaseOut(1.5),
230        strongEaseIn: Animator.makeEaseIn(2.5),
231        strongEaseOut: Animator.makeEaseOut(2.5),
232        elastic: Animator.makeElastic(1),
233        veryElastic: Animator.makeElastic(3),
234        bouncy: Animator.makeBounce(1),
235        veryBouncy: Animator.makeBounce(3)
236};
237
238// animates a pixel-based style property between two integer values
239function NumericalStyleSubject(els, property, from, to, units) {
240        this.els = Animator.makeArray(els);
241        if (property == 'opacity' && window.ActiveXObject) {
242                this.property = 'filter';
243        } else {
244                this.property = Animator.camelize(property);
245        }
246        this.from = parseFloat(from);
247        this.to = parseFloat(to);
248        this.units = units != null ? units : 'px';
249}
250NumericalStyleSubject.prototype = {
251        setState: function(state) {
252                var style = this.getStyle(state);
253                var visibility = (this.property == 'opacity' && state == 0) ? 'hidden' : '';
254                var j=0;
255                for (var i=0; i<this.els.length; i++) {
256                        try {
257                                this.els[i].style[this.property] = style;
258                        } catch (e) {
259                                // ignore fontWeight - intermediate numerical values cause exeptions in firefox
260                                if (this.property != 'fontWeight') throw e;
261                        }
262                        if (j++ > 20) return;
263                }
264        },
265        getStyle: function(state) {
266                state = this.from + ((this.to - this.from) * state);
267                if (this.property == 'filter') return "alpha(opacity=" + Math.round(state*100) + ")";
268                if (this.property == 'opacity') return state;
269                return Math.round(state) + this.units;
270        },
271        inspect: function() {
272                return "\t" + this.property + "(" + this.from + this.units + " to " + this.to + this.units + ")\n";
273        }
274};
275
276// animates a colour based style property between two hex values
277function ColorStyleSubject(els, property, from, to) {
278        this.els = Animator.makeArray(els);
279        this.property = Animator.camelize(property);
280        this.to = this.expandColor(to);
281        this.from = this.expandColor(from);
282        this.origFrom = from;
283        this.origTo = to;
284}
285
286ColorStyleSubject.prototype = {
287        // parse "#FFFF00" to [256, 256, 0]
288        expandColor: function(color) {
289                var hexColor, red, green, blue;
290                hexColor = ColorStyleSubject.parseColor(color);
291                if (hexColor) {
292                        red = parseInt(hexColor.slice(1, 3), 16);
293                        green = parseInt(hexColor.slice(3, 5), 16);
294                        blue = parseInt(hexColor.slice(5, 7), 16);
295                        return [red,green,blue]
296                }
297                if (window.DEBUG) {
298                        alert("Invalid colour: '" + color + "'");
299                }
300        },
301        getValueForState: function(color, state) {
302                return Math.round(this.from[color] + ((this.to[color] - this.from[color]) * state));
303        },
304        setState: function(state) {
305                var color = '#'
306                                + ColorStyleSubject.toColorPart(this.getValueForState(0, state))
307                                + ColorStyleSubject.toColorPart(this.getValueForState(1, state))
308                                + ColorStyleSubject.toColorPart(this.getValueForState(2, state));
309                for (var i=0; i<this.els.length; i++) {
310                        this.els[i].style[this.property] = color;
311                }
312        },
313        inspect: function() {
314                return "\t" + this.property + "(" + this.origFrom + " to " + this.origTo + ")\n";
315        }
316};
317
318// return a properly formatted 6-digit hex colour spec, or false
319ColorStyleSubject.parseColor = function(string) {
320        var color = '#', match;
321        if(match = ColorStyleSubject.parseColor.rgbRe.exec(string)) {
322                var part;
323                for (var i=1; i<=3; i++) {
324                        part = Math.max(0, Math.min(255, parseInt(match[i])));
325                        color += ColorStyleSubject.toColorPart(part);
326                }
327                return color;
328        }
329        if (match = ColorStyleSubject.parseColor.hexRe.exec(string)) {
330                if(match[1].length == 3) {
331                        for (var i=0; i<3; i++) {
332                                color += match[1].charAt(i) + match[1].charAt(i);
333                        }
334                        return color;
335                }
336                return '#' + match[1];
337        }
338        return false;
339};
340// convert a number to a 2 digit hex string
341ColorStyleSubject.toColorPart = function(number) {
342        if (number > 255) number = 255;
343        var digits = number.toString(16);
344        if (number < 16) return '0' + digits;
345        return digits;
346};
347ColorStyleSubject.parseColor.rgbRe = /^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i;
348ColorStyleSubject.parseColor.hexRe = /^\#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
349
350// Animates discrete styles, i.e. ones that do not scale but have discrete values
351// that can't be interpolated
352function DiscreteStyleSubject(els, property, from, to, threshold) {
353        this.els = Animator.makeArray(els);
354        this.property = Animator.camelize(property);
355        this.from = from;
356        this.to = to;
357        this.threshold = threshold || 0.5;
358}
359
360DiscreteStyleSubject.prototype = {
361        setState: function(state) {
362                var j=0;
363                for (var i=0; i<this.els.length; i++) {
364                        this.els[i].style[this.property] = state <= this.threshold ? this.from : this.to; 
365                }
366        },
367        inspect: function() {
368                return "\t" + this.property + "(" + this.from + " to " + this.to + " @ " + this.threshold + ")\n";
369        }
370};
371
372// animates between two styles defined using CSS.
373// if style1 and style2 are present, animate between them, if only style1
374// is present, animate between the element's current style and style1
375function CSSStyleSubject(els, style1, style2) {
376        els = Animator.makeArray(els);
377        this.subjects = [];
378        if (els.length == 0) return;
379        var prop, toStyle, fromStyle;
380        if (style2) {
381                fromStyle = this.parseStyle(style1, els[0]);
382                toStyle = this.parseStyle(style2, els[0]);
383        } else {
384                toStyle = this.parseStyle(style1, els[0]);
385                fromStyle = {};
386                for (prop in toStyle) {
387                        fromStyle[prop] = CSSStyleSubject.getStyle(els[0], prop);
388                }
389        }
390        // remove unchanging properties
391        var prop;
392        for (prop in fromStyle) {
393                if (fromStyle[prop] == toStyle[prop]) {
394                        delete fromStyle[prop];
395                        delete toStyle[prop];
396                }
397        }
398        // discover the type (numerical or colour) of each style
399        var prop, units, match, type, from, to;
400        for (prop in fromStyle) {
401                var fromProp = String(fromStyle[prop]);
402                var toProp = String(toStyle[prop]);
403                if (toStyle[prop] == null) {
404                        if (window.DEBUG) alert("No to style provided for '" + prop + '"');
405                        continue;
406                }
407               
408                if (from = ColorStyleSubject.parseColor(fromProp)) {
409                        to = ColorStyleSubject.parseColor(toProp);
410                        type = ColorStyleSubject;
411                } else if (fromProp.match(CSSStyleSubject.numericalRe)
412                                && toProp.match(CSSStyleSubject.numericalRe)) {
413                        from = parseFloat(fromProp);
414                        to = parseFloat(toProp);
415                        type = NumericalStyleSubject;
416                        match = CSSStyleSubject.numericalRe.exec(fromProp);
417                        var reResult = CSSStyleSubject.numericalRe.exec(toProp);
418                        if (match[1] != null) {
419                                units = match[1];
420                        } else if (reResult[1] != null) {
421                                units = reResult[1];
422                        } else {
423                                units = reResult;
424                        }
425                } else if (fromProp.match(CSSStyleSubject.discreteRe)
426                                && toProp.match(CSSStyleSubject.discreteRe)) {
427                        from = fromProp;
428                        to = toProp;
429                        type = DiscreteStyleSubject;
430                        units = 0;   // hack - how to get an animator option down to here
431                } else {
432                        if (window.DEBUG) {
433                                alert("Unrecognised format for value of "
434                                        + prop + ": '" + fromStyle[prop] + "'");
435                        }
436                        continue;
437                }
438                this.subjects[this.subjects.length] = new type(els, prop, from, to, units);
439        }
440}
441
442CSSStyleSubject.prototype = {
443        // parses "width: 400px; color: #FFBB2E" to {width: "400px", color: "#FFBB2E"}
444        parseStyle: function(style, el) {
445                var rtn = {};
446                // if style is a rule set
447                if (style.indexOf(":") != -1) {
448                        var styles = style.split(";");
449                        for (var i=0; i<styles.length; i++) {
450                                var parts = CSSStyleSubject.ruleRe.exec(styles[i]);
451                                if (parts) {
452                                        rtn[parts[1]] = parts[2];
453                                }
454                        }
455                }
456                // else assume style is a class name
457                else {
458                        var prop, value, oldClass;
459                        oldClass = el.className;
460                        el.className = style;
461                        for (var i=0; i<CSSStyleSubject.cssProperties.length; i++) {
462                                prop = CSSStyleSubject.cssProperties[i];
463                                value = CSSStyleSubject.getStyle(el, prop);
464                                if (value != null) {
465                                        rtn[prop] = value;
466                                }
467                        }
468                        el.className = oldClass;
469                }
470                return rtn;
471               
472        },
473        setState: function(state) {
474                for (var i=0; i<this.subjects.length; i++) {
475                        this.subjects[i].setState(state);
476                }
477        },
478        inspect: function() {
479                var str = "";
480                for (var i=0; i<this.subjects.length; i++) {
481                        str += this.subjects[i].inspect();
482                }
483                return str;
484        }
485};
486// get the current value of a css property,
487CSSStyleSubject.getStyle = function(el, property){
488        var style;
489        if(document.defaultView && document.defaultView.getComputedStyle){
490                style = document.defaultView.getComputedStyle(el, "").getPropertyValue(property);
491                if (style) {
492                        return style;
493                }
494        }
495        property = Animator.camelize(property);
496        if(el.currentStyle){
497                style = el.currentStyle[property];
498        }
499        return style || el.style[property]
500};
501
502
503CSSStyleSubject.ruleRe = /^\s*([a-zA-Z\-]+)\s*:\s*(\S(.+\S)?)\s*$/;
504CSSStyleSubject.numericalRe = /^-?\d+(?:\.\d+)?(%|[a-zA-Z]{2})?$/;
505CSSStyleSubject.discreteRe = /^\w+$/;
506
507// required because the style object of elements isn't enumerable in Safari
508/*
509CSSStyleSubject.cssProperties = ['background-color','border','border-color','border-spacing',
510'border-style','border-top','border-right','border-bottom','border-left','border-top-color',
511'border-right-color','border-bottom-color','border-left-color','border-top-width','border-right-width',
512'border-bottom-width','border-left-width','border-width','bottom','color','font-size','font-size-adjust',
513'font-stretch','font-style','height','left','letter-spacing','line-height','margin','margin-top',
514'margin-right','margin-bottom','margin-left','marker-offset','max-height','max-width','min-height',
515'min-width','orphans','outline','outline-color','outline-style','outline-width','overflow','padding',
516'padding-top','padding-right','padding-bottom','padding-left','quotes','right','size','text-indent',
517'top','width','word-spacing','z-index','opacity','outline-offset'];*/
518
519
520CSSStyleSubject.cssProperties = ['azimuth','background','background-attachment','background-color','background-image','background-position','background-repeat','border-collapse','border-color','border-spacing','border-style','border-top','border-top-color','border-right-color','border-bottom-color','border-left-color','border-top-style','border-right-style','border-bottom-style','border-left-style','border-top-width','border-right-width','border-bottom-width','border-left-width','border-width','bottom','clear','clip','color','content','cursor','direction','display','elevation','empty-cells','css-float','font','font-family','font-size','font-size-adjust','font-stretch','font-style','font-variant','font-weight','height','left','letter-spacing','line-height','list-style','list-style-image','list-style-position','list-style-type','margin','margin-top','margin-right','margin-bottom','margin-left','max-height','max-width','min-height','min-width','orphans','outline','outline-color','outline-style','outline-width','overflow','padding','padding-top','padding-right','padding-bottom','padding-left','pause','position','right','size','table-layout','text-align','text-decoration','text-indent','text-shadow','text-transform','top','vertical-align','visibility','white-space','width','word-spacing','z-index','opacity','outline-offset','overflow-x','overflow-y'];
521
522
523// chains several Animator objects together
524function AnimatorChain(animators, options) {
525        this.animators = animators;
526        this.setOptions(options);
527        for (var i=0; i<this.animators.length; i++) {
528                this.listenTo(this.animators[i]);
529        }
530        this.forwards = false;
531        this.current = 0;
532}
533
534AnimatorChain.prototype = {
535        // apply defaults
536        setOptions: function(options) {
537                this.options = Animator.applyDefaults({
538                        // by default, each call to AnimatorChain.play() calls jumpTo(0) of each animator
539                        // before playing, which can cause flickering if you have multiple animators all
540                        // targeting the same element. Set this to false to avoid this.
541                        resetOnPlay: true
542                }, options);
543        },
544        // play each animator in turn
545        play: function() {
546                this.forwards = true;
547                this.current = -1;
548                if (this.options.resetOnPlay) {
549                        for (var i=0; i<this.animators.length; i++) {
550                                this.animators[i].jumpTo(0);
551                        }
552                }
553                this.advance();
554        },
555        // play all animators backwards
556        reverse: function() {
557                this.forwards = false;
558                this.current = this.animators.length;
559                if (this.options.resetOnPlay) {
560                        for (var i=0; i<this.animators.length; i++) {
561                                this.animators[i].jumpTo(1);
562                        }
563                }
564                this.advance();
565        },
566        // if we have just play()'d, then call reverse(), and vice versa
567        toggle: function() {
568                if (this.forwards) {
569                        this.seekTo(0);
570                } else {
571                        this.seekTo(1);
572                }
573        },
574        // internal: install an event listener on an animator's onComplete option
575        // to trigger the next animator
576        listenTo: function(animator) {
577                var oldOnComplete = animator.options.onComplete;
578                var _this = this;
579                animator.options.onComplete = function() {
580                        if (oldOnComplete) oldOnComplete.call(animator);
581                        _this.advance();
582                }
583        },
584        // play the next animator
585        advance: function() {
586                if (this.forwards) {
587                        if (this.animators[this.current + 1] == null) return;
588                        this.current++;
589                        this.animators[this.current].play();
590                } else {
591                        if (this.animators[this.current - 1] == null) return;
592                        this.current--;
593                        this.animators[this.current].reverse();
594                }
595        },
596        // this function is provided for drop-in compatibility with Animator objects,
597        // but only accepts 0 and 1 as target values
598        seekTo: function(target) {
599                if (target <= 0) {
600                        this.forwards = false;
601                        this.animators[this.current].seekTo(0);
602                } else {
603                        this.forwards = true;
604                        this.animators[this.current].seekTo(1);
605                }
606        }
607};
608
609// an Accordion is a class that creates and controls a number of Animators. An array of elements is passed in,
610// and for each element an Animator and a activator button is created. When an Animator's activator button is
611// clicked, the Animator and all before it seek to 0, and all Animators after it seek to 1. This can be used to
612// create the classic Accordion effect, hence the name.
613// see setOptions for arguments
614function Accordion(options) {
615        this.setOptions(options);
616        var selected = this.options.initialSection, current;
617        if (this.options.rememberance) {
618                current = document.location.hash.substring(1);
619        }
620        this.rememberanceTexts = [];
621        this.ans = [];
622        var _this = this;
623        for (var i=0; i<this.options.sections.length; i++) {
624                var el = this.options.sections[i];
625                var an = new Animator(this.options.animatorOptions);
626                var from = this.options.from + (this.options.shift * i);
627                var to = this.options.to + (this.options.shift * i);
628                an.addSubject(new NumericalStyleSubject(el, this.options.property, from, to, this.options.units));
629                an.jumpTo(0);
630                var activator = this.options.getActivator(el);
631                activator.index = i;
632                activator.onclick = function(){_this.show(this.index)};
633                this.ans[this.ans.length] = an;
634                this.rememberanceTexts[i] = activator.innerHTML.replace(/\s/g, "");
635                if (this.rememberanceTexts[i] === current) {
636                        selected = i;
637                }
638        }
639        this.show(selected);
640}
641
642Accordion.prototype = {
643        // apply defaults
644        setOptions: function(options) {
645                this.options = Object.extend({
646                        // REQUIRED: an array of elements to use as the accordion sections
647                        sections: null,
648                        // a function that locates an activator button element given a section element.
649                        // by default it takes a button id from the section's "activator" attibute
650                        getActivator: function(el) {return document.getElementById(el.getAttribute("activator"))},
651                        // shifts each animator's range, for example with options {from:0,to:100,shift:20}
652                        // the animators' ranges will be 0-100, 20-120, 40-140 etc.
653                        shift: 0,
654                        // the first page to show
655                        initialSection: 0,
656                        // if set to true, document.location.hash will be used to preserve the open section across page reloads
657                        rememberance: true,
658                        // constructor arguments to the Animator objects
659                        animatorOptions: {}
660                }, options || {});
661        },
662        show: function(section) {
663                for (var i=0; i<this.ans.length; i++) {
664                        this.ans[i].seekTo(i > section ? 1 : 0);
665                }
666                if (this.options.rememberance) {
667                        document.location.hash = this.rememberanceTexts[section];
668                }
669        }
670};
Nota: Vea TracBrowser para ayuda de uso del navegador del repositorio.