PageSourceSearch

https://www.truppealpine.eu/slide/jquery.cross-slide.js

js truppealpine.eu collected 2026-10-02 19:40:52 UTC 11,890 bytes, 360 lines download raw bytes

1/*
2 * Copyright 2007-2008 by Tobia Conforto <[email protected]>
3 *
4 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General
5 * Public License as published by the Free Software Foundation; either version 2 of the License, or (at your
6 * option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
9 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
10 * for more details.
11 *
12 * You should have received a copy of the GNU General Public License along with this program; if not, write to
13 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
14 *
15 * Versions: 0.1    2007-08-19  Initial release
16 *                  2008-08-21  Re-released under GPL v2
17 *           0.1.1  2008-09-18  Compatibility with prototype.js
18 *           0.2    2008-10-15  Linkable images, contributed by Tim Rainey <[email protected]>
19 */
20
21jQuery.fn.crossSlide = function(opts, plan) {
22	var self = this,
23			self_width = this.width(),
24			self_height = this.height();
25
26	// generic utilities
27	function format(str) {
28		for (var i = 1; i < arguments.length; i++)
29			str = str.replace(new RegExp('\\{' + (i-1) + '}', 'g'), arguments[i]);
30		return str;
31	}
32
33	function dump_obj(o) {
34		var s = '{ ';
35		for (var n in o)
36			s += n + ': ' + o[n] + ', ';
37		return (s == '{ ' ? '{}' : s.slice(0, -2) + ' }');
38	}
39
40	// first preload all the images, while getting their actual width and height
41	(function(proceed) {
42
43		var n_loaded = 0;
44		function loop(i, img) {
45			// for (i = 0; i < plan.length; i++) but with independent var i, img (for the closures)
46			img.onload = function(e) {
47				n_loaded++;
48				plan[i].width = img.width;
49				plan[i].height = img.height;
50				if (n_loaded == plan.length)
51					proceed();
52			}
53			img.src = plan[i].src;
54			if (i + 1 < plan.length)
55				loop(i + 1, new Image());
56		}
57		loop(0, new Image());
58
59	})(function() {  // then proceed
60
61		// utility to parse "from" and "to" parameters
62		function parse_position_param(param) {
63			var zoom = 1;
64			var tokens = param.replace(/^\s*|\s*$/g, '').split(/\s+/);
65			if (tokens.length > 3) throw new Error();
66			if (tokens[0] == 'center')
67				if (tokens.length == 1)
68					tokens = ['center', 'center'];
69				else if (tokens.length == 2 && tokens[1].match(/^[\d.]+x$/i))
70					tokens = ['center', 'center', tokens[1]];
71			if (tokens.length == 3)
72				zoom = parseFloat(tokens[2].match(/^([\d.]+)x$/i)[1]);
73			var pos = tokens[0] + ' ' + tokens[1];
74			if (pos == 'left top'      || pos == 'top left')      return { xrel:  0, yrel:  0, zoom: zoom };
75			if (pos == 'left center'   || pos == 'center left')   return { xrel:  0, yrel: .5, zoom: zoom };
76			if (pos == 'left bottom'   || pos == 'bottom left')   return { xrel:  0, yrel:  1, zoom: zoom };
77			if (pos == 'center top'    || pos == 'top center')    return { xrel: .5, yrel:  0, zoom: zoom };
78			if (pos == 'center center')                           return { xrel: .5, yrel: .5, zoom: zoom };
79			if (pos == 'center bottom' || pos == 'bottom center') return { xrel: .5, yrel:  1, zoom: zoom };
80			if (pos == 'right top'     || pos == 'top right')     return { xrel:  1, yrel:  0, zoom: zoom };
81			if (pos == 'right center'  || pos == 'center right')  return { xrel:  1, yrel: .5, zoom: zoom };
82			if (pos == 'right bottom'  || pos == 'bottom right')  return { xrel:  1, yrel:  1, zoom: zoom };
83			return {
84				xrel: parseInt(tokens[0].match(/^(\d+)%$/)[1]) / 100,
85				yrel: parseInt(tokens[1].match(/^(\d+)%$/)[1]) / 100,
86				zoom: zoom
87			};
88		}
89
90		// utility to compute the css for a given phase between p.from and p.to
91		// phase = 1: begin fade-in,  2: end fade-in,  3: begin fade-out,  4: end fade-out
92		function position_to_css(p, phase) {
93			switch (phase) {
94				case 1:
95					var pos = 0;
96					break;
97				case 2:
98					var pos = fade_ms / (p.time_ms + 2 * fade_ms);
99					break;
100				case 3:
101					var pos = 1 - fade_ms / (p.time_ms + 2 * fade_ms);
102					break;
103				case 4:
104					var pos = 1;
105					break;
106			}
107			return {
108				left:   Math.round(p.from.left   + pos * (p.to.left   - p.from.left  )),
109				top:    Math.round(p.from.top    + pos * (p.to.top    - p.from.top   )),
110				width:  Math.round(p.from.width  + pos * (p.to.width  - p.from.width )),
111				height: Math.round(p.from.height + pos * (p.to.height - p.from.height))
112			};
113		}
114
115		// check global params
116		if (! opts.fade)
117			throw 'Missing fade parameter.';
118		if (opts.speed && opts.sleep)
119			throw 'You cannot set both speed and sleep at the same time.';
120		// conversion from sec to ms; from px/sec to px/ms
121		var fade_ms = Math.round(opts.fade * 1000);
122		if (opts.sleep)
123			var sleep = Math.round(opts.sleep * 1000);
124		if (opts.speed)
125			var speed = opts.speed / 1000,
126					fade_px = Math.round(fade_ms * speed);
127
128		// a debug: true option may be added to get a dump of the generated JavaScript code
129		if (opts.debug)
130			var debug = jQuery('<pre><hr/></pre>');
131
132		// set container css
133		self.empty().css({
134			overflow: 'hidden',
135			padding: 0
136		});
137		if (! self.css('position').match(/absolute|relative|fixed/))
138			self.css({ position: 'relative' })
139
140		// prepare each image
141		for (var i = 0; i < plan.length; ++i) {
142
143			var p = plan[i];
144			if (! p.src)
145				throw format('Missing src parameter in picture {0}.', i + 1);
146
147			if (speed) { // speed/dir mode
148
149				// check parameters and translate speed/dir mode into full mode (from/to/time)
150				switch (p.dir) {
151					case 'up':
152						p.from = { xrel: .5, yrel: 0, zoom: 1 };
153						p.to   = { xrel: .5, yrel: 1, zoom: 1 };
154						var slide_px = p.height - self_height - 2 * fade_px;
155						break;
156					case 'down':
157						p.from = { xrel: .5, yrel: 1, zoom: 1 };
158						p.to   = { xrel: .5, yrel: 0, zoom: 1 };
159						var slide_px = p.height - self_height - 2 * fade_px;
160						break;
161					case 'left':
162						p.from = { xrel: 0, yrel: .5, zoom: 1 };
163						p.to   = { xrel: 1, yrel: .5, zoom: 1 };
164						var slide_px = p.width - self_width - 2 * fade_px;
165						break;
166					case 'right':
167						p.from = { xrel: 1, yrel: .5, zoom: 1 };
168						p.to   = { xrel: 0, yrel: .5, zoom: 1 };
169						var slide_px = p.width - self_width - 2 * fade_px;
170						break;
171					default:
172						throw format('Missing or malformed "dir" parameter in picture {0}.', i + 1);
173				}
174				if (slide_px <= 0)
175					throw format('Picture number {0} is too short for the desired fade duration.', i + 1);
176				p.time_ms = Math.round(slide_px / speed);
177
178			} else if (! sleep) { // full mode
179
180				// check and parse parameters
181				if (! p.from || ! p.to || ! p.time)
182					throw format('Missing either speed/sleep option, or from/to/time params in picture {0}.', i + 1);
183				try {
184					p.from = parse_position_param(p.from)
185				} catch (e) {
186					throw format('Malformed "from" parameter in picture {0}.', i + 1);
187				}
188				try {
189					p.to = parse_position_param(p.to)
190				} catch (e) {
191					throw format('Malformed "to" parameter in picture {0}.', i + 1);
192				}
193				if (! p.time)
194					throw format('Missing "time" parameter in picture {0}.', i + 1);
195				p.time_ms = Math.round(p.time * 1000)
196			}
197
198			// precalculate left/top/width/height bounding values
199			if (p.from)
200				jQuery.each([ p.from, p.to ], function(i, from_to) {
201					from_to.width  = Math.round(p.width  * from_to.zoom);
202					from_to.height = Math.round(p.height * from_to.zoom);
203					from_to.left   = Math.round((self_width  - from_to.width)  * from_to.xrel);
204					from_to.top    = Math.round((self_height - from_to.height) * from_to.yrel);
205				});
206
207			// append the image element to the container
208			var html = p.href
209					? format('<a href="{0}"><img src="{1}"/></a>', p.href, p.src)
210					: format('<img src="{0}"/>', p.src);
211			jQuery(html).appendTo(self).css({
212				position: 'absolute',
213				visibility: 'hidden'
214			});
215		}
216		speed = undefined;  // speed mode has now been translated to full mode
217
218		var imgs = self.children();
219
220		// show first image
221		imgs.eq(0).css({ visibility: 'visible' });
222		if (! sleep)
223			imgs.eq(0).css(position_to_css(plan[0], 2));
224
225		// create animation chain
226		function create_chain(i, chainf) {
227			// building the chain backwards, or inside out
228
229			if (i % 2 == 0) {
230				if (sleep) {
231
232					// still image sleep
233
234					var i_sleep = i / 2,
235							i_hide = (i_sleep - 1 + plan.length) % plan.length,
236							img_sleep = imgs.eq(i_sleep),
237							img_hide = imgs.eq(i_hide);
238
239					var newf = function() {
240						img_hide.css('visibility', 'hidden');
241						setTimeout(chainf, sleep);
242					};
243
244					if (debug)
245						debug.prepend('<hr/>'
246							+ format("img[{0}].css(visibility, hidden)\n", i_hide)
247							+ format("setTimeout(&#9660;, {0})", sleep));
248
249				} else {
250
251					// single image slide
252
253					var i_slide = i / 2,
254							i_hide = (i_slide - 1 + plan.length) % plan.length,
255							img_slide = imgs.eq(i_slide),
256							img_hide = imgs.eq(i_hide),
257							time = plan[i_slide].time_ms,
258							slide_anim = position_to_css(plan[i_slide], 3);
259
260					var newf = function() {
261						img_hide.css('visibility', 'hidden');
262						img_slide.animate(slide_anim, time, 'linear', chainf);
263					};
264
265					if (debug)
266						debug.prepend('<hr/>'
267							+ format("img[{0}].css(visibility, hidden)\n", i_hide)
268							+ format("img[{0}].animate({1}, {2}, linear, &#9660;)", i_slide, dump_obj(slide_anim), time));
269
270				}
271			} else {
272				if (sleep) {
273
274					// still image cross-fade
275
276					var i_from = Math.floor(i / 2),
277							i_to = Math.ceil(i / 2) % plan.length,
278							img_from = imgs.eq(i_from),
279							img_to = imgs.eq(i_to),
280							from_anim = {},
281							to_init = { visibility: 'visible' },
282							to_anim = {};
283
284					if (i_to > i_from) {
285						to_init.opacity = 0;
286						to_anim.opacity = 1;
287					} else {
288						from_anim.opacity = 0;
289					}
290
291					var newf = function() {
292						img_to.css(to_init);
293						if (from_anim.opacity != undefined)
294							img_from.animate(from_anim, fade_ms, 'linear', chainf);
295						else
296							img_to.animate(to_anim, fade_ms, 'linear', chainf);
297					};
298
299					if (debug)
300						debug.prepend('<hr/>'
301							+ format("img[{0}].css({1}
301)\n", i_to, dump_obj(to_init))
302							+ (from_anim.opacity != undefined
303								? format("img[{0}].animate({1}, {2}, linear, &#9660;)", i_from, dump_obj(from_anim), fade_ms)
304								: format("img[{0}].animate({1}, {2}, linear, &#9660;)", i_to, dump_obj(to_anim), fade_ms)));
305
306				} else {
307
308					// cross-slide + cross-fade
309
310					var i_from = Math.floor(i / 2),
311							i_to = Math.ceil(i / 2) % plan.length,
312							img_from = imgs.eq(i_from),
313							img_to = imgs.eq(i_to),
314							from_anim = position_to_css(plan[i_from], 4),
315							to_init = position_to_css(plan[i_to], 1),
316							to_anim = position_to_css(plan[i_to], 2);
317
318					if (i_to > i_from) {
319						to_init.opacity = 0;
320						to_anim.opacity = 1;
321					} else {
322						from_anim.opacity = 0;
323					}
324					to_init.visibility = 'visible';
325
326					var newf = function() {
327						img_from.animate(from_anim, fade_ms, 'linear');
328						img_to.css(to_init);
329						img_to.animate(to_anim, fade_ms, 'linear', chainf);
330					};
331
332					if (debug)
333						debug.prepend('<hr/>'
334							+ format("img[{0}].animate({1}, {2}, linear)\n", i_from, dump_obj(from_anim), fade_ms)
335							+ format("img[{0}].css({1})\n", i_to, dump_obj(to_init))
336							+ format("img[{0}].animate({1}, {2}, linear, &#9660;)", i_to, dump_obj(to_anim), fade_ms));
337
338				}
339			}
340			if (i > 0)
341				return create_chain(i - 1, newf);
342			else
343				return newf;
344		}
345		var animation = create_chain(plan.length * 2 - 1, function() { return animation(); });
346
347		// show debug window, if enabled
348		if (debug)
349			jQuery(window.open('', 'debug', 'width=600,height=500,menubar=no,toolbar=no,directories=no,'
350					+ 'location=no,status=no,scrollbars=yes,resizable=yes').document.body)
351				.empty()
352				.append(debug);
353
354		// start animation
355		animation();
356
357	});
358
359	return self;
360};

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.