Copy files from jekyll-asciidoc-quickstart
[web.git] / js / foundation / foundation.orbit.js
1 ;
2 (function ($, window, document, undefined) {
3 'use strict';
4
5 var noop = function () {
6 };
7
8 var Orbit = function (el, settings) {
9 // Don't reinitialize plugin
10 if (el.hasClass(settings.slides_container_class)) {
11 return this;
12 }
13
14 var self = this,
15 container,
16 slides_container = el,
17 number_container,
18 bullets_container,
19 timer_container,
20 idx = 0,
21 animate,
22 timer,
23 locked = false,
24 adjust_height_after = false;
25
26
27 self.slides = function () {
28 return slides_container.children(settings.slide_selector);
29 };
30
31 self.slides().first().addClass(settings.active_slide_class);
32
33 self.update_slide_number = function (index) {
34 if (settings.slide_number) {
35 number_container.find('span:first').text(parseInt(index) + 1);
36 number_container.find('span:last').text(self.slides().length);
37 }
38 if (settings.bullets) {
39 bullets_container.children().removeClass(settings.bullets_active_class);
40 $(bullets_container.children().get(index)).addClass(settings.bullets_active_class);
41 }
42 };
43
44 self.update_active_link = function (index) {
45 var link = $('[data-orbit-link="' + self.slides().eq(index).attr('data-orbit-slide') + '"]');
46 link.siblings().removeClass(settings.bullets_active_class);
47 link.addClass(settings.bullets_active_class);
48 };
49
50 self.build_markup = function () {
51 slides_container.wrap('<div class="' + settings.container_class + '"></div>');
52 container = slides_container.parent();
53 slides_container.addClass(settings.slides_container_class);
54
55 if (settings.stack_on_small) {
56 container.addClass(settings.stack_on_small_class);
57 }
58
59 if (settings.navigation_arrows) {
60 container.append($('<a href="#"><span></span></a>').addClass(settings.prev_class));
61 container.append($('<a href="#"><span></span></a>').addClass(settings.next_class));
62 }
63
64 if (settings.timer) {
65 timer_container = $('<div>').addClass(settings.timer_container_class);
66 timer_container.append('<span>');
67 timer_container.append($('<div>').addClass(settings.timer_progress_class));
68 timer_container.addClass(settings.timer_paused_class);
69 container.append(timer_container);
70 }
71
72 if (settings.slide_number) {
73 number_container = $('<div>').addClass(settings.slide_number_class);
74 number_container.append('<span></span> ' + settings.slide_number_text + ' <span></span>');
75 container.append(number_container);
76 }
77
78 if (settings.bullets) {
79 bullets_container = $('<ol>').addClass(settings.bullets_container_class);
80 container.append(bullets_container);
81 bullets_container.wrap('<div class="orbit-bullets-container"></div>');
82 self.slides().each(function (idx, el) {
83 var bullet = $('<li>').attr('data-orbit-slide', idx).on('click', self.link_bullet);
84 ;
85 bullets_container.append(bullet);
86 });
87 }
88
89 };
90
91 self._goto = function (next_idx, start_timer) {
92 // if (locked) {return false;}
93 if (next_idx === idx) {
94 return false;
95 }
96 if (typeof timer === 'object') {
97 timer.restart();
98 }
99 var slides = self.slides();
100
101 var dir = 'next';
102 locked = true;
103 if (next_idx < idx) {
104 dir = 'prev';
105 }
106 if (next_idx >= slides.length) {
107 if (!settings.circular) return false;
108 next_idx = 0;
109 } else if (next_idx < 0) {
110 if (!settings.circular) return false;
111 next_idx = slides.length - 1;
112 }
113
114 var current = $(slides.get(idx));
115 var next = $(slides.get(next_idx));
116
117 current.css('zIndex', 2);
118 current.removeClass(settings.active_slide_class);
119 next.css('zIndex', 4).addClass(settings.active_slide_class);
120
121 slides_container.trigger('before-slide-change.fndtn.orbit');
122 settings.before_slide_change();
123 self.update_active_link(next_idx);
124
125 var callback = function () {
126 var unlock = function () {
127 idx = next_idx;
128 locked = false;
129 if (start_timer === true) {
130 timer = self.create_timer();
131 timer.start();
132 }
133 self.update_slide_number(idx);
134 slides_container.trigger('after-slide-change.fndtn.orbit', [{
135 slide_number: idx,
136 total_slides: slides.length
137 }]);
138 settings.after_slide_change(idx, slides.length);
139 };
140 if (slides_container.height() != next.height() && settings.variable_height) {
141 slides_container.animate({'height': next.height()}, 250, 'linear', unlock);
142 } else {
143 unlock();
144 }
145 };
146
147 if (slides.length === 1) {
148 callback();
149 return false;
150 }
151
152 var start_animation = function () {
153 if (dir === 'next') {
154 animate.next(current, next, callback);
155 }
156 if (dir === 'prev') {
157 animate.prev(current, next, callback);
158 }
159 };
160
161 if (next.height() > slides_container.height() && settings.variable_height) {
162 slides_container.animate({'height': next.height()}, 250, 'linear', start_animation);
163 } else {
164 start_animation();
165 }
166 };
167
168 self.next = function (e) {
169 e.stopImmediatePropagation();
170 e.preventDefault();
171 self._goto(idx + 1);
172 };
173
174 self.prev = function (e) {
175 e.stopImmediatePropagation();
176 e.preventDefault();
177 self._goto(idx - 1);
178 };
179
180 self.link_custom = function (e) {
181 e.preventDefault();
182 var link = $(this).attr('data-orbit-link');
183 if ((typeof link === 'string') && (link = $.trim(link)) != '') {
184 var slide = container.find('[data-orbit-slide=' + link + ']');
185 if (slide.index() != -1) {
186 self._goto(slide.index());
187 }
188 }
189 };
190
191 self.link_bullet = function (e) {
192 var index = $(this).attr('data-orbit-slide');
193 if ((typeof index === 'string') && (index = $.trim(index)) != '') {
194 if (isNaN(parseInt(index))) {
195 var slide = container.find('[data-orbit-slide=' + index + ']');
196 if (slide.index() != -1) {
197 self._goto(slide.index() + 1);
198 }
199 }
200 else {
201 self._goto(parseInt(index));
202 }
203 }
204
205 }
206
207 self.timer_callback = function () {
208 self._goto(idx + 1, true);
209 }
210
211 self.compute_dimensions = function () {
212 var current = $(self.slides().get(idx));
213 var h = current.height();
214 if (!settings.variable_height) {
215 self.slides().each(function () {
216 if ($(this).height() > h) {
217 h = $(this).height();
218 }
219 });
220 }
221 slides_container.height(h);
222 };
223
224 self.create_timer = function () {
225 var t = new Timer(
226 container.find('.' + settings.timer_container_class),
227 settings,
228 self.timer_callback
229 );
230 return t;
231 };
232
233 self.stop_timer = function () {
234 if (typeof timer === 'object') timer.stop();
235 };
236
237 self.toggle_timer = function () {
238 var t = container.find('.' + settings.timer_container_class);
239 if (t.hasClass(settings.timer_paused_class)) {
240 if (typeof timer === 'undefined') {
241 timer = self.create_timer();
242 }
243 timer.start();
244 }
245 else {
246 if (typeof timer === 'object') {
247 timer.stop();
248 }
249 }
250 };
251
252 self.init = function () {
253 self.build_markup();
254 if (settings.timer) {
255 timer = self.create_timer();
256 Foundation.utils.image_loaded(this.slides().children('img'), timer.start);
257 }
258 animate = new FadeAnimation(settings, slides_container);
259 if (settings.animation === 'slide')
260 animate = new SlideAnimation(settings, slides_container);
261
262 container.on('click', '.' + settings.next_class, self.next);
263 container.on('click', '.' + settings.prev_class, self.prev);
264
265 if (settings.next_on_click) {
266 container.on('click', '.' + settings.slides_container_class + ' [data-orbit-slide]', self.link_bullet);
267 }
268
269 container.on('click', self.toggle_timer);
270 if (settings.swipe) {
271 container.on('touchstart.fndtn.orbit', function (e) {
272 if (!e.touches) {
273 e = e.originalEvent;
274 }
275 var data = {
276 start_page_x: e.touches[0].pageX,
277 start_page_y: e.touches[0].pageY,
278 start_time: (new Date()).getTime(),
279 delta_x: 0,
280 is_scrolling: undefined
281 };
282 container.data('swipe-transition', data);
283 e.stopPropagation();
284 })
285 .on('touchmove.fndtn.orbit', function (e) {
286 if (!e.touches) {
287 e = e.originalEvent;
288 }
289 // Ignore pinch/zoom events
290 if (e.touches.length > 1 || e.scale && e.scale !== 1) return;
291
292 var data = container.data('swipe-transition');
293 if (typeof data === 'undefined') {
294 data = {};
295 }
296
297 data.delta_x = e.touches[0].pageX - data.start_page_x;
298
299 if (typeof data.is_scrolling === 'undefined') {
300 data.is_scrolling = !!( data.is_scrolling || Math.abs(data.delta_x) < Math.abs(e.touches[0].pageY - data.start_page_y) );
301 }
302
303 if (!data.is_scrolling && !data.active) {
304 e.preventDefault();
305 var direction = (data.delta_x < 0) ? (idx + 1) : (idx - 1);
306 data.active = true;
307 self._goto(direction);
308 }
309 })
310 .on('touchend.fndtn.orbit', function (e) {
311 container.data('swipe-transition', {});
312 e.stopPropagation();
313 })
314 }
315 container.on('mouseenter.fndtn.orbit', function (e) {
316 if (settings.timer && settings.pause_on_hover) {
317 self.stop_timer();
318 }
319 })
320 .on('mouseleave.fndtn.orbit', function (e) {
321 if (settings.timer && settings.resume_on_mouseout) {
322 timer.start();
323 }
324 });
325
326 $(document).on('click', '[data-orbit-link]', self.link_custom);
327 $(window).on('load resize', self.compute_dimensions);
328 Foundation.utils.image_loaded(this.slides().children('img'), self.compute_dimensions);
329 Foundation.utils.image_loaded(this.slides().children('img'), function () {
330 container.prev('.' + settings.preloader_class).css('display', 'none');
331 self.update_slide_number(0);
332 self.update_active_link(0);
333 slides_container.trigger('ready.fndtn.orbit');
334 });
335 };
336
337 self.init();
338 };
339
340 var Timer = function (el, settings, callback) {
341 var self = this,
342 duration = settings.timer_speed,
343 progress = el.find('.' + settings.timer_progress_class),
344 start,
345 timeout,
346 left = -1;
347
348 this.update_progress = function (w) {
349 var new_progress = progress.clone();
350 new_progress.attr('style', '');
351 new_progress.css('width', w + '%');
352 progress.replaceWith(new_progress);
353 progress = new_progress;
354 };
355
356 this.restart = function () {
357 clearTimeout(timeout);
358 el.addClass(settings.timer_paused_class);
359 left = -1;
360 self.update_progress(0);
361 };
362
363 this.start = function () {
364 if (!el.hasClass(settings.timer_paused_class)) {
365 return true;
366 }
367 left = (left === -1) ? duration : left;
368 el.removeClass(settings.timer_paused_class);
369 start = new Date().getTime();
370 progress.animate({'width': '100%'}, left, 'linear');
371 timeout = setTimeout(function () {
372 self.restart();
373 callback();
374 }, left);
375 el.trigger('timer-started.fndtn.orbit')
376 };
377
378 this.stop = function () {
379 if (el.hasClass(settings.timer_paused_class)) {
380 return true;
381 }
382 clearTimeout(timeout);
383 el.addClass(settings.timer_paused_class);
384 var end = new Date().getTime();
385 left = left - (end - start);
386 var w = 100 - ((left / duration) * 100);
387 self.update_progress(w);
388 el.trigger('timer-stopped.fndtn.orbit');
389 };
390 };
391
392 var SlideAnimation = function (settings, container) {
393 var duration = settings.animation_speed;
394 var is_rtl = ($('html[dir=rtl]').length === 1);
395 var margin = is_rtl ? 'marginRight' : 'marginLeft';
396 var animMargin = {};
397 animMargin[margin] = '0%';
398
399 this.next = function (current, next, callback) {
400 current.animate({marginLeft: '-100%'}, duration);
401 next.animate(animMargin, duration, function () {
402 current.css(margin, '100%');
403 callback();
404 });
405 };
406
407 this.prev = function (current, prev, callback) {
408 current.animate({marginLeft: '100%'}, duration);
409 prev.css(margin, '-100%');
410 prev.animate(animMargin, duration, function () {
411 current.css(margin, '100%');
412 callback();
413 });
414 };
415 };
416
417 var FadeAnimation = function (settings, container) {
418 var duration = settings.animation_speed;
419 var is_rtl = ($('html[dir=rtl]').length === 1);
420 var margin = is_rtl ? 'marginRight' : 'marginLeft';
421
422 this.next = function (current, next, callback) {
423 next.css({'margin': '0%', 'opacity': '0.01'});
424 next.animate({'opacity': '1'}, duration, 'linear', function () {
425 current.css('margin', '100%');
426 callback();
427 });
428 };
429
430 this.prev = function (current, prev, callback) {
431 prev.css({'margin': '0%', 'opacity': '0.01'});
432 prev.animate({'opacity': '1'}, duration, 'linear', function () {
433 current.css('margin', '100%');
434 callback();
435 });
436 };
437 };
438
439
440 Foundation.libs = Foundation.libs || {};
441
442 Foundation.libs.orbit = {
443 name: 'orbit',
444
445 version: '5.5.0',
446
447 settings: {
448 animation: 'slide',
449 timer_speed: 10000,
450 pause_on_hover: true,
451 resume_on_mouseout: false,
452 next_on_click: true,
453 animation_speed: 500,
454 stack_on_small: false,
455 navigation_arrows: true,
456 slide_number: true,
457 slide_number_text: 'of',
458 container_class: 'orbit-container',
459 stack_on_small_class: 'orbit-stack-on-small',
460 next_class: 'orbit-next',
461 prev_class: 'orbit-prev',
462 timer_container_class: 'orbit-timer',
463 timer_paused_class: 'paused',
464 timer_progress_class: 'orbit-progress',
465 slides_container_class: 'orbit-slides-container',
466 preloader_class: 'preloader',
467 slide_selector: '*',
468 bullets_container_class: 'orbit-bullets',
469 bullets_active_class: 'active',
470 slide_number_class: 'orbit-slide-number',
471 caption_class: 'orbit-caption',
472 active_slide_class: 'active',
473 orbit_transition_class: 'orbit-transitioning',
474 bullets: true,
475 circular: true,
476 timer: true,
477 variable_height: false,
478 swipe: true,
479 before_slide_change: noop,
480 after_slide_change: noop
481 },
482
483 init: function (scope, method, options) {
484 var self = this;
485 this.bindings(method, options);
486 },
487
488 events: function (instance) {
489 var orbit_instance = new Orbit(this.S(instance), this.S(instance).data('orbit-init'));
490 this.S(instance).data(this.name + '-instance', orbit_instance);
491 },
492
493 reflow: function () {
494 var self = this;
495
496 if (self.S(self.scope).is('[data-orbit]')) {
497 var $el = self.S(self.scope);
498 var instance = $el.data(self.name + '-instance');
499 instance.compute_dimensions();
500 } else {
501 self.S('[data-orbit]', self.scope).each(function (idx, el) {
502 var $el = self.S(el);
503 var opts = self.data_options($el);
504 var instance = $el.data(self.name + '-instance');
505 instance.compute_dimensions();
506 });
507 }
508 }
509 };
510
511
512 }(jQuery, window, window.document));