From 9c7e429b48320f6b021baa2ed23e35a6bd9ceae5 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Sun, 19 Apr 2020 19:51:06 +1000 Subject: [PATCH] Vimeo ratio fixes --- src/js/config/defaults.js | 8 +++--- src/js/listeners.js | 25 ++++++++++--------- src/js/plugins/vimeo.js | 52 ++++++++++++++++++++++----------------- src/js/utils/style.js | 5 ++-- src/sass/lib/mixins.scss | 2 -- src/sass/types/video.scss | 1 + 6 files changed, 51 insertions(+), 42 deletions(-) diff --git a/src/js/config/defaults.js b/src/js/config/defaults.js index bd4052be..087a5cb7 100644 --- a/src/js/config/defaults.js +++ b/src/js/config/defaults.js @@ -419,16 +419,16 @@ const defaults = { title: false, speed: true, transparent: false, - // These settings require a pro or premium account to work - sidedock: false, - controls: false, + // Whether the owner of the video has a Pro or Business account + // (which allows us to properly hide controls without CSS hacks, etc) + premium: false, // Custom settings from Plyr referrerPolicy: null, // https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/referrerPolicy }, // YouTube plugin youtube: { - noCookie: false, // Whether to use an alternative version of YouTube without cookies + noCookie: true, // Whether to use an alternative version of YouTube without cookies rel: 0, // No related vids showinfo: 0, // Hide info iv_load_policy: 3, // Hide annotations diff --git a/src/js/listeners.js b/src/js/listeners.js index e4c3c132..dd2c4834 100644 --- a/src/js/listeners.js +++ b/src/js/listeners.js @@ -229,16 +229,18 @@ class Listeners { // Delay the adding of classname until the focus has changed // This event fires before the focusin event - this.focusTimer = setTimeout(() => { - const focused = document.activeElement; + if (event.type !== 'focusout') { + this.focusTimer = setTimeout(() => { + const focused = document.activeElement; - // Ignore if current focus element isn't inside the player - if (!elements.container.contains(focused)) { - return; - } + // Ignore if current focus element isn't inside the player + if (!elements.container.contains(focused)) { + return; + } - toggleClass(document.activeElement, player.config.classNames.tabFocus, true); - }, 10); + toggleClass(document.activeElement, player.config.classNames.tabFocus, true); + }, 10); + } } // Global window & document listeners @@ -257,7 +259,7 @@ class Listeners { once.call(player, document.body, 'touchstart', this.firstTouch); // Tab focus detection - toggleListener.call(player, document.body, 'keydown focus blur', this.setTabFocus, toggle, false, true); + toggleListener.call(player, document.body, 'keydown focus blur focusout', this.setTabFocus, toggle, false, true); } // Container listeners @@ -304,7 +306,7 @@ class Listeners { // Set a gutter for Vimeo const setGutter = (ratio, padding, toggle) => { - if (!player.isVimeo) { + if (!player.isVimeo || player.config.vimeo.premium) { return; } @@ -331,6 +333,7 @@ class Listeners { const resized = () => { clearTimeout(timers.resized); + timers.resized = setTimeout(setPlayerSize, 50); }; @@ -354,7 +357,7 @@ class Listeners { // Set Vimeo gutter setGutter(ratio, padding, isEnter); - // If not using native fullscreen, we need to check for resizes of viewport + // If not using the native browser fullscreen API, we need to check for resizes of viewport if (!usingNative) { if (isEnter) { on.call(player, window, 'resize', resized); diff --git a/src/js/plugins/vimeo.js b/src/js/plugins/vimeo.js index 0937d62d..392512ca 100644 --- a/src/js/plugins/vimeo.js +++ b/src/js/plugins/vimeo.js @@ -10,7 +10,6 @@ import { triggerEvent } from '../utils/events'; import fetch from '../utils/fetch'; import is from '../utils/is'; import loadScript from '../utils/load-script'; -import { extend } from '../utils/objects'; import { format, stripHTML } from '../utils/strings'; import { setAspectRatio } from '../utils/style'; import { buildUrlParams } from '../utils/urls'; @@ -71,21 +70,25 @@ const vimeo = { ready() { const player = this; const config = player.config.vimeo; + const { premium, referrerPolicy, ...frameParams } = config; + + // If the owner has a pro or premium account then we can hide controls etc + if (premium) { + Object.assign(frameParams, { + controls: false, + sidedock: false, + }); + } // Get Vimeo params for the iframe - const params = buildUrlParams( - extend( - {}, - { - loop: player.config.loop.active, - autoplay: player.autoplay, - muted: player.muted, - gesture: 'media', - playsinline: !this.config.fullscreen.iosNative, - }, - config, - ), - ); + const params = buildUrlParams({ + loop: player.config.loop.active, + autoplay: player.autoplay, + muted: player.muted, + gesture: 'media', + playsinline: !this.config.fullscreen.iosNative, + ...frameParams, + }); // Get the source URL or ID let source = player.media.getAttribute('src'); @@ -101,20 +104,23 @@ const vimeo = { const src = format(player.config.urls.vimeo.iframe, id, params); iframe.setAttribute('src', src); iframe.setAttribute('allowfullscreen', ''); - iframe.setAttribute('allowtransparency', ''); - iframe.setAttribute('allow', 'autoplay'); + iframe.setAttribute('allow', 'autoplay,fullscreen,picture-in-picture'); // Set the referrer policy if required - if (!is.empty(config.referrerPolicy)) { - iframe.setAttribute('referrerPolicy', config.referrerPolicy); + if (!is.empty(referrerPolicy)) { + iframe.setAttribute('referrerPolicy', referrerPolicy); } - // Get poster, if already set - const { poster } = player; // Inject the package - const wrapper = createElement('div', { poster, class: player.config.classNames.embedContainer }); - wrapper.appendChild(iframe); - player.media = replaceElement(wrapper, player.media); + const { poster } = player; + if (premium) { + iframe.setAttribute('poster', poster); + player.media = replaceElement(iframe, player.media); + } else { + const wrapper = createElement('div', { class: player.config.classNames.embedContainer, poster }); + wrapper.appendChild(iframe); + player.media = replaceElement(wrapper, player.media); + } // Get poster image fetch(format(player.config.urls.vimeo.api, id), 'json').then(response => { diff --git a/src/js/utils/style.js b/src/js/utils/style.js index 0a37e595..c2004fcb 100644 --- a/src/js/utils/style.js +++ b/src/js/utils/style.js @@ -64,9 +64,10 @@ export function setAspectRatio(input) { wrapper.style.paddingBottom = `${padding}%`; // For Vimeo we have an extra
to hide the standard controls and UI - if (this.isVimeo && this.supported.ui) { - const height = 240; + if (this.isVimeo && !this.config.vimeo.premium && this.supported.ui) { + const height = (100 / this.media.offsetWidth) * parseInt(window.getComputedStyle(this.media).paddingBottom, 10); const offset = (height - padding) / (height / 50); + this.media.style.transform = `translateY(-${offset}%)`; } else if (this.isHTML5) { wrapper.classList.toggle(this.config.classNames.videoFixedRatio, ratio !== null); diff --git a/src/sass/lib/mixins.scss b/src/sass/lib/mixins.scss index 1eaa1a6c..9186fec6 100644 --- a/src/sass/lib/mixins.scss +++ b/src/sass/lib/mixins.scss @@ -71,8 +71,6 @@ &.plyr--vimeo .plyr__video-wrapper { height: 0; position: relative; - top: 50%; - transform: translateY(-50%); } // Display correct icon diff --git a/src/sass/types/video.scss b/src/sass/types/video.scss index a259465f..c18c1b45 100644 --- a/src/sass/types/video.scss +++ b/src/sass/types/video.scss @@ -17,6 +17,7 @@ height: 100%; margin: auto; overflow: hidden; + position: relative; width: 100%; }