]> _ Git - fluidbook-html5.git/commitdiff
WIP #3881 @4
authorStephen Cameron <stephen@cubedesigners.com>
Mon, 28 Sep 2020 14:33:01 +0000 (16:33 +0200)
committerStephen Cameron <stephen@cubedesigners.com>
Mon, 28 Sep 2020 14:33:01 +0000 (16:33 +0200)
js/libs/fluidbook/fluidbook.menu.js
js/libs/fluidbook/fluidbook.slideshow.js
style/fluidbook.less
style/fluidbook.slideshow.less

index f96079bde29ebc912654d66723df0ffc6b21b864..6dbc44350edd59ba708ac33b84a4a9c82013288a 100644 (file)
@@ -919,9 +919,9 @@ FluidbookMenu.prototype = {
                 // can be zero or negative. This causes an ugly jump with the thumbnails and a content redraw
                 // so we make it invisible until it is ready (resize function runs more than once)
                 if (fluidbook.slideshow.$wrapper.height() <= 0) {
-                    fluidbook.slideshow.$wrapper.css('opacity', 0);
+                    m.addClass('hidden');
                 } else {
-                    fluidbook.slideshow.$wrapper.css('opacity', 1);
+                    m.removeClass('hidden');
                 }
 
                 var horizontalPadding = fluidbook.slideshow.$slideshow.outerWidth() - fluidbook.slideshow.$slideshow.width();
@@ -951,30 +951,70 @@ FluidbookMenu.prototype = {
                     m.find('.caption, .back, .fb-slideshow-wrapper').removeClass('small');
                 }
 
-                // Default on larger screens is for modal to cover 80% of area but only if image is large enough
-                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
                     //var contentHeight = h;
                     var contentHeight = hh;
                 }
 
+                // On larger screens, the modal is sized based on a best fit for all images so that they are
+                // as large as possible but not so large that the modal exceeds 80% of the screen width and height.
+                // The modal should never be larger than necessary for the images
+                var maxModalWidth = Math.round(ww * 0.8); // Hard limit for modal width
+                var maxModalHeight = Math.round(hh * 0.8); // Hard limit for modal height
+                var maxImageWidth = maxModalWidth - horizontalPadding; // Hard limit for slideshow image width
+                var maxImageHeight = maxModalHeight - verticalPadding - headerHeight - thumbnailsHeight; // Hard limit for slideshow image height
+                var targetRatio = maxImageWidth / maxImageHeight;
+                var slideMaxWidth = 0; // Stores the largest scaled image width found
+                var slideMaxHeight = 0; // Stores the largest scaled image height found
+
+                // console.log('%cmaxImgW: '+ maxImageWidth +' | maxImageH: '+ maxImageHeight, lcss+'blueviolet')
+
+                // Process each image to determine dimensions and how big it will be once scaled onto the screen
+                fluidbook.slideshow.$slideshow.find('img').each(function() {
+                    var meta = $(this).data('meta');
+                    var scaledWidth = 0;
+                    var scaledHeight = 0;
+
+                    if (meta.width > maxImageWidth || meta.height > maxImageHeight) { // Does it need scaling?
+                        // Scale to fit depending on ratio (best fit for box)
+                        if (targetRatio > meta.ratio) {
+                            scaledWidth = Math.round(meta.width * maxImageHeight / meta.height);
+                            scaledHeight = maxImageHeight
+                        } else {
+                            scaledWidth = maxImageWidth;
+                            scaledHeight = Math.round(meta.height * maxImageWidth / meta.width);
+                        }
+
+                    } else {
+                        scaledWidth = meta.width;
+                        scaledHeight = meta.height;
+                    }
+
+                    // console.log('%cscaledW: '+ scaledWidth +' | ScaledH: '+ scaledHeight, lcss+'crimson')
+
+                    slideMaxWidth = Math.max(scaledWidth, slideMaxWidth);
+                    slideMaxHeight = Math.max(scaledHeight, slideMaxHeight);
+                });
+
+                w = slideMaxWidth + horizontalPadding;
+                h = slideMaxHeight + headerHeight + thumbnailsHeight + verticalPadding;
+
+
                 // On smaller screens, modal covers full available space
