streamlined control button position

This commit is contained in:
MinamiFunakoshiTR 2025-03-26 15:48:39 -07:00
parent 0dfa8c5959
commit aa24b06937
Failed to extract signature
3 changed files with 53 additions and 28 deletions

View file

@ -10,6 +10,8 @@
// types
import type { ContainerWidth } from '../@types/global';
import type { Snippet } from 'svelte';
import type { ControlsPosition } from './types';
import { getButtonPosition } from './utils';
interface Props {
/** Video source */
@ -55,12 +57,9 @@
/** Change the opacity of the play/pause button */
controlsOpacity?: number;
/** Have four options for controls position - top right, top left, bottom right, bottom left */
controlsPosition?:
| 'top right'
| 'top left'
| 'center'
| 'bottom right'
| 'bottom left';
controlsPosition?: ControlsPosition;
/** Offset for the controls from the border */
controlsBorderOffset?: number;
}
let {
@ -83,9 +82,10 @@
possibleToPlayPause = true,
showControls = true,
separateReplayIcon = false,
controlsColour = '#333',
controlsColour = 'red', // '#333',
controlsOpacity = 0.5,
controlsPosition = 'top left',
controlsPosition = 'bottom left',
controlsBorderOffset = 10,
}: Props = $props();
/// //////////////////////////////////
@ -107,7 +107,6 @@
let widthVideo = $state(0);
let heightVideoContainer = $state(0);
let widthVideoContainer = $state(0);
const controlsBorderOffset = 50;
// For intersection observer
let intersecting = $state(false);
@ -116,12 +115,15 @@
// For video with sound, check if there has been an interaction with the DOM
let interactedWithDom = false;
const setInteractedWithDom = () => {
interactedWithDom = true;
};
const setInteractedWithDom = () => (interactedWithDom = true);
let interactiveControlsOpacity = $state(controlsOpacity);
// Get control button positioning
let controlButtonPosition = $derived.by(() =>
getButtonPosition(controlsPosition, controlsBorderOffset)
);
/** Control play/pause */
$effect(() => {
// Play the video (with no sound) if it's intersecting; pause when it's no longer intersecting
@ -159,23 +161,14 @@
class="controls"
onclick={() => {
paused = !paused;
// clickedOnPauseBtn = paused === true; // so video doesn't autoplay when coming into view again if paused previously
clickedOnPauseBtn = paused === true; // so video doesn't autoplay when coming into view again if paused previously
}}
style="
opacity: {interactiveControlsOpacity};
top: {controlsPosition === 'top left' || controlsPosition === 'top right' ?
`${10}px`
: controlsPosition === 'center' ?
`${(heightVideoContainer - controlsBorderOffset) / 2}px`
: `${heightVideoContainer - controlsBorderOffset}px`};
left: {(
controlsPosition === 'top left' || controlsPosition === 'bottom left'
) ?
`${10}px`
: controlsPosition === 'center' ?
`${(widthVideoContainer - controlsBorderOffset) / 2}px`
: `${widthVideoContainer - controlsBorderOffset}px`};
top: {controlButtonPosition.top}px;
bottom: {controlButtonPosition.bottom}px;
left: {controlButtonPosition.left}px;
right: {controlButtonPosition.right}px;
"
>
{#if resetCondition}
@ -234,10 +227,10 @@
interactiveControlsOpacity = controlsOpacity;
}}
onmouseout={() => {
interactiveControlsOpacity = 0;
interactiveControlsOpacity = 1;
}}
onblur={() => {
interactiveControlsOpacity = 0;
interactiveControlsOpacity = 1;
}}
>
{#if (hidden && ariaDescription) || !hidden}

View file

@ -0,0 +1,5 @@
export type ControlsPosition =
| 'top right'
| 'top left'
| 'bottom right'
| 'bottom left';

View file

@ -0,0 +1,27 @@
import type { ControlsPosition } from './types';
/** Returns the pixel values for positioning the controls button */
export const getButtonPosition = (
controlsPosition: ControlsPosition,
borderOffset: number
) => {
if (controlsPosition === 'top left')
return {
top: borderOffset,
left: borderOffset,
};
if (controlsPosition === 'bottom left')
return {
bottom: borderOffset,
left: borderOffset,
};
if (controlsPosition === 'bottom right')
return {
bottom: borderOffset,
right: borderOffset,
};
return {
top: borderOffset,
right: borderOffset,
};
};