From: Vincent Vanwaelscappel Date: Thu, 9 Jun 2016 15:02:46 +0000 (+0000) Subject: Commit code to production #424 @0:10 X-Git-Url: http://git.cubedesigners.com/?a=commitdiff_plain;h=616940290a795360e15f56135b057dfa366ed569;p=fluidbook-html5.git Commit code to production #424 @0:10 --- diff --git a/js/libs/fluidbook/fluidbook.audiodescription.js b/js/libs/fluidbook/fluidbook.audiodescription.js new file mode 100644 index 00000000..f1f6b9b7 --- /dev/null +++ b/js/libs/fluidbook/fluidbook.audiodescription.js @@ -0,0 +1,140 @@ +/* + * Translations: + * __('listen to the page') + */ + +function FluidbookAudioDescription(fluidbook) { + this.fluidbook = fluidbook; + this.dataPath = 'data/audiodescription/'; + this.container = $('#interface'); + this.buttonClass = 'audio-description-button'; + + // Players + this.audioplayerLeft = new Audio(); + this.audioplayerRight = new Audio(); + + // Button elements + this.buttonLeft = document.createElement('a'); + this.buttonLeft.setAttribute('class', this.buttonClass + ' left'); + this.buttonRight = document.createElement('a'); + this.buttonRight.setAttribute('class', this.buttonClass + ' right'); + + this.init(); +} + +FluidbookAudioDescription.prototype = { + + init: function () { + + // Add button elements + this.container.append(this.buttonLeft); + this.container.append(this.buttonRight); + + var $this = this, + buttons = $('.' + this.buttonClass) + + // Add tooltips + buttons.attr('data-tooltip', this.fluidbook.l10n.__('listen to the page')); + + // Hide buttons by default - they will be shown if there is audio when setupPages() is run + buttons.hide(); + + // Add listeners to audio players so that the button state will be reset once play finishes + this.audioplayerLeft.addEventListener('ended', this.endPlaying.bind(this, this.audioplayerLeft)); + this.audioplayerRight.addEventListener('ended', this.endPlaying.bind(this, this.audioplayerRight)); + + // Handle click + $(document).on('click', '.' + this.buttonClass, function (e) { + + var player, button; + + if ($(this).hasClass('right')) { + player = $this.audioplayerRight; + button = $($this.buttonRight); + } else { + player = $this.audioplayerLeft; + button = $($this.buttonLeft); + } + + // If the button we clicked is already playing, pause it and exit the function + if ($(this).hasClass('playing')) { + $this.pauseAllPlayers(); + return false; + } + + // Play normally + $this.pauseAllPlayers(); + button.addClass('playing'); + //fb('currently playing: ' + player.src); + player.play(); + + e.preventDefault(); + }); + + // Keyboard Shortcuts + key('ctrl+shift+left', this.playSide.bind(this, 'left')); + key('ctrl+shift+right', this.playSide.bind(this, 'right')); + + this.setupPages(); + }, + + setupPages: function () { + + this.pauseAllPlayers(); + + var pageNumLeft = this.fluidbook.getPageNumberOfSide('left'), + pageNumRight = this.fluidbook.getPageNumberOfSide('right'); + + // Left hand page + if (this.hasAudio(pageNumLeft)) { + $(this.buttonLeft).show(); + this.audioplayerLeft.src = this.getAudio(pageNumLeft); + } else { + $(this.buttonLeft).hide(); + } + + // Right hand page + if (this.hasAudio(pageNumRight) && !this.fluidbook.displayOnePage) { + $(this.buttonRight).show(); + this.audioplayerRight.src = this.getAudio(pageNumRight); + } else { + $(this.buttonRight).hide(); + } + + }, + + pauseAllPlayers: function() { + this.audioplayerLeft.pause(); + this.audioplayerRight.pause(); + + $('.' + this.buttonClass).removeClass('playing'); // Reset button states + }, + + endPlaying: function(player) { + this.pauseAllPlayers(); // Reset button states and ensure all playback is halted + player.currentTime = 0; // Rewind audio + }, + + hasAudio: function(page) { + + if (this.fluidbook.datas.audiodescription === undefined) return false; + + return (this.fluidbook.datas.audiodescription[page] !== undefined); + }, + + getAudio: function(page) { + return this.dataPath + this.fluidbook.datas.audiodescription[page]; + }, + + playSide: function(side) { + + var targetSelector = '.' + this.buttonClass + '.' + side, + pageNum = this.fluidbook.getPageNumberOfSide(side); + + // Only try to play audio if available (button will be visible) + if (this.hasAudio(pageNum)) { + $(targetSelector).trigger('click'); + } + } + +} diff --git a/js/libs/fluidbook/fluidbook.js b/js/libs/fluidbook/fluidbook.js index d6af8a6e..ffc56d8e 100644 --- a/js/libs/fluidbook/fluidbook.js +++ b/js/libs/fluidbook/fluidbook.js @@ -43,6 +43,7 @@ Fluidbook.prototype = { this.bookmarks = new FluidbookBookmarks(this); this.index = new FluidbookIndex(this); this.tooltip = new FluidbookTooltip(this); + this.audiodescription = new FluidbookAudioDescription(this); if (this.datas.form == 'bulle') { this.form = new FluidbookBulleForm(this); } else { @@ -81,6 +82,7 @@ Fluidbook.prototype = { this.desktop = new FluidbookDesktop(this); } this.initTheme(); + this.initKeyboardShortcuts(); }, initTheme: function () { if (this.datas.arrowsTheme) { @@ -96,6 +98,16 @@ Fluidbook.prototype = { }); }, + initKeyboardShortcuts: function () { + + // General keyboard shortcuts + key('home', this.goFirstPage.bind(this)); + key('end', this.goLastPage.bind(this)); + key('left', this.goPreviousPage.bind(this)); + key('right', this.goNextPage.bind(this)); + + // See fluidbook.audiodescription.js for specific shortcuts + }, hideSplash: function () { if ($("#splash").length == 0) { return; @@ -680,6 +692,11 @@ Fluidbook.prototype = { $("#down").css('opacity', 0); } + // Handle audio descriptions + if (Modernizr.audio) { + this.audiodescription.setupPages(); + } + }, setPageNumbers: function () { $("#pagesnumbers .left").html(this.getPageNumberOfSide('left')); diff --git a/js/libs/fluidbook/fluidbook.resize.js b/js/libs/fluidbook/fluidbook.resize.js index 14aa1205..65fbe0e6 100644 --- a/js/libs/fluidbook/fluidbook.resize.js +++ b/js/libs/fluidbook/fluidbook.resize.js @@ -131,7 +131,21 @@ FluidbookResize.prototype = { $("#previous").transform({ scale: cssInterfaceScale, translateX: -40 * (1 - interfaceScale) + 'px' - }) + }); + + // Position audio buttons relative to book size and position + var audioButtonPosition = Math.max(top / this.bookScale, 30); // Ensure at least 30px clearance at the bottom + $(".audio-description-button").css({ + scale: cssInterfaceScale, + bottom: audioButtonPosition + }); + $(".audio-description-button.left").css({ + translateX: -52 * (1 - interfaceScale) + 'px' + }); + $(".audio-description-button.right").css({ + translateX: 52 * (1 - interfaceScale) + 'px' + }); + $("#nav,#logo,footer,#searchHints").transform({ scale: navScale diff --git a/js/libs/fluidbook/fluidbook.support.js b/js/libs/fluidbook/fluidbook.support.js index 9a128f49..4c8f62e5 100644 --- a/js/libs/fluidbook/fluidbook.support.js +++ b/js/libs/fluidbook/fluidbook.support.js @@ -1,171 +1,171 @@ function FluidbookSupport(fluidbook) { - this.fluidbook = fluidbook; - this.userAgent = navigator.userAgent; - this.android = this.fitScreenAtZero = this.userAgent.search(/android/i) > -1 || this.userAgent.search(/galaxy/i) > -1; - this.android3 = this.android && this.userAgent.search(/android 3/i) > -1; - this.iOS = this.userAgent.search(/ipad/i) > -1 || this.userAgent.search(/iphone/i) > -1 || this.userAgent.search(/ipod/i) > -1; - - this.transitions2d = Modernizr.csstransforms && Modernizr.csstransitions; - this.transitions3d = Modernizr.csstransforms3d && Modernizr.csstransformspreserve3d && this.transitions2d; - - this.transitionendevent = null; - - if (window.resolution == 'auto') { - this.resolution = Modernizr.mq('(-webkit-min-device-pixel-ratio: 2)') ? 300 : 150; - } else { - this.resolution = window.resolution; - } - - this.isMobile = isMobile(); - this.SVG = Modernizr.svg && this.fluidbook.datas.mobileIconVector; - - this._orientation = this.getOrientation(); - this.initialZoomPortrait = 0; - this.initialZoomLandscape = 0; - var z = DetectZoom.zoom(); - if (this._orientation == 0) { - this.initialZoomPortrait = z; - } else { - this.initialZoomLandscape = z; - } - this.initEvents(); + this.fluidbook = fluidbook; + this.userAgent = navigator.userAgent; + this.android = this.fitScreenAtZero = this.userAgent.search(/android/i) > -1 || this.userAgent.search(/galaxy/i) > -1; + this.android3 = this.android && this.userAgent.search(/android 3/i) > -1; + this.iOS = this.userAgent.search(/ipad/i) > -1 || this.userAgent.search(/iphone/i) > -1 || this.userAgent.search(/ipod/i) > -1; + + this.transitions2d = Modernizr.csstransforms && Modernizr.csstransitions; + this.transitions3d = Modernizr.csstransforms3d && Modernizr.csstransformspreserve3d && this.transitions2d; + + this.transitionendevent = null; + + if (window.resolution == 'auto') { + this.resolution = Modernizr.mq('(-webkit-min-device-pixel-ratio: 2)') ? 300 : 150; + } else { + this.resolution = window.resolution; + } + + this.isMobile = isMobile(); + this.SVG = Modernizr.svg && this.fluidbook.datas.mobileIconVector; + + this._orientation = this.getOrientation(); + this.initialZoomPortrait = 0; + this.initialZoomLandscape = 0; + var z = DetectZoom.zoom(); + if (this._orientation == 0) { + this.initialZoomPortrait = z; + } else { + this.initialZoomLandscape = z; + } + this.initEvents(); } FluidbookSupport.prototype = { - getTransitionEndEvent: function(all) { - if (all == undefined) { - all = false; - } - if (!all) { - return this.transitionEndEvent; - } - return "webkitTransitionEnd transitionend oTransitionEnd msTransitionEnd transitionEnd"; - }, - hasNetwork: function() { - if (navigator.onLine != undefined) { - return navigator.onLine; - } else { - return networkState() != 'none'; - } - }, - networkState: function() { - var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection || { - type: 'unknown' - }; - var t = connetion.type; - - if (t == undefined) { - t = 'unknown'; - } else if (t == 0) { - t = 'unknown'; - } else if (t == 1) { - t = 'ethernet'; - } else if (t == 2) { - t = 'wifi'; - } else if (t == 3) { - t = '2g'; - } else if (t == 4) { - t = '3g'; - } else if (t == 5) { - t = '4g'; - } else { - t = 'none'; - } - return t; - }, - initEvents: function() { - - var $this = this; - - if (!this.isMobile) { - $(window).resize(function() { - resize(); - }); - } else { - - if ("onorientationchange" in window) { - window.addEventListener('orientationchange', function() { - if ($this.iOS) { - resize(); - } else { - resize(); - setTimeout(function() { - resize(); - }, 750); - } - }, false); - } else { - setInterval(function() { - $this.checkOrientation(); - }, 100); - } - } - - // Test transition end event - var div = document.createElement('div'); - div.id = "my-transition-test"; - div.style.position = 'absolute'; - div.style.zIndex = -10; - div.style.bottom = '-1000px'; - div.style.height = '100px'; - div.style.width = '100px'; - div.style.background = 'yellow'; - div.style.display = 'hidden'; - window.document.body.appendChild(div); - - $('#my-transition-test').one("webkitTransitionEnd transitionend oTransitionEnd msTransitionEnd transitionEnd", function(e) { - if ($this.transitionEndEvent !== e.type) { - $this.transitionEndEvent = e.type; - } - window.document.body.removeChild(div); - }); - - setTimeout(function() { - div.style[Modernizr.prefixed('transition')] = '0.1s'; - div.style[Modernizr.prefixed('transform')] = 'translate3d( 100px,0,0)'; - }, 25); - }, - checkOrientation: function() { - var o = this.getOrientation(); - if (o != this._orientation) { - this._orientation = o; - resize(); - } - }, - getOrientation: function() { - try { - if (this.fluidbook.pad && this.fluidbook.pad.enabled) { - return 0; - } else if (this.fluidbook.datas.mobileNavigationType == 'landscape') { - return 90; - } else if (this.fluidbook.datas.mobileNavigationType == 'portrait') { - return 0; - } - } catch (err) { - - } - - try { - return Modernizr.mq("(orientation: portrait)") ? 0 : 90; - } catch (err) { - - } - return $("#op").is(':visible') ? 0 : 90; - }, - getZoomLevel: function() { - var tzoom = DetectZoom.zoom(); - var iz; - if (this._orientation == 0) { - iz = this.initialZoomPortrait; - if (iz == 0) { - iz = this.initialZoomPortrait = tzoom; - } - } else { - iz = this.initialZoomLandscape; - if (iz == 0) { - iz = this.initialZoomLandscape = tzoom; - } - } - return tzoom / iz; - } + getTransitionEndEvent: function (all) { + if (all == undefined) { + all = false; + } + if (!all) { + return this.transitionEndEvent; + } + return "webkitTransitionEnd transitionend oTransitionEnd msTransitionEnd transitionEnd"; + }, + hasNetwork: function () { + if (navigator.onLine != undefined) { + return navigator.onLine; + } else { + return networkState() != 'none'; + } + }, + networkState: function () { + var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection || { + type: 'unknown' + }; + var t = connetion.type; + + if (t == undefined) { + t = 'unknown'; + } else if (t == 0) { + t = 'unknown'; + } else if (t == 1) { + t = 'ethernet'; + } else if (t == 2) { + t = 'wifi'; + } else if (t == 3) { + t = '2g'; + } else if (t == 4) { + t = '3g'; + } else if (t == 5) { + t = '4g'; + } else { + t = 'none'; + } + return t; + }, + initEvents: function () { + + var $this = this; + + if (!this.isMobile) { + $(window).resize(function () { + resize(); + }); + } else { + + if ("onorientationchange" in window) { + window.addEventListener('orientationchange', function () { + if ($this.iOS) { + resize(); + } else { + resize(); + setTimeout(function () { + resize(); + }, 750); + } + }, false); + } else { + setInterval(function () { + $this.checkOrientation(); + }, 100); + } + } + + // Test transition end event + var div = document.createElement('div'); + div.id = "my-transition-test"; + div.style.position = 'absolute'; + div.style.zIndex = -10; + div.style.bottom = '0px'; + div.style.height = '0px'; + div.style.width = '0px'; + div.style.background = 'yellow'; + //div.style.display = 'none'; + window.document.body.appendChild(div); + + $('#my-transition-test').one("webkitTransitionEnd transitionend oTransitionEnd msTransitionEnd transitionEnd", function (e) { + if ($this.transitionEndEvent !== e.type) { + $this.transitionEndEvent = e.type; + } + window.document.body.removeChild(div); + }); + + setTimeout(function () { + div.style[Modernizr.prefixed('transition')] = '0.1s'; + div.style[Modernizr.prefixed('transform')] = 'translate3d( 100px,0,0)'; + }, 25); + }, + checkOrientation: function () { + var o = this.getOrientation(); + if (o != this._orientation) { + this._orientation = o; + resize(); + } + }, + getOrientation: function () { + try { + if (this.fluidbook.pad && this.fluidbook.pad.enabled) { + return 0; + } else if (this.fluidbook.datas.mobileNavigationType == 'landscape') { + return 90; + } else if (this.fluidbook.datas.mobileNavigationType == 'portrait') { + return 0; + } + } catch (err) { + + } + + try { + return Modernizr.mq("(orientation: portrait)") ? 0 : 90; + } catch (err) { + + } + return $("#op").is(':visible') ? 0 : 90; + }, + getZoomLevel: function () { + var tzoom = DetectZoom.zoom(); + var iz; + if (this._orientation == 0) { + iz = this.initialZoomPortrait; + if (iz == 0) { + iz = this.initialZoomPortrait = tzoom; + } + } else { + iz = this.initialZoomLandscape; + if (iz == 0) { + iz = this.initialZoomLandscape = tzoom; + } + } + return tzoom / iz; + } }