diff --git a/src/components/backdropscreensaver/plugin.js b/src/components/backdropscreensaver/plugin.js new file mode 100644 index 0000000000..0c4883d61f --- /dev/null +++ b/src/components/backdropscreensaver/plugin.js @@ -0,0 +1,55 @@ +define([], function () { + + return function () { + + var self = this; + + self.name = 'Backdrop ScreenSaver'; + self.type = 'screensaver'; + self.id = 'backdropscreensaver'; + self.supportsAnonymous = false; + + var currentSlideshow; + + self.show = function () { + + var query = { + ImageTypes: "Backdrop", + EnableImageTypes: "Backdrop", + IncludeItemTypes: "Movie,Series,MusicArtist,Game", + SortBy: "Random", + Recursive: true, + Fields: "Taglines", + ImageTypeLimit: 1, + StartIndex: 0, + Limit: 200 + }; + + Emby.Models.items(query).then(function (result) { + + if (result.Items.length) { + + require(['slideshow'], function (slideshow) { + + var newSlideShow = new slideshow({ + showTitle: true, + cover: true, + items: result.Items + }); + + newSlideShow.show(); + currentSlideshow = newSlideShow; + }); + } + }); + }; + + self.hide = function () { + + if (currentSlideshow) { + currentSlideshow.hide(); + currentSlideshow = null; + } + }; + } +}); \ No newline at end of file diff --git a/src/components/logoscreensaver/logowhite.png b/src/components/logoscreensaver/logowhite.png new file mode 100644 index 0000000000..560d910d74 Binary files /dev/null and b/src/components/logoscreensaver/logowhite.png differ diff --git a/src/components/logoscreensaver/plugin.js b/src/components/logoscreensaver/plugin.js new file mode 100644 index 0000000000..77df0218a0 --- /dev/null +++ b/src/components/logoscreensaver/plugin.js @@ -0,0 +1,191 @@ +define(['pluginManager'], function (pluginManager) { + + return function () { + + var self = this; + + self.name = 'Logo ScreenSaver'; + self.type = 'screensaver'; + self.id = 'logoscreensaver'; + self.supportsAnonymous = true; + + var interval; + + function animate() { + + var animations = [ + + bounceInLeft, + bounceInRight, + swing, + tada, + wobble, + rotateIn, + rotateOut + ]; + + var elem = document.querySelector('.logoScreenSaverImage'); + + if (elem && elem.animate) { + var random = getRandomInt(0, animations.length - 1); + + animations[random](elem, 1); + } + } + + function getRandomInt(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + } + + function bounceInLeft(elem, iterations) { + var keyframes = [ + { transform: 'translate3d(-3000px, 0, 0)', opacity: '0', offset: 0 }, + { transform: 'translate3d(25px, 0, 0)', opacity: '1', offset: 0.6 }, + { transform: 'translate3d(-100px, 0, 0)', offset: 0.75 }, + { transform: 'translate3d(5px, 0, 0)', offset: 0.9 }, + { transform: 'none', opacity: '1', offset: 1 }]; + var timing = { duration: 900, iterations: iterations, easing: 'cubic-bezier(0.215, 0.610, 0.355, 1.000)' }; + return elem.animate(keyframes, timing); + } + + function bounceInRight(elem, iterations) { + var keyframes = [ + { transform: 'translate3d(3000px, 0, 0)', opacity: '0', offset: 0 }, + { transform: 'translate3d(-25px, 0, 0)', opacity: '1', offset: 0.6 }, + { transform: 'translate3d(100px, 0, 0)', offset: 0.75 }, + { transform: 'translate3d(-5px, 0, 0)', offset: 0.9 }, + { transform: 'none', opacity: '1', offset: 1 }]; + var timing = { duration: 900, iterations: iterations, easing: 'cubic-bezier(0.215, 0.610, 0.355, 1.000)' }; + return elem.animate(keyframes, timing); + } + function shake(elem, iterations) { + var keyframes = [ + { transform: 'translate3d(0, 0, 0)', offset: 0 }, + { transform: 'translate3d(-10px, 0, 0)', offset: 0.1 }, + { transform: 'translate3d(10px, 0, 0)', offset: 0.2 }, + { transform: 'translate3d(-10px, 0, 0)', offset: 0.3 }, + { transform: 'translate3d(10px, 0, 0)', offset: 0.4 }, + { transform: 'translate3d(-10px, 0, 0)', offset: 0.5 }, + { transform: 'translate3d(10px, 0, 0)', offset: 0.6 }, + { transform: 'translate3d(-10px, 0, 0)', offset: 0.7 }, + { transform: 'translate3d(10px, 0, 0)', offset: 0.8 }, + { transform: 'translate3d(-10px, 0, 0)', offset: 0.9 }, + { transform: 'translate3d(0, 0, 0)', offset: 1 }]; + var timing = { duration: 900, iterations: iterations }; + return elem.animate(keyframes, timing); + } + + function swing(elem, iterations) { + var keyframes = [ + { transform: 'translate(0%)', offset: 0 }, + { transform: 'rotate3d(0, 0, 1, 15deg)', offset: 0.2 }, + { transform: 'rotate3d(0, 0, 1, -10deg)', offset: 0.4 }, + { transform: 'rotate3d(0, 0, 1, 5deg)', offset: 0.6 }, + { transform: 'rotate3d(0, 0, 1, -5deg)', offset: 0.8 }, + { transform: 'rotate3d(0, 0, 1, 0deg)', offset: 1 }]; + var timing = { duration: 900, iterations: iterations }; + return elem.animate(keyframes, timing); + } + + function tada(elem, iterations) { + var keyframes = [ + { transform: 'scale3d(1, 1, 1)', offset: 0 }, + { transform: 'scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg)', offset: 0.1 }, + { transform: 'scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg)', offset: 0.2 }, + { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg)', offset: 0.3 }, + { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg)', offset: 0.4 }, + { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg)', offset: 0.5 }, + { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg)', offset: 0.6 }, + { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg)', offset: 0.7 }, + { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg)', offset: 0.8 }, + { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg)', offset: 0.9 }, + { transform: 'scale3d(1, 1, 1)', offset: 1 }]; + var timing = { duration: 900, iterations: iterations }; + return elem.animate(keyframes, timing); + } + + function wobble(elem, iterations) { + var keyframes = [ + { transform: 'translate(0%)', offset: 0 }, + { transform: 'translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg)', offset: 0.15 }, + { transform: 'translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg)', offset: 0.45 }, + { transform: 'translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg)', offset: 0.6 }, + { transform: 'translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg)', offset: 0.75 }, + { transform: 'translateX(0%)', offset: 1 }]; + var timing = { duration: 900, iterations: iterations }; + return elem.animate(keyframes, timing); + } + + function rotateIn(elem, iterations) { + var transformOrigin = elem.style['transform-origin']; + var keyframes = [{ transform: 'rotate3d(0, 0, 1, -200deg)', opacity: '0', transformOrigin: 'center', offset: 0 }, + { transform: 'none', opacity: '1', transformOrigin: 'center', offset: 1 }]; + var timing = { duration: 900, iterations: iterations }; + return elem.animate(keyframes, timing); + } + + function rotateOut(elem, iterations) { + var transformOrigin = elem.style['transform-origin']; + var keyframes = [{ transform: 'none', opacity: '1', transformOrigin: 'center', offset: 0 }, + { transform: 'rotate3d(0, 0, 1, 200deg)', opacity: '0', transformOrigin: 'center', offset: 1 }]; + var timing = { duration: 900, iterations: iterations }; + return elem.animate(keyframes, timing); + + } + + function fadeOut(elem, iterations) { + var keyframes = [ + { opacity: '1', offset: 0 }, + { opacity: '0', offset: 1 }]; + var timing = { duration: 400, iterations: iterations }; + return elem.animate(keyframes, timing); + } + + function stopInterval() { + if (interval) { + clearInterval(interval); + interval = null; + } + } + + self.show = function () { + + require(['css!' + pluginManager.mapPath(self, 'style.css')], function () { + + var elem = document.querySelector('.logoScreenSaver'); + + if (!elem) { + elem = document.createElement('div'); + elem.classList.add('logoScreenSaver'); + document.body.appendChild(elem); + + elem.innerHTML = ''; + } + + stopInterval(); + interval = setInterval(animate, 3000); + }); + }; + + self.hide = function () { + + stopInterval(); + + var elem = document.querySelector('.logoScreenSaver'); + + if (elem) { + + var onAnimationFinish = function () { + elem.parentNode.removeChild(elem); + }; + + if (elem.animate) { + var animation = fadeOut(elem, 1); + animation.onfinish = onAnimationFinish; + } else { + onAnimationFinish(); + } + } + }; + } +}); \ No newline at end of file diff --git a/src/components/logoscreensaver/style.css b/src/components/logoscreensaver/style.css new file mode 100644 index 0000000000..92c8139717 --- /dev/null +++ b/src/components/logoscreensaver/style.css @@ -0,0 +1,18 @@ +.logoScreenSaver { + background: #101010; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 1000; + text-align: center; +} + +.logoScreenSaverImage { + height: 120px; + position: absolute; + top: 50%; + margin-top: -60px; + margin-left: -197px; +} diff --git a/src/components/screensavermanager.js b/src/components/screensavermanager.js new file mode 100644 index 0000000000..d186b538b3 --- /dev/null +++ b/src/components/screensavermanager.js @@ -0,0 +1,134 @@ +define(['events', 'playbackManager'], function (events, playbackManager) { + + function getMinIdleTime() { + // Returns the minimum amount of idle time required before the screen saver can be displayed + //return 3000; + return 180000; + } + + var lastFunctionalEvent = 0; + function getFunctionalEventIdleTime() { + return new Date().getTime() - lastFunctionalEvent; + } + + events.on(playbackManager, 'playbackstop', function (e, stopInfo) { + var state = stopInfo.state; + if (state.NowPlayingItem && state.NowPlayingItem.MediaType == 'Video') { + lastFunctionalEvent = new Date().getTime(); + } + }); + + function ScreenSaverManager() { + + var self = this; + var activeScreenSaver; + + function showScreenSaver(screensaver) { + + if (activeScreenSaver) { + throw new Error('An existing screensaver is already active.'); + } + + console.log('Showing screensaver ' + screensaver.name); + + screensaver.show(); + activeScreenSaver = screensaver; + + if (screensaver.hideOnClick !== false) { + window.addEventListener('click', hide, true); + } + if (screensaver.hideOnMouse !== false) { + window.addEventListener('mousemove', hide, true); + } + if (screensaver.hideOnKey !== false) { + window.addEventListener('keydown', hide, true); + } + } + + function hide() { + if (activeScreenSaver) { + console.log('Hiding screensaver'); + activeScreenSaver.hide(); + activeScreenSaver = null; + } + + window.removeEventListener('click', hide, true); + window.removeEventListener('mousemove', hide, true); + window.removeEventListener('keydown', hide, true); + } + + self.isShowing = function () { + return activeScreenSaver != null; + }; + + self.show = function () { + var screensavers = Emby.PluginManager.ofType('screensaver'); + + require(['connectionManager'], function (connectionManager) { + + var server = connectionManager.currentLoggedInServer(); + + show(screensavers, server); + }); + }; + + function show(screensavers, currentServer) { + + if (currentServer) { + + var loggedInScreenSavers = screensavers.filter(function (screensaver) { + return !screensaver.supportsAnonymous; + }); + + if (loggedInScreenSavers.length) { + screensavers = loggedInScreenSavers; + } + + } else { + + screensavers = screensavers.filter(function (screensaver) { + return screensaver.supportsAnonymous; + }); + } + + // Perform some other filter here to get the configured screensaver + + var current = screensavers.length ? screensavers[0] : null; + if (current) { + showScreenSaver(current); + } + } + + self.hide = function () { + hide(); + }; + + function onInterval() { + + if (self.isShowing()) { + return; + } + + require(['inputmanager'], function (inputmanager) { + + if (inputmanager.idleTime() < getMinIdleTime()) { + return; + } + + if (getFunctionalEventIdleTime < getMinIdleTime()) { + return; + } + + if (playbackManager.isPlayingVideo()) { + return; + } + + self.show(); + }); + } + + setInterval(onInterval, 10000); + } + + return new ScreenSaverManager(); +}); \ No newline at end of file