mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Merge pull request #1204 from dmitrylyzo/fix-slideshow-safari-webos2
Fix slideshow (Safari, WebOS 2)
This commit is contained in:
commit
b2db27a424
2 changed files with 68 additions and 21 deletions
|
@ -2,9 +2,20 @@
|
||||||
* Image viewer component
|
* Image viewer component
|
||||||
* @module components/slideshow/slideshow
|
* @module components/slideshow/slideshow
|
||||||
*/
|
*/
|
||||||
define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'focusManager', 'browser', 'apphost', 'css!./style', 'material-icons', 'paper-icon-button-light'], function (dialogHelper, inputManager, connectionManager, layoutManager, focusManager, browser, appHost) {
|
define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'focusManager', 'browser', 'apphost', 'dom', 'css!./style', 'material-icons', 'paper-icon-button-light'], function (dialogHelper, inputManager, connectionManager, layoutManager, focusManager, browser, appHost, dom) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of transition event.
|
||||||
|
*/
|
||||||
|
const transitionEndEventName = dom.whichTransitionEvent();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag to use fake image to fix blurry zoomed image.
|
||||||
|
* At least WebKit doesn't restore quality for zoomed images.
|
||||||
|
*/
|
||||||
|
const useFakeZoomImage = browser.safari;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves an item's image URL from the API.
|
* Retrieves an item's image URL from the API.
|
||||||
* @param {object|string} item - Item used to generate the image URL.
|
* @param {object|string} item - Item used to generate the image URL.
|
||||||
|
@ -240,6 +251,41 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles zoom changes.
|
||||||
|
*/
|
||||||
|
function onZoomChange(scale, imageEl, slideEl) {
|
||||||
|
const zoomImage = slideEl.querySelector('.swiper-zoom-fakeimg');
|
||||||
|
|
||||||
|
if (zoomImage) {
|
||||||
|
zoomImage.style.width = zoomImage.style.height = scale * 100 + '%';
|
||||||
|
|
||||||
|
if (scale > 1) {
|
||||||
|
if (zoomImage.classList.contains('swiper-zoom-fakeimg-hidden')) {
|
||||||
|
// Await for Swiper style changes
|
||||||
|
setTimeout(() => {
|
||||||
|
const callback = () => {
|
||||||
|
imageEl.removeEventListener(transitionEndEventName, callback);
|
||||||
|
zoomImage.classList.remove('swiper-zoom-fakeimg-hidden');
|
||||||
|
};
|
||||||
|
|
||||||
|
// Swiper set 'transition-duration: 300ms' for auto zoom
|
||||||
|
// and 'transition-duration: 0s' for touch zoom
|
||||||
|
const transitionDuration = parseFloat(imageEl.style.transitionDuration.replace(/[a-z]/i, ''));
|
||||||
|
|
||||||
|
if (transitionDuration > 0) {
|
||||||
|
imageEl.addEventListener(transitionEndEventName, callback);
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
zoomImage.classList.add('swiper-zoom-fakeimg-hidden');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the Swiper instance and binds the relevant events.
|
* Initializes the Swiper instance and binds the relevant events.
|
||||||
* @param {HTMLElement} dialog - Element containing the dialog.
|
* @param {HTMLElement} dialog - Element containing the dialog.
|
||||||
|
@ -260,8 +306,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
||||||
loop: false,
|
loop: false,
|
||||||
zoom: {
|
zoom: {
|
||||||
minRatio: 1,
|
minRatio: 1,
|
||||||
toggle: true,
|
toggle: true
|
||||||
containerClass: 'slider-zoom-container'
|
|
||||||
},
|
},
|
||||||
autoplay: !options.interactive,
|
autoplay: !options.interactive,
|
||||||
keyboard: {
|
keyboard: {
|
||||||
|
@ -288,6 +333,10 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
||||||
|
|
||||||
swiperInstance.on('autoplayStart', onAutoplayStart);
|
swiperInstance.on('autoplayStart', onAutoplayStart);
|
||||||
swiperInstance.on('autoplayStop', onAutoplayStop);
|
swiperInstance.on('autoplayStop', onAutoplayStop);
|
||||||
|
|
||||||
|
if (useFakeZoomImage) {
|
||||||
|
swiperInstance.on('zoomChange', onZoomChange);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,7 +377,10 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
||||||
function getSwiperSlideHtmlFromSlide(item) {
|
function getSwiperSlideHtmlFromSlide(item) {
|
||||||
var html = '';
|
var html = '';
|
||||||
html += '<div class="swiper-slide" data-original="' + item.originalImage + '" data-itemid="' + item.Id + '" data-serverid="' + item.ServerId + '">';
|
html += '<div class="swiper-slide" data-original="' + item.originalImage + '" data-itemid="' + item.Id + '" data-serverid="' + item.ServerId + '">';
|
||||||
html += '<div class="slider-zoom-container">';
|
html += '<div class="swiper-zoom-container">';
|
||||||
|
if (useFakeZoomImage) {
|
||||||
|
html += `<div class="swiper-zoom-fakeimg swiper-zoom-fakeimg-hidden" style="background-image: url('${item.originalImage}')"></div>`;
|
||||||
|
}
|
||||||
html += '<img src="' + item.originalImage + '" class="swiper-slide-img">';
|
html += '<img src="' + item.originalImage + '" class="swiper-slide-img">';
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
if (item.title || item.subtitle) {
|
if (item.title || item.subtitle) {
|
||||||
|
|
|
@ -40,16 +40,6 @@
|
||||||
text-shadow: 3px 3px 0 #000, -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
|
text-shadow: 3px 3px 0 #000, -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.swiper-slide-img {
|
|
||||||
max-height: 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
text-align: center;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.slideshowButtonIcon {
|
.slideshowButtonIcon {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
|
@ -135,13 +125,18 @@
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
.swiper-slide {
|
.swiper-zoom-fakeimg {
|
||||||
display: flex;
|
position: absolute;
|
||||||
flex-direction: column;
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background-position: 50% 50%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: contain;
|
||||||
|
z-index: 1;
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.slider-zoom-container {
|
.swiper-zoom-fakeimg-hidden {
|
||||||
margin: auto;
|
display: none;
|
||||||
max-height: 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue