PageSourceSearch

https://events.bostonguide.com/js/carousel.js

js bostonguide.com collected 2026-10-02 12:13:18 UTC 10,660 bytes, 327 lines download raw bytes

1/*
2Copyright (c) 2009 Victor Stanciu - https://www.victorstanciu.ro
3
4Permission is hereby granted, free of charge, to any person
5obtaining a copy of this software and associated documentation
6files (the "Software"), to deal in the Software without
7restriction, including without limitation the rights to use,
8copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the
10Software is furnished to do so, subject to the following
11conditions:
12
13The above copyright notice and this permission notice shall be
14included in all copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23OTHER DEALINGS IN THE SOFTWARE.
24*/
25
26Carousel = Class.create(Abstract, {
27	initialize: function (scroller, slides, controls, options) {
28		this.scrolling	= false;
29		this.scroller	= $(scroller);
30		this.slides		= slides;
31		this.controls	= controls;
32
33		this.options    = Object.extend({
34            duration:           1,
35            auto:               false,
36            frequency:          3,
37            visibleSlides:      1,
38            controlClassName:   'carousel-control',
39            jumperClassName:    'carousel-jumper',
40            disabledClassName:  'carousel-disabled',
41            selectedClassName:  'carousel-selected',
42            circular:           false,
43            wheel:              true,
44            effect:             'scroll',
45            transition:         'sinoidal'
46        }, options || {});
47        
48        if (this.options.effect == 'fade') {
49            this.options.circular = true;
50        }
51
52		this.slides.each(function(slide, index) {
53			slide._index = index;
54        });
55
56		if (this.controls) {
57            this.controls.invoke('observe', 'click', this.click.bind(this));
58        }
59        
60        if (this.options.wheel) {            
61            this.scroller.observe('mousewheel', this.wheel.bindAsEventListener(this)).observe('DOMMouseScroll', this.wheel.bindAsEventListener(this));;
62        }
63
64        if (this.options.auto) {
65            this.start();
66        }
67
68		if (this.options.initial) {
69			var initialIndex = this.slides.indexOf($(this.options.initial));
70			if (initialIndex > (this.options.visibleSlides - 1) && this.options.visibleSlides > 1) {               
71				if (initialIndex > this.slides.length - (this.options.visibleSlides + 1)) {
72					initialIndex = this.slides.length - this.options.visibleSlides;
73				}
74			}
75            this.moveTo(this.slides[initialIndex]);
76		}
77	},
78
79	click: function (event) {
80		this.stop();
81
82		var element = event.findElement('a');
83
84		if (!element.hasClassName(this.options.disabledClassName)) {
85			if (element.hasClassName(this.options.controlClassName)) {
86				eval("this." + element.rel + "()");
87            } else if (element.hasClassName(this.options.jumperClassName)) {
88                this.moveTo(element.rel);
89                if (this.options.selectedClassName) {
90                    this.controls.invoke('removeClassName', this.options.selectedClassName);
91                    element.addClassName(this.options.selectedClassName);
92                }
93            }
94        }
95
96		this.deactivateControls();
97
98		event.stop();
99    },
100
101	moveTo: function (element) {
102		if (this.options.beforeMove && (typeof this.options.beforeMove == 'function')) {
103			this.options.beforeMove();
104        }
105
106		this.previous = this.current ? this.current : this.slides[0];
107		this.current  = $(element);
108
109		var scrollerOffset = this.scroller.cumulativeOffset();
110		var elementOffset  = this.current.cumulativeOffset();
111
112		if (this.scrolling) {
113			this.scrolling.cancel();
114		}
115
116        switch (this.options.effect) {
117            case 'fade':               
118                this.scrolling = new Effect.Opacity(this.scroller, {
119                    from:   1.0,
120                    to:     0,
121                    duration: this.options.duration,
122                    afterFinish: (function () {
123                        this.scroller.scrollLeft = elementOffset[0] - scrollerOffset[0];
124                        this.scroller.scrollTop  = elementOffset[1] - scrollerOffset[1];
125
126                        new Effect.Opacity(this.scroller, {
127                            from: 0,
128                            to: 1.0,
129                            duration: this.options.duration,
130                            afterFinish: (function () {
131                                if (this.controls) {
132                                    this.activateControls();
133                                }
134                                if (this.options.afterMove && (typeof this.options.afterMove == 'function')) {
135                                    this.options.afterMove();
136                                }
137                            }).bind(this)
138                        });
139                    }
140                ).bind(this)});
141            break;
142            case 'scroll':
143            default:
144                var transition;
145                switch (this.options.transition) {
146                    case 'spring':
147                        transition = Effect.Transitions.spring;
148                        break;
149                    case 'sinoidal':
150                    default:
151                        transition = Effect.Transitions.sinoidal;
152                        break;
153                }
154
155                this.scrolling = new Effect.SmoothScroll(this.scroller, {
156                    duration: this.options.duration,
157                    x: (elementOffset[0] - scrollerOffset[0]),
158                    y: (elementOffset[1] - scrollerOffset[1]),
159                    transition: transition,
160                    afterFinish: (function () {
161                        if (this.controls) {
162                            this.activateControls();
163                        }
164                        if (this.options.afterMove && (typeof this.options.afterMove == 'function')) {
165                            this.options.afterMove();
166                        }                        
167                        this.scrolling = false;
168                    }).bind(this)});
169            break;
170        }
171
172		return false;
173	},
174
175	prev: function () {
176		if (this.current) {
177			var currentIndex = this.current._index;
178			var prevIndex = (currentIndex == 0) ? (this.options.circular ? this.slides.length - 1 : 0) : currentIndex - 1;
179        } else {
180            var prevIndex = (this.options.circular ? this.slides.length - 1 : 0);
181        }
182
183		if (prevIndex == (this.slides.length - 1) && this.options.circular && this.options.effect != 'fade') {
184			this.scroller.scrollLeft =  (this.slides.length - 1) * this.slides.first().getWidth();
185			this.scroller.scrollTop =  (this.slides.length - 1) * this.slides.first().getHeight();
186			prevIndex = this.slides.length - 2;
187        }
188
189		this.moveTo(this.slides[prevIndex]);
190	},
191
192	next: function () {
193		if (this.current) {
194			var currentIndex = this.current._index;
195			var nextIndex = (this.slides.length - 1 == currentIndex) ? (this.options.circular ? 0 : currentIndex) : currentIndex + 1;
196        } else {
197            var nextIndex = 1;
198        }
199
200		if (nextIndex == 0 && this.options.circular && this.options.effect != 'fade') {
201			this.scroller.scrollLeft = 0;
202			this.scroller.scrollTop  = 0;
203			nextIndex = 1;
204        }
205
206		if (nextIndex > this.slides.length - (this.options.visibleSlides + 1)) {
207			nextIndex = this.slides.length - this.options.visibleSlides;
208		}		
209
210		this.moveTo(this.slides[nextIndex]);
211	},
212
213	first: function () {
214		this.moveTo(this.slides[0]);
215    },
216
217	last: function () {
218		this.moveTo(this.slides[this.slides.length - 1]);
219    },
220
221	toggle: function () {
222		if (this.previous) {
223			this.moveTo(this.slides[this.previous._index]);
224        } else {
225            return false;
226        }
227    },
228
229	stop: function () {
230		if (this.timer) {
231			clearTimeout(this.timer);
232		}
233	},
234
235	start: function () { 
236        this.periodicallyUpdate();
237    },
238
239	pause: function () {
240		this.stop();
241		this.activateControls();
242    },
243
244	resume: function (event) {
245		if (event) {
246			var related = event.relatedTarget || event.toElement;
247			if (!related || (!this.slides.include(related) && !this.slides.any(function (slide) { return related.descendantOf(slide); }))) {
248				this.start();
249            }
250        } else {
251            this.start();
252        }
253    },
254
255	periodicallyUpdate: function () {
256		if (this.timer != null) {
257			clearTimeout(this.timer);
258			this.next();
259        }
260		this.timer = setTimeout(this.periodicallyUpdate.bind(this), this.options.frequency * 1000);
261    },
262    
263    wheel: function (event) {
264        event.cancelBubble = true;
265        event.stop();
266        
267		var delta = 0;
268		if (!event) {
269            event = window.event;
270        }
271		if (event.wheelDelta) {
272			delta = event.wheelDelta / 120; 
273		} else if (event.detail) { 
274            delta = -event.detail / 3;	
275        }        
276       
277        if (!this.scrolling) {
278            this.deactivateControls();
279            if (delta > 0) {
280                this.prev();
281            } else {
282                this.next();
283            }            
284        }
285        
286		return Math.round(delta); //Safari Round
287    },
288
289	deactivateControls: function () {
290		this.controls.invoke('addClassName', this.options.disabledClassName);
291    },
292
293	activateControls: function () {
294		this.controls.invoke('removeClassName', this.options.disabledClassName);
295    }
296});
297
298
299Effect.SmoothScroll = Class.create();
300Object.extend(Object.extend(Effect.SmoothScroll.prototype, Effect.Base.prototype), {
301	initialize: function (element) {
302		this.element = $(element);
303		var options = Object.extend({ x: 0, y: 0, mode: 'absolute' } , arguments[1] || {});
304		this.start(options);
305    },
306
307	setup: function () {
308		if (this.options.continuous && !this.element._ext) {
309			this.element.cleanWhitespace();
310			this.element._ext = true;
311			this.element.appendChild(this.element.firstChild);
312        }
313
314		this.originalLeft = this.element.scrollLeft;
315		this.originalTop  = this.element.scrollTop;
316
317		if (this.options.mode == 'absolute') {
318			this.options.x -= this.originalLeft;
319			this.options.y -= this.originalTop;
320        }
321    },
322
323	update: function (position) {
324		this.element.scrollLeft = this.options.x * position + this.originalLeft;
325		this.element.scrollTop  = this.options.y * position + this.originalTop;
326    }
327});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.