diff options
author | Sam Potts <sam@potts.es> | 2021-05-12 23:31:01 +1000 |
---|---|---|
committer | Sam Potts <sam@potts.es> | 2021-05-12 23:37:05 +1000 |
commit | 5fd4391cd923bac874f67413cbacc42c77648759 (patch) | |
tree | f1c9f02aed2989597e9c4cb6dcb231831a3c98ed /src/js/listeners.js | |
parent | b050fde276b181464e0ccbf2d3ac7835032517fd (diff) | |
download | plyr-5fd4391cd923bac874f67413cbacc42c77648759.tar.lz plyr-5fd4391cd923bac874f67413cbacc42c77648759.tar.xz plyr-5fd4391cd923bac874f67413cbacc42c77648759.zip |
fix: fullscreen issues with Vimeo (fixes #2175)
Diffstat (limited to 'src/js/listeners.js')
-rw-r--r-- | src/js/listeners.js | 86 |
1 files changed, 41 insertions, 45 deletions
diff --git a/src/js/listeners.js b/src/js/listeners.js index 3d1f8ef0..c490070c 100644 --- a/src/js/listeners.js +++ b/src/js/listeners.js @@ -10,7 +10,7 @@ import { getElement, getElements, matches, toggleClass } from './utils/elements' import { off, on, once, toggleListener, triggerEvent } from './utils/events'; import is from './utils/is'; import { silencePromise } from './utils/promise'; -import { getAspectRatio, setAspectRatio } from './utils/style'; +import { getAspectRatio, getViewportSize, supportsCSS } from './utils/style'; class Listeners { constructor(player) { @@ -149,16 +149,16 @@ class Listeners { break; /* case 73: - this.setLoop('start'); - break; + this.setLoop('start'); + break; - case 76: - this.setLoop(); - break; + case 76: + this.setLoop(); + break; - case 79: - this.setLoop('end'); - break; */ + case 79: + this.setLoop('end'); + break; */ default: break; @@ -305,39 +305,49 @@ class Listeners { ); // Set a gutter for Vimeo - const setGutter = (ratio, padding, toggle) => { + const setGutter = () => { if (!player.isVimeo || player.config.vimeo.premium) { return; } - const target = player.elements.wrapper.firstChild; - const [, y] = ratio; - const [videoX, videoY] = getAspectRatio.call(player); - - target.style.maxWidth = toggle ? `${(y / videoY) * videoX}px` : null; - target.style.margin = toggle ? '0 auto' : null; - }; + const target = elements.wrapper; + const { active } = player.fullscreen; + const [videoWidth, videoHeight] = getAspectRatio.call(player); + const useNativeAspectRatio = supportsCSS(`aspect-ratio: ${videoWidth} / ${videoHeight}`); - // Resize on fullscreen change - const setPlayerSize = (measure) => { - // If we don't need to measure the viewport - if (!measure) { - return setAspectRatio.call(player); + // If not active, remove styles + if (!active) { + if (useNativeAspectRatio) { + target.style.width = null; + target.style.height = null; + } else { + target.style.maxWidth = null; + target.style.margin = null; + } + return; } - const rect = elements.container.getBoundingClientRect(); - const { width, height } = rect; + // Determine which dimension will overflow and constrain view + const [viewportWidth, viewportHeight] = getViewportSize(); + const overflow = viewportWidth / viewportHeight > videoWidth / videoHeight; - return setAspectRatio.call(player, `${width}:${height}`); + if (useNativeAspectRatio) { + target.style.width = overflow ? 'auto' : '100%'; + target.style.height = overflow ? '100%' : 'auto'; + } else { + target.style.maxWidth = overflow ? `${(viewportHeight / videoHeight) * videoWidth}px` : null; + target.style.margin = overflow ? '0 auto' : null; + } }; + // Handle resizing const resized = () => { clearTimeout(timers.resized); - timers.resized = setTimeout(setPlayerSize, 50); + timers.resized = setTimeout(setGutter, 50); }; on.call(player, elements.container, 'enterfullscreen exitfullscreen', (event) => { - const { target, usingNative } = player.fullscreen; + const { target } = player.fullscreen; // Ignore events not from target if (target !== elements.container) { @@ -349,26 +359,12 @@ class Listeners { return; } - const isEnter = event.type === 'enterfullscreen'; - // Set the player size when entering fullscreen to viewport size - const { padding, ratio } = setPlayerSize(isEnter); - // Set Vimeo gutter - setGutter(ratio, padding, isEnter); - - // Horrible hack for Safari 14 not repainting properly on entering fullscreen - if (isEnter) { - setTimeout(() => repaint(elements.container), 100); - } + setGutter(); - // If not using native browser fullscreen API, we need to check for resizes of viewport - if (!usingNative) { - if (isEnter) { - on.call(player, window, 'resize', resized); - } else { - off.call(player, window, 'resize', resized); - } - } + // Watch for resizes + const method = event.type === 'enterfullscreen' ? on : off; + method.call(player, window, 'resize', resized); }); }; |