mirror of
https://github.com/zoriya/v10.git
synced 2026-08-11 08:29:47 +00:00
82 lines
2.9 KiB
JavaScript
82 lines
2.9 KiB
JavaScript
"use client";
|
|
import { useOptionalPlayer } from "../../player/context.js";
|
|
import { useDestroy } from "../../utils/use-destroy.js";
|
|
import { renderElement } from "../../utils/use-render.js";
|
|
import { createThumbnail, selectTextTrack } from "@videojs/core/dom";
|
|
import { forwardRef, useMemo, useRef, useState } from "react";
|
|
import { jsx } from "react/jsx-runtime";
|
|
import { ThumbnailCore, ThumbnailDataAttrs, mapCuesToThumbnails } from "@videojs/core";
|
|
//#region src/ui/thumbnail/thumbnail.tsx
|
|
const Thumbnail = forwardRef(function Thumbnail(componentProps, forwardedRef) {
|
|
const { render, className, style, time = 0, thumbnails: externalThumbnails, crossOrigin, loading, fetchPriority, ...elementProps } = componentProps;
|
|
const [core] = useState(() => new ThumbnailCore());
|
|
const divRef = useRef(null);
|
|
const imgRef = useRef(null);
|
|
const textTrack = useOptionalPlayer(selectTextTrack);
|
|
const [, setRenderToken] = useState(0);
|
|
const [handle] = useState(() => createThumbnail({
|
|
getContainer: () => divRef.current,
|
|
getImg: () => imgRef.current,
|
|
onStateChange: () => setRenderToken((n) => n + 1)
|
|
}));
|
|
useDestroy(handle, () => handle.connect());
|
|
const thumbnails = useMemo(() => {
|
|
if (externalThumbnails && externalThumbnails.length > 0) return externalThumbnails;
|
|
return textTrack && textTrack.thumbnailCues.length > 0 ? mapCuesToThumbnails(textTrack.thumbnailCues, textTrack.thumbnailTrackSrc ?? void 0) : [];
|
|
}, [externalThumbnails, textTrack]);
|
|
const thumbnail = useMemo(() => core.findActiveThumbnail(thumbnails, time), [
|
|
core,
|
|
thumbnails,
|
|
time
|
|
]);
|
|
handle.updateSrc(thumbnail?.url);
|
|
const state = core.getState(handle.loading, handle.error, thumbnail);
|
|
let containerStyle = { overflow: "hidden" };
|
|
let imgStyle;
|
|
if (thumbnail && handle.naturalWidth && handle.naturalHeight) {
|
|
const constraints = handle.readConstraints();
|
|
const result = core.resize(thumbnail, handle.naturalWidth, handle.naturalHeight, constraints);
|
|
if (result) {
|
|
containerStyle = {
|
|
overflow: "hidden",
|
|
width: result.containerWidth,
|
|
height: result.containerHeight
|
|
};
|
|
imgStyle = {
|
|
width: result.imageWidth,
|
|
height: result.imageHeight,
|
|
maxWidth: "none",
|
|
transform: result.offsetX || result.offsetY ? `translate(-${result.offsetX}px, -${result.offsetY}px)` : void 0
|
|
};
|
|
}
|
|
}
|
|
return renderElement("div", {
|
|
render,
|
|
className,
|
|
style
|
|
}, {
|
|
state,
|
|
stateAttrMap: ThumbnailDataAttrs,
|
|
ref: [forwardedRef, divRef],
|
|
props: [
|
|
core.getAttrs(state),
|
|
{ style: containerStyle },
|
|
elementProps,
|
|
{ children: /* @__PURE__ */ jsx("img", {
|
|
ref: imgRef,
|
|
alt: "",
|
|
"aria-hidden": "true",
|
|
decoding: "async",
|
|
src: thumbnail?.url,
|
|
crossOrigin: crossOrigin === "" || crossOrigin === null ? void 0 : crossOrigin,
|
|
loading,
|
|
style: imgStyle,
|
|
fetchPriority
|
|
}) }
|
|
]
|
|
});
|
|
});
|
|
//#endregion
|
|
export { Thumbnail };
|
|
|
|
//# sourceMappingURL=thumbnail.js.map
|