UNPKG

blueimp-gallery

Version:

blueimp Gallery is a touch-enabled, responsive and customizable image and video gallery, carousel and lightbox, optimized for both mobile and desktop web browsers. It features swipe, mouse and keyboard navigation, transition effects, slideshow functionali

225 lines (206 loc) 6.21 kB
/* * blueimp Gallery YouTube Video Factory JS * https://github.com/blueimp/Gallery * * Copyright 2013, Sebastian Tschan * https://blueimp.net * * Licensed under the MIT license: * https://opensource.org/licenses/MIT */ /* global define, YT */ ;(function (factory) { 'use strict' if (typeof define === 'function' && define.amd) { // Register as an anonymous AMD module: define(['./blueimp-helper', './blueimp-gallery-video'], factory) } else { // Browser globals: factory(window.blueimp.helper || window.jQuery, window.blueimp.Gallery) } })(function ($, Gallery) { 'use strict' if (!window.postMessage) { return Gallery } var galleryPrototype = Gallery.prototype $.extend(galleryPrototype.options, { // The list object property (or data attribute) with the YouTube video id: youTubeVideoIdProperty: 'youtube', // Optional object with parameters passed to the YouTube video player: // https://developers.google.com/youtube/player_parameters youTubePlayerVars: { wmode: 'transparent' }, // Require a click on the native YouTube player for the initial playback: youTubeClickToPlay: false }) var textFactory = galleryPrototype.textFactory || galleryPrototype.imageFactory var YouTubePlayer = function (videoId, playerVars, clickToPlay) { this.videoId = videoId this.playerVars = playerVars this.clickToPlay = clickToPlay this.element = document.createElement('div') this.listeners = {} } $.extend(YouTubePlayer.prototype, { on: function (type, func) { this.listeners[type] = func return this }, loadAPI: function () { var that = this var onYouTubeIframeAPIReady = window.onYouTubeIframeAPIReady var apiUrl = 'https://www.youtube.com/iframe_api' var scriptTags = document.getElementsByTagName('script') var i = scriptTags.length var scriptTag window.onYouTubeIframeAPIReady = function () { if (onYouTubeIframeAPIReady) { onYouTubeIframeAPIReady.apply(this) } if (that.playOnReady) { that.play() } } while (i) { i -= 1 if (scriptTags[i].src === apiUrl) { return } } scriptTag = document.createElement('script') scriptTag.src = apiUrl scriptTags[0].parentNode.insertBefore(scriptTag, scriptTags[0]) }, onReady: function () { this.ready = true if (this.playOnReady) { this.play() } }, onPlaying: function () { if (this.playStatus < 2) { this.listeners.playing() this.playStatus = 2 } }, onPause: function () { this.listeners.pause() delete this.playStatus }, onStateChange: function (event) { window.clearTimeout(this.pauseTimeout) switch (event.data) { case YT.PlayerState.PLAYING: this.hasPlayed = true this.onPlaying() break case YT.PlayerState.UNSTARTED: case YT.PlayerState.PAUSED: // YouTube sends an unstarted event if pause is triggered before the // video has started. // YouTube sends a pause event when seeking. // In both cases, we initiate a pause in a timeout that gets cleared // if followed by another event within the timeout window. this.pauseTimeout = galleryPrototype.setTimeout.call( this, this.onPause, null, 500 ) break case YT.PlayerState.ENDED: this.onPause() break } }, onError: function (event) { this.listeners.error(event) }, play: function () { var that = this if (!this.playStatus) { this.listeners.play() this.playStatus = 1 } if (this.ready) { if ( !this.hasPlayed && (this.clickToPlay || (window.navigator && /iP(hone|od|ad)/.test(window.navigator.platform))) ) { // Manually trigger the playing callback if clickToPlay // is enabled and to workaround a limitation in iOS, // which requires synchronous user interaction to start // the video playback: this.onPlaying() } else { this.player.playVideo() } } else { this.playOnReady = true if (!(window.YT && YT.Player)) { this.loadAPI() } else if (!this.player) { this.player = new YT.Player(this.element, { videoId: this.videoId, playerVars: this.playerVars, events: { onReady: function () { that.onReady() }, onStateChange: function (event) { that.onStateChange(event) }, onError: function (event) { that.onError(event) } } }) } } }, pause: function () { if (this.ready) { this.player.pauseVideo() } else if (this.playStatus) { delete this.playOnReady this.listeners.pause() delete this.playStatus } } }) $.extend(galleryPrototype, { YouTubePlayer: YouTubePlayer, textFactory: function (obj, callback) { var options = this.options var videoId = this.getItemProperty(obj, options.youTubeVideoIdProperty) if (videoId) { if (this.getItemProperty(obj, options.urlProperty) === undefined) { obj[options.urlProperty] = 'https://www.youtube.com/watch?v=' + videoId } if ( this.getItemProperty(obj, options.videoPosterProperty) === undefined ) { obj[options.videoPosterProperty] = 'https://img.youtube.com/vi/' + videoId + '/maxresdefault.jpg' } return this.videoFactory( obj, callback, new YouTubePlayer( videoId, options.youTubePlayerVars, options.youTubeClickToPlay ) ) } return textFactory.call(this, obj, callback) } }) return Gallery })