]> _ Git - fluidbook-html5.git/commitdiff
Slideshow module revamp. WIP #3881 @10
authorStephen Cameron <stephen@cubedesigners.com>
Thu, 24 Sep 2020 17:29:43 +0000 (19:29 +0200)
committerStephen Cameron <stephen@cubedesigners.com>
Thu, 24 Sep 2020 17:29:43 +0000 (19:29 +0200)
js/libs/fluidbook/fluidbook.js
js/libs/fluidbook/fluidbook.menu.js
js/libs/fluidbook/fluidbook.slideshow.js
style/fluidbook.slideshow.less

index 7c16acf58c05e8da8d13783d4f9c39856f6c1588..58fc51888146d47e2d1744be477ddc58c2a5b784 100644 (file)
@@ -429,7 +429,8 @@ Fluidbook.prototype = {
             var view = args[1];
 
             if (this.currentPage === -1) {
-                if (view === 'multimedia' || view === 'video' || view === 'iframe') {
+                // Allow direct linking to specific types of content
+                if (view === 'multimedia' || view === 'video' || view === 'iframe' || view === 'slideshow') {
                     var searchURL = args.join('/');
                     $.each(this.settings.links, function (pageNr, links) {
                         var hl = $('<root>' + links + '</root>');
@@ -444,6 +445,9 @@ Fluidbook.prototype = {
                 } else {
                     this.currentPage = 0;
                 }
+
+                // Jump to correct page containing this content
+                // TODO: Investigate why this doesn't work properly - it should go to the page containing the link but it seems to get reset to 0, possibly caused by a resize function...
                 $this.pagetransitions.pageTransition(this.currentPage);
             }
             this.menu.openView(view, args[2], args[3], function () {
index 0a66de5aea80c3c808d1a28cf885f69ccb4a52fd..6a1a688e2ccf175bf5089e2249a4527aa17e030e 100644 (file)
@@ -252,10 +252,9 @@ FluidbookMenu.prototype = {
         // TODO: check which type should be passed to fluidbook.stats.track() ???
         // this.fluidbook.stats.track(11);
 
-      this.fluidbook.slideshow.initSlideshow('slideshow_' + slideshow);
+        this.fluidbook.slideshow.initSlideshow('slideshow_' + slideshow);
 
-
-        var $this = this;
+        // var $this = this;
         // var times = [250, 500, 750, 1000, 1250];
         // $.each(times, function (k, v) {
         //     setTimeout(function () {
@@ -859,16 +858,21 @@ FluidbookMenu.prototype = {
                 break;
             case 'slideshow':
 
+                // The slideshow should scale to the optimium size: no larger than 80% of screen width or height
+                // but also only as large as necessary for the included images (which are scaled to fit the screen ratio)
+
                 var horizontalPadding = fluidbook.slideshow.$slideshow.outerWidth() - fluidbook.slideshow.$slideshow.width();
                 var verticalPadding = fluidbook.slideshow.$slideshow.outerHeight() - fluidbook.slideshow.$slideshow.height();
 
-                // When resizing the slideshow, the goal is to fit it into the maxModalHeight.
-                // The thumbnails and caption can't be scaled so we must scale the height of the main image
-                // (it is already scaled for max-width via CSS)
+                // var lcss = 'color:#fff;padding:0.5em;background:';
+                // console.log('%cVPad: '+ verticalPadding + ' | HPad: '+ horizontalPadding, lcss+'green');
+
                 var headerHeight = m.find('.caption').outerHeight(); // Height of title section that also contains close button
+                var thumbnailsPresent = false;
                 var thumbnailsHeight = 0;
                 if (m.find('.fb-slideshow-thumbnails').length > 0) {
-                  thumbnailsHeight = m.find('.fb-slideshow-thumbnails').outerHeight(); // Thumbnail slider height
+                    thumbnailsPresent = true;
+                    thumbnailsHeight = m.find('.fb-slideshow-thumbnails').outerHeight(); // Thumbnail slider height
                 }
 
                 // On small/short screens, thumbnails are hidden and close icon / header is reduced
@@ -884,8 +888,10 @@ FluidbookMenu.prototype = {
                 }
 
                 // Default on larger screens is for modal to cover 80% of area but only if image is large enough
-                w = Math.min(ww * 0.8, fluidbook.slideshow.maxImageWidth + horizontalPadding);
-                h = Math.min(hh * 0.8, fluidbook.slideshow.maxImageHeight + verticalPadding + headerHeight + thumbnailsHeight);
+                w = Math.round(Math.min(ww * 0.8, fluidbook.slideshow.maxImageWidth + horizontalPadding));
+                h = Math.round(Math.min(hh * 0.8, fluidbook.slideshow.maxImageHeight + verticalPadding + headerHeight + thumbnailsHeight));
+
+                //console.log('%cMODAL W: '+ w +' | H: '+ h, lcss+'orangered');
 
                 if (optimizeHeight) {
                     // ToDo: test this more with and without captions activated. Needs refactoring for better transparency of logic
@@ -898,39 +904,53 @@ FluidbookMenu.prototype = {
                     w = ww;
                     h = hh;
                     fullscreen = true;
-                    $(".fb-slideshow").addClass('fb-slideshow-fullscreen');
+                    $('.fb-slideshow, .fb-slideshow-thumbnails').addClass('fb-slideshow-fullscreen');
                 } else {
-                    $(".fb-slideshow").removeClass('fb-slideshow-fullscreen');
+                    $('.fb-slideshow, .fb-slideshow-thumbnails').removeClass('fb-slideshow-fullscreen');
                 }
 
                 var slideMaxWidth = w - horizontalPadding;
-                var slideMaxHeight = h - headerHeight - thumbnailsHeight; // Remaining height that main image + caption has to fit into
-                var maxCaptionHeight = 0;
+                var slideMaxHeight = h - headerHeight - thumbnailsHeight - verticalPadding; // Remaining height that main image + caption has to fit into
 
-                // Process each slide and calculate optimal height for image and slide container
-                fluidbook.slideshow.$slideshow.find('.fb-slideshow-slide').each(function () {
-                    // Set the height on this container so flexbox can vertically center
-                    // the contents when they don't take up the full height available
-                    //$(this).find('.splide__slide__container').css('height', slideMaxHeight);
+                // console.log('%cslideMaxHeight: '+ slideMaxHeight +' %cheaderHeight: '+ headerHeight +' %cthumbnailsHeight: '+thumbnailsHeight, lcss+'teal', lcss+'blueviolet', lcss+'crimson');
 
-                    //console.log('setting h', slideMaxHeight);
+                // console.log('%cMain slideshow height: '+ $('.fb-slideshow').height(), lcss+'chocolate');
 
-                    // The caption normally provides the space needed
-                    // but if it's not present, we still count 30px of padding for the bottom
+                // Process each slide and calculate optimal height for image and slide container
+                fluidbook.slideshow.$slideshow.find('.fb-slideshow-slide').each(function () {
+                    // Get slide's caption height, if present
                     var captionHeight = $(this).find('.fb-slideshow-slide-caption').outerHeight() || 0;
-                    maxCaptionHeight = Math.max(captionHeight, maxCaptionHeight);
-                    console.log('captionHeight | maxCaptionHeight', captionHeight, maxCaptionHeight);
 
                     // Allow image to take up whatever height is left after accounting for the caption
                     // This is only the max-height so the image might not end up being this tall...
-                    // $(this).find('.fb-slideshow-slide-image').css({
-                    //     'max-height': slideMaxHeight - captionHeight
-                    // });
+                    var slideHeight = $(this).outerHeight();
+                    $(this).find('.fb-slideshow-slide-image').css({
+                        'max-height': slideMaxHeight - captionHeight
+                    });
                 });
 
-                fluidbook.slideshow.primarySlider.options.fixedHeight = slideMaxHeight - maxCaptionHeight;
+                // Don't attempt to interact with slider if it's not ready (resize function may run early)
+                if (!fluidbook.slideshow.primarySlider) break;
+
+                fluidbook.slideshow.primarySlider.options.fixedHeight = slideMaxHeight;
                 fluidbook.slideshow.primarySlider.options.fixedWidth = slideMaxWidth;
 
+                // If thumbnail slider content is wider than available space, enable dragging and focus:center mode
+                if (thumbnailsPresent) {
+                    if (fluidbook.slideshow.$thumbnails.find('.splide__list').width() >= slideMaxWidth) {
+                        fluidbook.slideshow.thumbSlider.options = {
+                            drag: true,
+                            focus: 'center',
+                        }
+                    } else {
+                        fluidbook.slideshow.thumbSlider.options = {
+                            drag: false,
+                            focus: false,
+                        }
+                    }
+                    fluidbook.slideshow.thumbSlider.refresh();
+                }
+
                 fluidbook.slideshow.primarySlider.refresh();
 
                 break;
index f44f8638561035a557ed272d82367412437cd2d3..622ce0bba42a0277077b5e11ac3bb3ee1a2593e3 100644 (file)
@@ -44,7 +44,6 @@ FluidbookSlideshow.prototype = {
             start      : openIndex,
             pagination : false,
             arrows     : true,
-            cover      : true, // Will be set to 'contain' in CSS
         };
 
         this.primarySlider = new Splide(this.slideshowID, slideshowSettings);
@@ -60,8 +59,7 @@ FluidbookSlideshow.prototype = {
                 isNavigation: true,
                 arrows      : false,
                 pagination  : false,
-                // ToDo: consider setting focus: 'center' dynamically in resize function only when the width of all thumbnails is wider than the modal width...
-                //focus     : 'center', // Center mode doesn't work well when there aren't many thumbs
+                drag        : false, // Will be enabled along with focus:center if thumbs are wider than available space
             } );
 
             this.thumbSlider.mount();
@@ -70,48 +68,4 @@ FluidbookSlideshow.prototype = {
 
         this.primarySlider.mount();
     }
-
-        /*
-        var slideshowParams = {
-            variableWidth: false,
-            infinite: this.numSlides > 1,
-            draggable: true
-        };
-        if (showThumbnails) {
-            slideshowParams.asNasFor = '#' + thumbnailsID; // Synced with thumbnails slider
-        }
-        // Main image slider
-        var mainSlideshow = $slideshow.slick(slideshowParams);
-        if (openIndex > 0) {
-            $slideshow.slick('slickGoTo', openIndex, true);
-        }
-
-        if (showThumbnails) {
-            // Thumbnails slider
-            $thumbnails.slick({
-                slidesToShow: 6,
-                asNavFor: '#' + id, // Synced with main slider
-                focusOnSelect: true,
-                variableWidth: true,
-                arrows: false,
-                draggable: true,
-                swipeToSlide: true,
-                infinite: true,
-                centerMode: false,
-            });
-
-            $slideshow.on('afterChange', function () {
-                $this.afterChange(id);
-            });
-            this.afterChange(id);
-        }
-    },
-
-    afterChange: function (id) {
-        var thumbnailsID = id + '_thumbnails';
-        var inFocus = $('#' + id + ' .slick-current').attr('data-slick-index');
-        $('#' + thumbnailsID + ' .slick-current').removeClass('slick-current');
-        $('#' + thumbnailsID + ' .slick-slide[data-slick-index="' + inFocus + '"]').trigger('click');
-    }
-    */
-}
+};
index e8067ba591656a834058db939971870413d518b2..cb7d60e426bf8254fffe5eaf7f0d27d1ae4bee20 100644 (file)
@@ -89,6 +89,7 @@
       height: @arrow-size;
       fill: @main-color;
       transition: fill .2s linear;
+      filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.4));
     }
 
     &:hover {
   //=== Nav
   &--nav {
     > .splide__track > .splide__list > .splide__slide {
-      border: 3px solid transparent;
+      //border: 3px solid transparent;
       cursor: pointer;
       opacity: .7;
 
       &.is-active {
-        border-color: @main-color;
+        //border-color: @main-color;
         opacity: 1;
+        position: relative;
+
+        &:after {
+          content: '';
+          position: absolute;
+          top: 0;
+          right: 0;
+          bottom: 0;
+          left: 0;
+          border: 3px solid @main-color;
+        }
       }
 
       &:focus {
 
 .fb-slideshow {
   position: relative;
-  padding: 0 60px;
+  padding: 0 60px 20px;
 
   &.fb-slideshow-fullscreen {
-    padding: 0;
+    padding-left: 0;
+    padding-right: 0;
 
     .fb-slideshow-slide {
     }
   }
 
   &-slide {
-    //position: relative;
-    //display: flex !important;
-    //flex-direction: column;
-    //justify-content: center;
-    //text-align: center;
-    //visibility: hidden; // Hide until JS can resize the images to avoid flicker
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
 
-    //&-image {
-    //  margin: 0 auto;
-    //}
+    &-image {
+      width: auto;
+      height: auto;
+    }
 
     &-caption {
       font-size: 75%;
-      padding: 1em;
+      padding: 1em 1em 0;
     }
   }
 
   &-thumbnails {
-    padding: 20px 60px 40px;
+    padding: 0 60px 20px;
+
+    &.fb-slideshow-fullscreen {
+      padding-left: 10px;
+      padding-right: 10px;
+    }
 
     &.fb-slideshow-nothumbs {
       display: none;
     }
 
-
     img {
-      height: 80px;
-      width: auto;
       cursor: pointer;
     }
   }