From: Stephen Cameron Date: Thu, 24 Sep 2020 17:29:43 +0000 (+0200) Subject: Slideshow module revamp. WIP #3881 @10 X-Git-Url: http://git.cubedesigners.com/?a=commitdiff_plain;h=cc3240cb1ac1b056b3641ed4e9ede487626effd9;p=fluidbook-html5.git Slideshow module revamp. WIP #3881 @10 --- diff --git a/js/libs/fluidbook/fluidbook.js b/js/libs/fluidbook/fluidbook.js index 7c16acf5..58fc5188 100644 --- a/js/libs/fluidbook/fluidbook.js +++ b/js/libs/fluidbook/fluidbook.js @@ -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 = $('' + links + ''); @@ -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 () { diff --git a/js/libs/fluidbook/fluidbook.menu.js b/js/libs/fluidbook/fluidbook.menu.js index 0a66de5a..6a1a688e 100644 --- a/js/libs/fluidbook/fluidbook.menu.js +++ b/js/libs/fluidbook/fluidbook.menu.js @@ -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; diff --git a/js/libs/fluidbook/fluidbook.slideshow.js b/js/libs/fluidbook/fluidbook.slideshow.js index f44f8638..622ce0bb 100644 --- a/js/libs/fluidbook/fluidbook.slideshow.js +++ b/js/libs/fluidbook/fluidbook.slideshow.js @@ -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'); - } - */ -} +}; diff --git a/style/fluidbook.slideshow.less b/style/fluidbook.slideshow.less index e8067ba5..cb7d60e4 100644 --- a/style/fluidbook.slideshow.less +++ b/style/fluidbook.slideshow.less @@ -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 { @@ -224,13 +225,24 @@ //=== 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 { @@ -319,10 +331,11 @@ .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 { } @@ -334,34 +347,35 @@ } &-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; } }