diff --git a/packages/react/src/video.tsx b/packages/react/src/video.tsx index 12bc5727..4b093b0f 100644 --- a/packages/react/src/video.tsx +++ b/packages/react/src/video.tsx @@ -44,7 +44,27 @@ export const Video: (props: VideoProperties & RefAttributes) => const providedHtmlElement = props.src instanceof HTMLVideoElement ? props.src : undefined - const element = useMemo(() => providedHtmlElement ?? document.createElement('video'), [providedHtmlElement]) + const element = useMemo(() => { + if (providedHtmlElement != null) { + return providedHtmlElement + } + const result = document.createElement('video') + result.style.position = 'absolute' + result.style.width = '1px' + result.style.zIndex = '-1000' + result.style.top = '0px' + result.style.left = '0px' + return result + }, [providedHtmlElement]) + + const isElementProvided = props.src instanceof HTMLVideoElement + useEffect(() => { + if (isElementProvided) { + return + } + document.body.appendChild(element) + return () => element.remove() + }, [element, isElementProvided]) const invalidate = useThree((s) => s.invalidate) useEffect(() => setupVideoElementInvalidation(element, invalidate), [element, invalidate]) diff --git a/packages/uikit/src/components/video.ts b/packages/uikit/src/components/video.ts index 08f559de..7ac57c2a 100644 --- a/packages/uikit/src/components/video.ts +++ b/packages/uikit/src/components/video.ts @@ -15,6 +15,9 @@ type InternalVideoProperties = { autoplay?: boolean } +/** + * @requires that the element is attached to the document and therefore should be hidden (position = 'absolute', width = '1px', zIndex = '-1000', top = '0px', left = '0px') + */ export function updateVideoElement( element: HTMLVideoElement, { src, autoplay, loop, muted, playbackRate, preservesPitch, volume }: InternalVideoProperties, @@ -23,15 +26,6 @@ export function updateVideoElement( return } - if (autoplay) { - element.remove() - document.body.append(element) - element.style.position = 'absolute' - element.style.width = '1px' - element.style.zIndex = '-1000' - element.style.top = '0px' - element.style.left = '0px' - } element.playsInline = true element.volume = volume ?? 1 element.preservesPitch = preservesPitch ?? true