summaryrefslogtreecommitdiff
path: root/js/components/slideshow.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/components/slideshow.js')
-rwxr-xr-xjs/components/slideshow.js560
1 files changed, 560 insertions, 0 deletions
diff --git a/js/components/slideshow.js b/js/components/slideshow.js
new file mode 100755
index 0000000..88cd4e7
--- /dev/null
+++ b/js/components/slideshow.js
@@ -0,0 +1,560 @@
1/*! UIkit 2.26.4 | http://www.getuikit.com | (c) 2014 YOOtheme | MIT License */
2(function(addon) {
3
4 var component;
5
6 if (window.UIkit) {
7 component = addon(UIkit);
8 }
9
10 if (typeof define == "function" && define.amd) {
11 define("uikit-slideshow", ["uikit"], function() {
12 return component || addon(UIkit);
13 });
14 }
15
16})(function(UI) {
17
18 "use strict";
19
20 var Animations, playerId = 0;
21
22 UI.component('slideshow', {
23
24 defaults: {
25 animation : "fade",
26 duration : 500,
27 height : "auto",
28 start : 0,
29 autoplay : false,
30 autoplayInterval : 7000,
31 videoautoplay : true,
32 videomute : true,
33 slices : 15,
34 pauseOnHover : true,
35 kenburns : false,
36 kenburnsanimations : [
37 'uk-animation-middle-left',
38 'uk-animation-top-right',
39 'uk-animation-bottom-left',
40 'uk-animation-top-center',
41 '', // middle-center
42 'uk-animation-bottom-right'
43 ]
44 },
45
46 current : false,
47 interval : null,
48 hovering : false,
49
50 boot: function() {
51
52 // init code
53 UI.ready(function(context) {
54
55 UI.$('[data-uk-slideshow]', context).each(function() {
56
57 var slideshow = UI.$(this);
58
59 if (!slideshow.data("slideshow")) {
60 UI.slideshow(slideshow, UI.Utils.options(slideshow.attr("data-uk-slideshow")));
61 }
62 });
63 });
64 },
65
66 init: function() {
67
68 var $this = this, canvas, kbanimduration;
69
70 this.container = this.element.hasClass('uk-slideshow') ? this.element : UI.$(this.find('.uk-slideshow:first'));
71 this.slides = this.container.children();
72 this.slidesCount = this.slides.length;
73 this.current = this.options.start;
74 this.animating = false;
75 this.triggers = this.find('[data-uk-slideshow-item]');
76 this.fixFullscreen = navigator.userAgent.match(/(iPad|iPhone|iPod)/g) && this.container.hasClass('uk-slideshow-fullscreen'); // viewport unit fix for height:100vh - should be fixed in iOS 8
77
78 if (this.options.kenburns) {
79
80 kbanimduration = this.options.kenburns === true ? '15s': this.options.kenburns;
81
82 if (!String(kbanimduration).match(/(ms|s)$/)) {
83 kbanimduration += 'ms';
84 }
85
86 if (typeof(this.options.kenburnsanimations) == 'string') {
87 this.options.kenburnsanimations = this.options.kenburnsanimations.split(',');
88 }
89 }
90
91 this.slides.each(function(index) {
92
93 var slide = UI.$(this),
94 media = slide.children('img,video,iframe').eq(0);
95
96 slide.data('media', media);
97 slide.data('sizer', media);
98
99 if (media.length) {
100
101 var placeholder;
102
103 switch(media[0].nodeName) {
104 case 'IMG':
105
106 var cover = UI.$('<div class="uk-cover-background uk-position-cover"></div>').css({'background-image':'url('+ media.attr('src') + ')'});
107
108 if (media.attr('width') && media.attr('height')) {
109 placeholder = UI.$('<canvas></canvas>').attr({width:media.attr('width'), height:media.attr('height')});
110 media.replaceWith(placeholder);
111 media = placeholder;
112 placeholder = undefined;
113 }
114
115 media.css({width: '100%',height: 'auto', opacity:0});
116 slide.prepend(cover).data('cover', cover);
117 break;
118
119 case 'IFRAME':
120
121 var src = media[0].src, iframeId = 'sw-'+(++playerId);
122
123 media
124 .attr('src', '').on('load', function(){
125
126 if (index !== $this.current || (index == $this.current && !$this.options.videoautoplay)) {
127 $this.pausemedia(media);
128 }
129
130 if ($this.options.videomute) {
131
132 $this.mutemedia(media);
133
134 var inv = setInterval((function(ic) {
135 return function() {
136 $this.mutemedia(media);
137 if (++ic >= 4) clearInterval(inv);
138 }
139 })(0), 250);
140 }
141
142 })
143 .data('slideshow', $this) // add self-reference for the vimeo-ready listener
144 .attr('data-player-id', iframeId) // add frameId for the vimeo-ready listener
145 .attr('src', [src, (src.indexOf('?') > -1 ? '&':'?'), 'enablejsapi=1&api=1&player_id='+iframeId].join(''))
146 .addClass('uk-position-absolute');
147
148 // disable pointer events
149 if(!UI.support.touch) media.css('pointer-events', 'none');
150
151 placeholder = true;
152
153 if (UI.cover) {
154 UI.cover(media);
155 media.attr('data-uk-cover', '{}');
156 }
157
158 break;
159
160 case 'VIDEO':
161 media.addClass('uk-cover-object uk-position-absolute');
162 placeholder = true;
163
164 if ($this.options.videomute) $this.mutemedia(media);
165 }
166
167 if (placeholder) {
168
169 canvas = UI.$('<canvas></canvas>').attr({'width': media[0].width, 'height': media[0].height});
170 var img = UI.$('<img style="width:100%;height:auto;">').attr('src', canvas[0].toDataURL());
171
172 slide.prepend(img);
173 slide.data('sizer', img);
174 }
175
176 } else {
177 slide.data('sizer', slide);
178 }
179
180 if ($this.hasKenBurns(slide)) {
181
182 slide.data('cover').css({
183 '-webkit-animation-duration': kbanimduration,
184 'animation-duration': kbanimduration
185 });
186 }
187 });
188
189 this.on("click.uk.slideshow", '[data-uk-slideshow-item]', function(e) {
190
191 e.preventDefault();
192
193 var slide = UI.$(this).attr('data-uk-slideshow-item');
194
195 if ($this.current == slide) return;
196
197 switch(slide) {
198 case 'next':
199 case 'previous':
200 $this[slide=='next' ? 'next':'previous']();
201 break;
202 default:
203 $this.show(parseInt(slide, 10));
204 }
205
206 $this.stop();
207 });
208
209 // Set start slide
210 this.slides.attr('aria-hidden', 'true').eq(this.current).addClass('uk-active').attr('aria-hidden', 'false');
211 this.triggers.filter('[data-uk-slideshow-item="'+this.current+'"]').addClass('uk-active');
212
213 UI.$win.on("resize load", UI.Utils.debounce(function() {
214 $this.resize();
215
216 if ($this.fixFullscreen) {
217 $this.container.css('height', window.innerHeight);
218 $this.slides.css('height', window.innerHeight);
219 }
220 }, 100));
221
222 // chrome image load fix
223 setTimeout(function(){
224 $this.resize();
225 }, 80);
226
227 // Set autoplay
228 if (this.options.autoplay) {
229 this.start();
230 }
231
232 if (this.options.videoautoplay && this.slides.eq(this.current).data('media')) {
233 this.playmedia(this.slides.eq(this.current).data('media'));
234 }
235
236 if (this.options.kenburns) {
237 this.applyKenBurns(this.slides.eq(this.current));
238 }
239
240 this.container.on({
241 mouseenter: function() { if ($this.options.pauseOnHover) $this.hovering = true; },
242 mouseleave: function() { $this.hovering = false; }
243 });
244
245 this.on('swipeRight swipeLeft', function(e) {
246 $this[e.type=='swipeLeft' ? 'next' : 'previous']();
247 });
248
249 this.on('display.uk.check', function(){
250 if ($this.element.is(":visible")) {
251
252 $this.resize();
253
254 if ($this.fixFullscreen) {
255 $this.container.css('height', window.innerHeight);
256 $this.slides.css('height', window.innerHeight);
257 }
258 }
259 });
260 },
261
262
263 resize: function() {
264
265 if (this.container.hasClass('uk-slideshow-fullscreen')) return;
266
267 var height = this.options.height;
268
269 if (this.options.height === 'auto') {
270
271 height = 0;
272
273 this.slides.css('height', '').each(function() {
274 height = Math.max(height, UI.$(this).height());
275 });
276 }
277
278 this.container.css('height', height);
279 this.slides.css('height', height);
280 },
281
282 show: function(index, direction) {
283
284 if (this.animating || this.current == index) return;
285
286 this.animating = true;
287
288 var $this = this,
289 current = this.slides.eq(this.current),
290 next = this.slides.eq(index),
291 dir = direction ? direction : this.current < index ? 1 : -1,
292 currentmedia = current.data('media'),
293 animation = Animations[this.options.animation] ? this.options.animation : 'fade',
294 nextmedia = next.data('media'),
295 finalize = function() {
296
297 if (!$this.animating) return;
298
299 if (currentmedia && currentmedia.is('video,iframe')) {
300 $this.pausemedia(currentmedia);
301 }
302
303 if (nextmedia && nextmedia.is('video,iframe')) {
304 $this.playmedia(nextmedia);
305 }
306
307 next.addClass("uk-active").attr('aria-hidden', 'false');
308 current.removeClass("uk-active").attr('aria-hidden', 'true');
309
310 $this.animating = false;
311 $this.current = index;
312
313 UI.Utils.checkDisplay(next, '[class*="uk-animation-"]:not(.uk-cover-background.uk-position-cover)');
314
315 $this.trigger('show.uk.slideshow', [next, current, $this]);
316 };
317
318 $this.applyKenBurns(next);
319
320 // animation fallback
321 if (!UI.support.animation) {
322 animation = 'none';
323 }
324
325 current = UI.$(current);
326 next = UI.$(next);
327
328 $this.trigger('beforeshow.uk.slideshow', [next, current, $this]);
329
330 Animations[animation].apply(this, [current, next, dir]).then(finalize);
331
332 $this.triggers.removeClass('uk-active');
333 $this.triggers.filter('[data-uk-slideshow-item="'+index+'"]').addClass('uk-active');
334 },
335
336 applyKenBurns: function(slide) {
337
338 if (!this.hasKenBurns(slide)) {
339 return;
340 }
341
342 var animations = this.options.kenburnsanimations,
343 index = this.kbindex || 0;
344
345
346 slide.data('cover').attr('class', 'uk-cover-background uk-position-cover').width();
347 slide.data('cover').addClass(['uk-animation-scale', 'uk-animation-reverse', animations[index].trim()].join(' '));
348
349 this.kbindex = animations[index + 1] ? (index+1):0;
350 },
351
352 hasKenBurns: function(slide) {
353 return (this.options.kenburns && slide.data('cover'));
354 },
355
356 next: function() {
357 this.show(this.slides[this.current + 1] ? (this.current + 1) : 0, 1);
358 },
359
360 previous: function() {
361 this.show(this.slides[this.current - 1] ? (this.current - 1) : (this.slides.length - 1), -1);
362 },
363
364 start: function() {
365
366 this.stop();
367
368 var $this = this;
369
370 this.interval = setInterval(function() {
371 if (!$this.hovering) $this.next();
372 }, this.options.autoplayInterval);
373
374 },
375
376 stop: function() {
377 if (this.interval) clearInterval(this.interval);
378 },
379
380 playmedia: function(media) {
381
382 if (!(media && media[0])) return;
383
384 switch(media[0].nodeName) {
385 case 'VIDEO':
386
387 if (!this.options.videomute) {
388 media[0].muted = false;
389 }
390
391 media[0].play();
392 break;
393 case 'IFRAME':
394
395 if (!this.options.videomute) {
396 media[0].contentWindow.postMessage('{ "event": "command", "func": "unmute", "method":"setVolume", "value":1}', '*');
397 }
398
399 media[0].contentWindow.postMessage('{ "event": "command", "func": "playVideo", "method":"play"}', '*');
400 break;
401 }
402 },
403
404 pausemedia: function(media) {
405
406 switch(media[0].nodeName) {
407 case 'VIDEO':
408 media[0].pause();
409 break;
410 case 'IFRAME':
411 media[0].contentWindow.postMessage('{ "event": "command", "func": "pauseVideo", "method":"pause"}', '*');
412 break;
413 }
414 },
415
416 mutemedia: function(media) {
417
418 switch(media[0].nodeName) {
419 case 'VIDEO':
420 media[0].muted = true;
421 break;
422 case 'IFRAME':
423 media[0].contentWindow.postMessage('{ "event": "command", "func": "mute", "method":"setVolume", "value":0}', '*');
424 break;
425 }
426 }
427 });
428
429 Animations = {
430
431 'none': function() {
432
433 var d = UI.$.Deferred();
434 d.resolve();
435 return d.promise();
436 },
437
438 'scroll': function(current, next, dir) {
439
440 var d = UI.$.Deferred();
441
442 current.css('animation-duration', this.options.duration+'ms');
443 next.css('animation-duration', this.options.duration+'ms');
444
445 next.css('opacity', 1).one(UI.support.animation.end, function() {
446
447 current.css('opacity', 0).removeClass(dir == -1 ? 'uk-slideshow-scroll-backward-out' : 'uk-slideshow-scroll-forward-out');
448 next.removeClass(dir == -1 ? 'uk-slideshow-scroll-backward-in' : 'uk-slideshow-scroll-forward-in');
449 d.resolve();
450
451 }.bind(this));
452
453 current.addClass(dir == -1 ? 'uk-slideshow-scroll-backward-out' : 'uk-slideshow-scroll-forward-out');
454 next.addClass(dir == -1 ? 'uk-slideshow-scroll-backward-in' : 'uk-slideshow-scroll-forward-in');
455 next.width(); // force redraw
456
457 return d.promise();
458 },
459
460 'swipe': function(current, next, dir) {
461
462 var d = UI.$.Deferred();
463
464 current.css('animation-duration', this.options.duration+'ms');
465 next.css('animation-duration', this.options.duration+'ms');
466
467 next.css('opacity', 1).one(UI.support.animation.end, function() {
468
469 current.css('opacity', 0).removeClass(dir === -1 ? 'uk-slideshow-swipe-backward-out' : 'uk-slideshow-swipe-forward-out');
470 next.removeClass(dir === -1 ? 'uk-slideshow-swipe-backward-in' : 'uk-slideshow-swipe-forward-in');
471 d.resolve();
472
473 }.bind(this));
474
475 current.addClass(dir == -1 ? 'uk-slideshow-swipe-backward-out' : 'uk-slideshow-swipe-forward-out');
476 next.addClass(dir == -1 ? 'uk-slideshow-swipe-backward-in' : 'uk-slideshow-swipe-forward-in');
477 next.width(); // force redraw
478
479 return d.promise();
480 },
481
482 'scale': function(current, next, dir) {
483
484 var d = UI.$.Deferred();
485
486 current.css('animation-duration', this.options.duration+'ms');
487 next.css('animation-duration', this.options.duration+'ms');
488
489 next.css('opacity', 1);
490
491 current.one(UI.support.animation.end, function() {
492
493 current.css('opacity', 0).removeClass('uk-slideshow-scale-out');
494 d.resolve();
495
496 }.bind(this));
497
498 current.addClass('uk-slideshow-scale-out');
499 current.width(); // force redraw
500
501 return d.promise();
502 },
503
504 'fade': function(current, next, dir) {
505
506 var d = UI.$.Deferred();
507
508 current.css('animation-duration', this.options.duration+'ms');
509 next.css('animation-duration', this.options.duration+'ms');
510
511 next.css('opacity', 1);
512
513 // for plain text content slides - looks smoother
514 if (!(next.data('cover') || next.data('placeholder'))) {
515
516 next.css('opacity', 1).one(UI.support.animation.end, function() {
517 next.removeClass('uk-slideshow-fade-in');
518 }).addClass('uk-slideshow-fade-in');
519 }
520
521 current.one(UI.support.animation.end, function() {
522
523 current.css('opacity', 0).removeClass('uk-slideshow-fade-out');
524 d.resolve();
525
526 }.bind(this));
527
528 current.addClass('uk-slideshow-fade-out');
529 current.width(); // force redraw
530
531 return d.promise();
532 }
533 };
534
535 UI.slideshow.animations = Animations;
536
537 // Listen for messages from the vimeo player
538 window.addEventListener('message', function onMessageReceived(e) {
539
540 var data = e.data, iframe;
541
542 if (typeof(data) == 'string') {
543
544 try {
545 data = JSON.parse(data);
546 } catch(err) {
547 data = {};
548 }
549 }
550
551 if (e.origin && e.origin.indexOf('vimeo') > -1 && data.event == 'ready' && data.player_id) {
552 iframe = UI.$('[data-player-id="'+ data.player_id+'"]');
553
554 if (iframe.length) {
555 iframe.data('slideshow').mutemedia(iframe);
556 }
557 }
558 }, false);
559
560});