Improved player timeline tooltip
This commit is contained in:
@@ -120,6 +120,7 @@
|
||||
let playerSliderDebounce: ReturnType<typeof setTimeout>;
|
||||
let playerVolumeElement: HTMLElement | undefined = $state();
|
||||
let playerIsFullscreen: boolean = $state(false);
|
||||
let playerTimelineTooltip: HTMLDivElement | undefined = $state();
|
||||
let playerInitalInteract = true;
|
||||
|
||||
const playerTimelineSlider = new Slider({
|
||||
@@ -1099,26 +1100,41 @@
|
||||
}
|
||||
|
||||
let requestAnimationTooltip: number | undefined;
|
||||
let latestMouseX: number | undefined;
|
||||
|
||||
function timelineMouseMove(event: MouseEvent) {
|
||||
if (requestAnimationTooltip) return;
|
||||
latestMouseX = event.clientX;
|
||||
|
||||
requestAnimationTooltip = requestAnimationFrame(() => {
|
||||
if (!playerSliderElement) return;
|
||||
const rect = playerSliderElement.getBoundingClientRect();
|
||||
|
||||
const percent = Math.min(
|
||||
Math.max((event.clientX - rect.left) / playerSliderElement.clientWidth, 0),
|
||||
1
|
||||
);
|
||||
|
||||
playerTimelineTimeHover = percent * (data.video.lengthSeconds ?? 0);
|
||||
|
||||
document.documentElement.style.setProperty('--timeline-tooltip-left', `${percent * 100}%`);
|
||||
|
||||
setPlayerTimelineChapters(playerTimelineTimeHover);
|
||||
if (!requestAnimationTooltip) {
|
||||
requestAnimationTooltip = requestAnimationFrame(updateTooltip);
|
||||
}
|
||||
}
|
||||
|
||||
function updateTooltip() {
|
||||
if (!playerSliderElement || latestMouseX === undefined) {
|
||||
requestAnimationTooltip = undefined;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const rect = playerSliderElement.getBoundingClientRect();
|
||||
const percent = Math.min(Math.max((latestMouseX - rect.left) / rect.width, 0), 1);
|
||||
|
||||
playerTimelineTimeHover = percent * (data.video.lengthSeconds ?? 0);
|
||||
setPlayerTimelineChapters(playerTimelineTimeHover);
|
||||
|
||||
if (playerTimelineTooltip) {
|
||||
const tooltipWidth = playerTimelineTooltip.offsetWidth;
|
||||
const tooltipHeight = playerTimelineTooltip.offsetHeight;
|
||||
const sliderWidth = playerSliderElement.clientWidth;
|
||||
|
||||
let left = percent * sliderWidth;
|
||||
left = Math.min(Math.max(left, tooltipWidth / 2), sliderWidth - tooltipWidth / 2);
|
||||
playerTimelineTooltip.style.transform = `translateX(${left - tooltipWidth / 2}px)`;
|
||||
|
||||
playerTimelineTooltip.style.top = `${-tooltipHeight - 5}px`;
|
||||
}
|
||||
|
||||
requestAnimationTooltip = undefined;
|
||||
}
|
||||
|
||||
function onVideoClick(
|
||||
@@ -1302,31 +1318,26 @@
|
||||
onmousemove={timelineMouseMove}
|
||||
bind:this={playerSliderElement}
|
||||
>
|
||||
{#snippet timelineTooltip()}
|
||||
{#if playerCloestSponsor}
|
||||
{sponsorSegments[playerCloestSponsor.category]}
|
||||
<br />
|
||||
{:else if playerCloestTimestamp}
|
||||
{playerCloestTimestamp.title}
|
||||
<br />
|
||||
{/if}
|
||||
{/snippet}
|
||||
<div class="track">
|
||||
{#if !userManualSeeking}
|
||||
<div class="tooltip" style="position: absolute;left: var(--timeline-tooltip-left);">
|
||||
{#if playerCloestSponsor}
|
||||
{sponsorSegments[playerCloestSponsor.category]}
|
||||
<br />
|
||||
{:else if playerCloestTimestamp}
|
||||
{playerCloestTimestamp.title}
|
||||
<br />
|
||||
{/if}
|
||||
|
||||
<div bind:this={playerTimelineTooltip} class="timeline tooltip">
|
||||
{@render timelineTooltip()}
|
||||
{videoLength(playerTimelineTimeHover)}
|
||||
</div>
|
||||
{/if}
|
||||
<div class="range"></div>
|
||||
<div {...playerTimelineSlider.thumb}>
|
||||
<div class="tooltip thumb-tooltip">
|
||||
{#if playerCloestSponsor}
|
||||
{sponsorSegments[playerCloestSponsor.category]}
|
||||
<br />
|
||||
{:else if playerCloestTimestamp}
|
||||
{playerCloestTimestamp.title}
|
||||
<br />
|
||||
{/if}
|
||||
|
||||
{@render timelineTooltip()}
|
||||
{videoLength(currentTime)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1808,4 +1819,13 @@
|
||||
.hide-cursor {
|
||||
cursor: none;
|
||||
}
|
||||
|
||||
.timeline.tooltip {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
transform: translateX(0%);
|
||||
transition: none;
|
||||
pointer-events: none;
|
||||
will-change: transform;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -121,6 +121,14 @@ menu {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
background-color: var(--surface) !important;
|
||||
border: 0.1px solid var(--primary) !important;
|
||||
box-shadow: none !important;
|
||||
border-radius: 0.25rem !important;
|
||||
color: var(--on-surface) !important;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1000px) {
|
||||
menu.mobile {
|
||||
position: fixed !important;
|
||||
|
||||
Reference in New Issue
Block a user