]> _ Git - fluidbook-html5.git/commitdiff
Commit code to production #424 @0:10
authorVincent Vanwaelscappel <vincent@cubedesigners.com>
Thu, 9 Jun 2016 15:02:46 +0000 (15:02 +0000)
committerVincent Vanwaelscappel <vincent@cubedesigners.com>
Thu, 9 Jun 2016 15:02:46 +0000 (15:02 +0000)
js/libs/fluidbook/fluidbook.audiodescription.js [new file with mode: 0644]
js/libs/fluidbook/fluidbook.js
js/libs/fluidbook/fluidbook.resize.js
js/libs/fluidbook/fluidbook.support.js

diff --git a/js/libs/fluidbook/fluidbook.audiodescription.js b/js/libs/fluidbook/fluidbook.audiodescription.js
new file mode 100644 (file)
index 0000000..f1f6b9b
--- /dev/null
@@ -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');
+        }
+    }
+
+}
index d6af8a6eab1059e02e25a69d3795213efefde4b1..ffc56d8e5b0a5c76aa47e3ac33203d6da58c6881 100644 (file)
@@ -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'));
index 14aa1205980df7e2eef8d030e221b8f652477a7c..65fbe0e61d6edd0fd0665311f16441e52d56ffb7 100644 (file)
@@ -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
index 9a128f4995ed9a8dc7dc54cf1eb0f93456a33e3e..4c8f62e5993e8eb898c63d87a55f03a2b6ad1d16 100644 (file)
 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;
+    }
 }