UNPKG

metro4

Version:

The front-end framework for Build responsive, mobile-first projects on the web with the first front-end component library in Metro Style

606 lines (489 loc) 17.9 kB
/* global Metro, Cake */ /** * Component Vegas based on Vegas by Jay Salvat (http://jaysalvat.com/) * Original code https://github.com/jaysalvat/vegas * MIT License, Copyright 2018 Jay Salvat * * Adaptation for Metro UI by Serhii Pimenov, * Copyright 2020 Serhii Pimenov */ (function(Metro, $) { 'use strict'; var Utils = Metro.utils; var VegasDefaultConfig = { duration: 4000, animationDuration: null, transitionDuration: null, transition: "fade", animation: null, slides: [], shuffle: false, align: "center", valign: "center", loop: true, autoplay: true, mute: true, cover: true, preload: true, timer: true, overlay: 2, color: null, volume: 1, onPlay: Metro.noop, onPause: Metro.noop, onEnd: Metro.noop, onWalk: Metro.noop, onNext: Metro.noop, onPrev: Metro.noop, onJump: Metro.noop, onVegasCreate: Metro.noop }; Metro.vegasSetup = function (options) { VegasDefaultConfig = $.extend({}, VegasDefaultConfig, options); }; if (typeof window["metroVegasSetup"] !== undefined) { Metro.vegasSetup(window["metroVegasSetup"]); } Metro.Component('vegas', { videoCache: {}, init: function( options, elem ) { this.transitions = [ "fade", "fade2", "slideLeft", "slideLeft2", "slideRight", "slideRight2", "slideUp", "slideUp2", "slideDown", "slideDown2", "zoomIn", "zoomIn2", "zoomOut", "zoomOut2", "swirlLeft", "swirlLeft2", "swirlRight", "swirlRight2" ]; this.animations = [ "kenburns", "kenburnsUp", "kenburnsDown", "kenburnsRight", "kenburnsLeft", "kenburnsUpLeft", "kenburnsUpRight", "kenburnsDownLeft", "kenburnsDownRight" ]; this.support = { objectFit: 'objectFit' in document.body.style, video: !/(Android|webOS|Phone|iPad|iPod|BlackBerry|Windows Phone)/i.test(navigator.userAgent) } this._super(elem, options, VegasDefaultConfig, { slide: 0, slides: null, total: 0, noshow: false, paused: false, ended: false, timer: null, overlay: null, first: true, timeout: false }); return this; }, _create: function(){ var element = this.element, o = this.options; this.slides = Utils.isObject(o.slides) || []; this.total = this.slides.length; this.noshow = this.total < 2; this.paused = !o.autoplay || this.noshow; if (o.shuffle) { this.slides.shuffle(); } if (o.preload) { this._preload(); } this._createStructure(); this._createEvents(); this._fireEvent("vegas-create", { element: element }); }, _createStructure: function(){ var that = this, element = this.element, o = this.options; var isBody = element[0].tagName === 'BODY'; var wrapper; if (!isBody) { element.css('height', element.css('height')); // it is not clear why this line wrapper = $('<div class="vegas-wrapper">') .css('overflow', element.css('overflow')) .css('padding', element.css('padding')); if (!element.css('padding')) { wrapper .css('padding-top', element.css('padding-top')) .css('padding-bottom', element.css('padding-bottom')) .css('padding-left', element.css('padding-left')) .css('padding-right', element.css('padding-right')); } element.children().appendTo(wrapper); element.clear(); } element.addClass("vegas-container"); if (!isBody) { element.append(wrapper); } if (o.timer) { this.timer = $('<div class="vegas-timer"><div class="vegas-timer-progress">'); element.append(this.timer); } if (o.overlay) { this.overlay = $('<div class="vegas-overlay">').addClass('overlay' + (typeof o.overlay === 'boolean' || isNaN(o.overlay) ? 2 : +o.overlay)); element.append(this.overlay); } setTimeout(function(){ Utils.exec(o.onPlay, null, element[0]); that._goto(that.slide); },1) }, _createEvents: function(){ }, _preload: function(){ var img, i; for (i = 0; i < this.slides.length; i++) { var obj = this.slides[i]; if (obj.src) { img = new Image(); img.src = this.slides[i].src; } if (obj.video) { if (obj.video instanceof Array) { this._video(obj.video); } else { this._video(obj.video.src); } } } }, _slideShow: function () { var that = this, o = this.options; if (this.total > 1 && !this.ended && !this.paused && !this.noshow) { this.timeout = setTimeout(function () { that.next(); }, o.duration); } }, _timer: function (state) { var that = this, o = this.options; clearTimeout(this.timeout); if (!this.timer) { return; } this.timer .removeClass('vegas-timer-running') .find('div') .css('transition-duration', '0ms'); if (this.ended || this.paused || this.noshow) { return; } if (state) { setTimeout(function () { that.timer .addClass('vegas-timer-running') .find('div') .css('transition-duration', +o.duration - 100 + 'ms'); }, 100); } }, _fadeSoundIn: function(video, duration){ var o = this.options; $.animate({ el: video, draw: { volume: +o.volume }, dur: duration }) }, _fadeSoundOut: function(video, duration){ $.animate({ el: video, draw: { volume: 0 }, dur: duration }) }, _video: function(sources){ var video, source; var cacheKey = sources.toString(); if (this.videoCache[cacheKey]) { return this.videoCache[cacheKey]; } if (!Array.isArray(sources)) { sources = [sources]; } video = document.createElement("video"); video.preload = true; sources.forEach(function(src){ source = document.createElement("source"); source.src = src; video.appendChild(source); }); this.videoCache[cacheKey] = video; return video; }, _goto: function(n){ var that = this, element = this.element, o = this.options; if (typeof this.slides[n] === 'undefined') { n = 0; } this.slide = n; var $slide, $inner, video, img, $video; var slides = element.children(".vegas-slide"); var obj = this.slides[n]; var cover = o.cover; var transition, animation; var transitionDuration, animationDuration; if (this.first) { this.first = false; } if (cover !== 'repeat') { if (cover === true) { cover = 'cover'; } else if (cover === false) { cover = 'contain'; } } if (o.transition === 'random') { transition = $.random(this.transitions); } else { transition = o.transition ? o.transition : this.transitions[0]; } if (o.animation === 'random') { animation = $.random(this.animations); } else { animation = o.animation ? o.animation : this.animations[0]; } if (!o.transitionDuration) { transitionDuration = +o.duration; } else if (o.transitionDuration === 'auto' || +o.transitionDuration > +o.duration) { transitionDuration = +o.duration; } else { transitionDuration = +o.transitionDuration; } if (!o.animationDuration) { animationDuration = +o.duration; } else if (o.animationDuration === 'auto' || +o.animationDuration > +o.duration) { animationDuration = +o.duration; } else { animationDuration = +o.animationDuration; } $slide = $("<div>").addClass("vegas-slide").addClass('vegas-transition-' + transition); if (this.support.video && obj.video) { video = obj.video instanceof Array ? this._video(obj.video) : this._video(obj.video.src); video.loop = obj.video.loop ? obj.video.loop : o.loop; video.muted = obj.video.mute ? obj.video.mute : o.mute; if (!video.muted) { this._fadeSoundIn(video, transitionDuration); } else { video.pause(); } $video = $(video) .addClass('vegas-video') .css('background-color', o.color || '#000000'); if (this.support.objectFit) { $video .css('object-position', o.align + ' ' + o.valign) .css('object-fit', cover) .css('width', '100%') .css('height', '100%'); } else if (cover === 'contain') { $video .css('width', '100%') .css('height', '100%'); } $slide.append($video); } else { img = new Image(); $inner = $("<div>").addClass('vegas-slide-inner') .css({ backgroundImage: 'url("'+obj.src+'")', backgroundColor: o.color || '#000000', backgroundPosition: o.align + ' ' + o.valign }); if (cover === 'repeat') { $inner.css('background-repeat', 'repeat'); } else { $inner.css('background-size', cover); } if (animation) { $inner .addClass('vegas-animation-' + animation) .css('animation-duration', animationDuration + 'ms'); } $slide.append($inner); } if (slides.length) { slides.eq(slides.length - 1).after($slide); } else { element.prepend($slide); } slides .css('transition', 'all 0ms') .each(function(){ this.className = 'vegas-slide'; if (this.tagName === 'VIDEO') { this.className += ' vegas-video'; } if (transition) { this.className += ' vegas-transition-' + transition; this.className += ' vegas-transition-' + transition + '-in'; } } ); this._timer(false); function go(){ that._timer(true); setTimeout(function () { slides .css('transition', 'all ' + transitionDuration + 'ms') .addClass('vegas-transition-' + transition + '-out'); slides.each(function () { var video = slides.find('video').get(0); if (video) { video.volume = 1; that._fadeSoundOut(video, transitionDuration); } }); $slide .css('transition', 'all ' + transitionDuration + 'ms') .addClass('vegas-transition-' + transition + '-in'); for (var i = 0; i < slides.length - 1; i++) { slides.eq(i).remove(); } that._fireEvent("walk", { slide: that.current(true) }); that._slideShow(); }, 100); } if (video) { if (video.readyState === 4) { video.currentTime = 0; } video.play(); go(); } else { img.src = obj.src; if (img.complete) { go(); } else { img.onload = go; } } }, _end: function(){ this.ended = this.options.autoplay; this._timer(false); this._fireEvent("end", { slide: this.current(true) }); }, play: function(){ if (!this.paused) { return ; } this._fireEvent("play", { slide: this.current(true) }); this.paused = false; this.next(); }, pause: function(){ this._timer(false); this.paused = true; this._fireEvent("pause", { slide: this.current(true) }); }, toggle: function(){ this.paused ? this.play() : this.pause(); }, playing: function(){ return !this.paused && !this.noshow; }, current: function (advanced) { if (advanced) { return { slide: this.slide, data: this.slides[this.slide] }; } return this.slide; }, jump: function(n){ if (n <= 0 || n > this.slides.length || n === this.slide + 1) { return this; } this.slide = n - 1; this._fireEvent("jump", { slide: this.current(true) }) this._goto(this.slide); }, next: function(){ var o = this.options; this.slide++; if (this.slide >= this.slides.length) { if (!o.loop) { return this._end(); } this.slide = 0; } this._fireEvent("next", { slide: this.current(true) }); this._goto(this.slide); }, prev: function(){ var o = this.options; this.slide--; if (this.slide < 0) { if (!o.loop) { this.slide++; return this._end(); } this.slide = this.slides.length - 1; } this._fireEvent("prev", { slide: this.current(true) }); this._goto(this.slide); }, changeAttribute: function(attr){ var element = this.element, o = this.options; var propName = Str.camelCase(attr.replace("data-", "")); if (propName === 'slides') { o.slides = element.attr('data-slides'); this.slides = Utils.isObject(o.slides) || []; this.total = this.slides.length; this.noshow = this.total < 2; this.paused = !this.options.autoplay || this.noshow; } else { if (typeof VegasDefaultConfig[propName] !== 'undefined') o[propName] = JSON.parse(element.attr(attr)); } }, destroy: function(){ var element = this.element, o = this.options; clearTimeout(this.timeout); element.removeClass('vegas-container'); element.find('> .vegas-slide').remove(); element.find('> .vegas-wrapper').children().appendTo(element); element.find('> .vegas-wrapper').remove(); if (o.timer) { this.timer.remove(); } if (o.overlay) { this.overlay.remove(); } return element[0]; } }); }(Metro, m4q));