-                if (ww < 800) {
+                if (ww < 800 || hh < 500) {
                     w = ww;
                     h = hh;
                     fullscreen = true;
+                    slideMaxWidth = w - horizontalPadding;
+                    slideMaxHeight = h - headerHeight - thumbnailsHeight - verticalPadding;
                     $('.fb-slideshow, .fb-slideshow-thumbnails').addClass('fb-slideshow-fullscreen');
                 } else {
                     $('.fb-slideshow, .fb-slideshow-thumbnails').removeClass('fb-slideshow-fullscreen');
                 }
 
-                var slideMaxWidth = w - horizontalPadding;
-                var slideMaxHeight = h - headerHeight - thumbnailsHeight - verticalPadding; // Remaining height that main image + caption has to fit into
+                // console.log('%cMODAL W: '+ w +' | H: '+ h, lcss+'orangered');
+                // console.log('%cslideMaxWidth: '+ slideMaxWidth +' %cslideMaxHeight: '+ slideMaxHeight, lcss+'teal', lcss+'dodgerblue');
 
                 // console.log('%cslideMaxHeight: '+ slideMaxHeight +' %cheaderHeight: '+ headerHeight +' %cthumbnailsHeight: '+thumbnailsHeight, lcss+'teal', lcss+'blueviolet', lcss+'crimson');
                 // console.log('%cMain slideshow height: '+ $('.fb-slideshow').height(), lcss+'hotpink');
index fa8b1511c232314ed6d928d08f9906cbfdeeb2ae..609ce90615d9039847a50f9d6fee9b78348713f4 100644 (file)
@@ -12,9 +12,6 @@ FluidbookSlideshow.prototype = {
         this.thumbnailsID = this.slideshowID + '_thumbnails';
         this.$thumbnails = $(this.thumbnailsID);
         this.showThumbnails = this.$slideshow.attr('data-thumbnails') === '1';
-        this.maxImageHeight = 0; // Tallest image
-        this.maxImageWidth = 0; // Widest image
-        this.maxImageRatio = 0; // Largest aspect ratio among all images
 
 
         if (this.$slideshow.length === 0) {
@@ -30,14 +27,6 @@ FluidbookSlideshow.prototype = {
         }
         openIndex--; // Convert to zero-based index
 
-        // Determine the maximum width, height and ratio for all images
-        this.$slideshow.find('img').each(function() {
-          var meta = $(this).data('meta');
-          $this.maxImageHeight = Math.max(meta.height, $this.maxImageHeight);
-          $this.maxImageWidth = Math.max(meta.width, $this.maxImageWidth);
-          $this.maxImageRatio = Math.max(meta.width / meta.height, $this.maxImageRatio);
-        });
-
         // Height and width are set by fluidbook.menu resize function
         // Note: certain settings are set via the data-splide attribute, generated on the server-side
         var slideshowSettings = {
index e204264be2bf79289676d1b815881bbffbf56e0b..157092f06646f0adacc50ea8bb849709ed8e2695 100644 (file)
@@ -2929,4 +2929,4 @@ body > input {
 @import "tabs.less";
 @import "widget.less";
 @import "menu-articles.less";
-@import "nointerface.less";
\ No newline at end of file
+@import "nointerface.less";
index 75eba7b5c3a99967c507383e7ebe52a322017da0..f783e0d12a315d5359a40fd3eac6a3dd61b16898 100644 (file)
 
 
 // Slideshow Module
+[data-menu="slideshow"].hidden {
+  opacity: 0 !important;
+}
+
 .fb-slideshow-wrapper {
   padding-bottom: 60px;
   transition: opacity 0.15s;
   &.small {
     padding-bottom: 30px;
   }
+
+  @media (max-width: 799px) {
+    padding-bottom: 30px;
+  }
 }
 
 .fb-slideshow {