feat: minor tweaks to the preview thumbs UI
This commit is contained in:
parent
4a78b656da
commit
73bfb5211b
@ -2,6 +2,7 @@ import { createElement } from '../utils/elements';
|
|||||||
import { once } from '../utils/events';
|
import { once } from '../utils/events';
|
||||||
import fetch from '../utils/fetch';
|
import fetch from '../utils/fetch';
|
||||||
import is from '../utils/is';
|
import is from '../utils/is';
|
||||||
|
import { clamp } from '../utils/numbers';
|
||||||
import { formatTime } from '../utils/time';
|
import { formatTime } from '../utils/time';
|
||||||
|
|
||||||
// Arg: vttDataString example: "WEBVTT\n\n1\n00:00:05.000 --> 00:00:10.000\n1080p-00001.jpg"
|
// Arg: vttDataString example: "WEBVTT\n\n1\n00:00:05.000 --> 00:00:10.000\n1080p-00001.jpg"
|
||||||
@ -109,9 +110,7 @@ class PreviewThumbnails {
|
|||||||
this.player.elements.display.seekTooltip.hidden = this.enabled;
|
this.player.elements.display.seekTooltip.hidden = this.enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.enabled) {
|
if (!this.enabled) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.getThumbnails().then(() => {
|
this.getThumbnails().then(() => {
|
||||||
if (!this.enabled) {
|
if (!this.enabled) {
|
||||||
@ -205,18 +204,12 @@ class PreviewThumbnails {
|
|||||||
};
|
};
|
||||||
|
|
||||||
startMove = (event) => {
|
startMove = (event) => {
|
||||||
if (!this.loaded) {
|
if (!this.loaded) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is.event(event) || !['touchmove', 'mousemove'].includes(event.type)) {
|
if (!is.event(event) || !['touchmove', 'mousemove'].includes(event.type)) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait until media has a duration
|
// Wait until media has a duration
|
||||||
if (!this.player.media.duration) {
|
if (!this.player.media.duration) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.type === 'touchmove') {
|
if (event.type === 'touchmove') {
|
||||||
// Calculate seek hover position as approx video seconds
|
// Calculate seek hover position as approx video seconds
|
||||||
@ -391,7 +384,7 @@ class PreviewThumbnails {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Only proceed if either thumbnum or thumbfilename has changed
|
// Only proceed if either thumb num or thumbfilename has changed
|
||||||
if (thumbNum !== this.showingThumb) {
|
if (thumbNum !== this.showingThumb) {
|
||||||
this.showingThumb = thumbNum;
|
this.showingThumb = thumbNum;
|
||||||
this.loadImage(qualityIndex);
|
this.loadImage(qualityIndex);
|
||||||
@ -562,11 +555,7 @@ class PreviewThumbnails {
|
|||||||
};
|
};
|
||||||
|
|
||||||
get currentImageContainer() {
|
get currentImageContainer() {
|
||||||
if (this.mouseDown) {
|
return this.mouseDown ? this.elements.scrubbing.container : this.elements.thumb.imageContainer;
|
||||||
return this.elements.scrubbing.container;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.elements.thumb.imageContainer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get usingSprites() {
|
get usingSprites() {
|
||||||
@ -599,11 +588,7 @@ class PreviewThumbnails {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get currentImageElement() {
|
get currentImageElement() {
|
||||||
if (this.mouseDown) {
|
return this.mouseDown ? this.currentScrubbingImageElement : this.currentThumbnailImageElement;
|
||||||
return this.currentScrubbingImageElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.currentThumbnailImageElement;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set currentImageElement(element) {
|
set currentImageElement(element) {
|
||||||
@ -643,46 +628,39 @@ class PreviewThumbnails {
|
|||||||
|
|
||||||
// Set the size to be about a quarter of the size of video. Unless option dynamicSize === false, in which case it needs to be set in CSS
|
// Set the size to be about a quarter of the size of video. Unless option dynamicSize === false, in which case it needs to be set in CSS
|
||||||
setThumbContainerSizeAndPos = () => {
|
setThumbContainerSizeAndPos = () => {
|
||||||
|
const { imageContainer } = this.elements.thumb;
|
||||||
|
|
||||||
if (!this.sizeSpecifiedInCSS) {
|
if (!this.sizeSpecifiedInCSS) {
|
||||||
const thumbWidth = Math.floor(this.thumbContainerHeight * this.thumbAspectRatio);
|
const thumbWidth = Math.floor(this.thumbContainerHeight * this.thumbAspectRatio);
|
||||||
this.elements.thumb.imageContainer.style.height = `${this.thumbContainerHeight}px`;
|
imageContainer.style.height = `${this.thumbContainerHeight}px`;
|
||||||
this.elements.thumb.imageContainer.style.width = `${thumbWidth}px`;
|
imageContainer.style.width = `${thumbWidth}px`;
|
||||||
} else if (
|
} else if (imageContainer.clientHeight > 20 && imageContainer.clientWidth < 20) {
|
||||||
this.elements.thumb.imageContainer.clientHeight > 20 &&
|
const thumbWidth = Math.floor(imageContainer.clientHeight * this.thumbAspectRatio);
|
||||||
this.elements.thumb.imageContainer.clientWidth < 20
|
imageContainer.style.width = `${thumbWidth}px`;
|
||||||
) {
|
} else if (imageContainer.clientHeight < 20 && imageContainer.clientWidth > 20) {
|
||||||
const thumbWidth = Math.floor(this.elements.thumb.imageContainer.clientHeight * this.thumbAspectRatio);
|
const thumbHeight = Math.floor(imageContainer.clientWidth / this.thumbAspectRatio);
|
||||||
this.elements.thumb.imageContainer.style.width = `${thumbWidth}px`;
|
imageContainer.style.height = `${thumbHeight}px`;
|
||||||
} else if (
|
|
||||||
this.elements.thumb.imageContainer.clientHeight < 20 &&
|
|
||||||
this.elements.thumb.imageContainer.clientWidth > 20
|
|
||||||
) {
|
|
||||||
const thumbHeight = Math.floor(this.elements.thumb.imageContainer.clientWidth / this.thumbAspectRatio);
|
|
||||||
this.elements.thumb.imageContainer.style.height = `${thumbHeight}px`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setThumbContainerPos();
|
this.setThumbContainerPos();
|
||||||
};
|
};
|
||||||
|
|
||||||
setThumbContainerPos = () => {
|
setThumbContainerPos = () => {
|
||||||
const seekbarRect = this.player.elements.progress.getBoundingClientRect();
|
const scrubberRect = this.player.elements.progress.getBoundingClientRect();
|
||||||
const plyrRect = this.player.elements.container.getBoundingClientRect();
|
const containerRect = this.player.elements.container.getBoundingClientRect();
|
||||||
const { container } = this.elements.thumb;
|
const { container } = this.elements.thumb;
|
||||||
// Find the lowest and highest desired left-position, so we don't slide out the side of the video container
|
// Find the lowest and highest desired left-position, so we don't slide out the side of the video container
|
||||||
const minVal = plyrRect.left - seekbarRect.left + 10;
|
const min = containerRect.left - scrubberRect.left + 10;
|
||||||
const maxVal = plyrRect.right - seekbarRect.left - container.clientWidth - 10;
|
const max = containerRect.right - scrubberRect.left - container.clientWidth - 10;
|
||||||
// Set preview container position to: mousepos, minus seekbar.left, minus half of previewContainer.clientWidth
|
// Set preview container position to: mousepos, minus seekbar.left, minus half of previewContainer.clientWidth
|
||||||
let previewPos = this.mousePosX - seekbarRect.left - container.clientWidth / 2;
|
const position = this.mousePosX - scrubberRect.left - container.clientWidth / 2;
|
||||||
|
const clamped = clamp(position, min, max);
|
||||||
|
|
||||||
if (previewPos < minVal) {
|
// Move the popover position
|
||||||
previewPos = minVal;
|
container.style.left = `${clamped}px`;
|
||||||
}
|
|
||||||
|
|
||||||
if (previewPos > maxVal) {
|
// The arrow can follow the cursor
|
||||||
previewPos = maxVal;
|
container.style.setProperty('--preview-arrow-offset', `${position - clamped}px`);
|
||||||
}
|
|
||||||
|
|
||||||
container.style.left = `${previewPos}px`;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Can't use 100% width, in case the video is a different aspect ratio to the video container
|
// Can't use 100% width, in case the video is a different aspect ratio to the video container
|
||||||
@ -697,9 +675,7 @@ class PreviewThumbnails {
|
|||||||
|
|
||||||
// Sprites need to be offset to the correct location
|
// Sprites need to be offset to the correct location
|
||||||
setImageSizeAndOffset = (previewImage, frame) => {
|
setImageSizeAndOffset = (previewImage, frame) => {
|
||||||
if (!this.usingSprites) {
|
if (!this.usingSprites) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find difference between height and preview container height
|
// Find difference between height and preview container height
|
||||||
const multiplier = this.thumbContainerHeight / frame.h;
|
const multiplier = this.thumbContainerHeight / frame.h;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* @param {Number} input
|
* @param {Number} input
|
||||||
* @param {Number} min The lower boundary of the output range
|
* @param {Number} min The lower boundary of the output range
|
||||||
* @param {Number} max The upper boundary of the output range
|
* @param {Number} max The upper boundary of the output range
|
||||||
* @returns A number in the range [min, max]
|
* @returns A number within the bounds of min and max
|
||||||
* @type Number
|
* @type Number
|
||||||
*/
|
*/
|
||||||
export function clamp(input = 0, min = 0, max = 255) {
|
export function clamp(input = 0, min = 0, max = 255) {
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
bottom: calc(#{$plyr-preview-arrow-size} * -1);
|
bottom: calc(#{$plyr-preview-arrow-size} * -1);
|
||||||
content: '';
|
content: '';
|
||||||
height: 0;
|
height: 0;
|
||||||
left: 50%;
|
left: calc(50% + var(--preview-arrow-offset));
|
||||||
position: absolute;
|
position: absolute;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
width: 0;
|
width: 0;
|
||||||
@ -46,15 +46,27 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
|
|
||||||
img {
|
img,
|
||||||
height: 100%; // Non sprite images are 100%. Sprites will have their size applied by JavaScript
|
&::after {
|
||||||
|
height: 100%;
|
||||||
left: 0;
|
left: 0;
|
||||||
max-height: none;
|
|
||||||
max-width: none;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
border-radius: inherit;
|
||||||
|
box-shadow: inset 0 0 0 1px rgba(#000, 15%);
|
||||||
|
content: '';
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
// Non sprite images are 100%. Sprites will have their size applied by JavaScript
|
||||||
|
max-height: none;
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Seek time text
|
// Seek time text
|
||||||
|
Loading…
x
Reference in New Issue
Block a user