diff --git a/src/setup/index.css b/src/setup/index.css index c17b8258..259aaa61 100644 --- a/src/setup/index.css +++ b/src/setup/index.css @@ -34,6 +34,10 @@ body[data-no-select] { animation: roll 1s; } +.roll-infinite { + animation: roll 2s infinite; +} + @keyframes roll { from { transform: rotate(0deg); diff --git a/src/utils/thumbnailCreator.ts b/src/utils/thumbnailCreator.ts index e67e1b4a..7f9a2556 100644 --- a/src/utils/thumbnailCreator.ts +++ b/src/utils/thumbnailCreator.ts @@ -3,11 +3,14 @@ export interface Thumbnail { to: number; imgUrl: string; } -export const SCALE_FACTOR = 0.1; +export const SCALE_FACTOR = 1; export default async function* extractThumbnails( videoUrl: string, numThumbnails: number ): AsyncGenerator { + const canvas = document.createElement("canvas"); + const ctx = canvas.getContext("2d"); + if (!ctx) return { from: -1, to: -1, imgUrl: "" }; const video = document.createElement("video"); video.src = videoUrl; video.crossOrigin = "anonymous"; @@ -18,12 +21,8 @@ export default async function* extractThumbnails( video.addEventListener("error", reject); }); - const canvas = document.createElement("canvas"); - canvas.height = video.videoHeight * SCALE_FACTOR; canvas.width = video.videoWidth * SCALE_FACTOR; - const ctx = canvas.getContext("2d"); - if (!ctx) return { from: 0, to: 0, imgUrl: "" }; for (let i = 0; i <= numThumbnails; i += 1) { const from = (i / (numThumbnails + 1)) * video.duration; @@ -48,5 +47,5 @@ export default async function* extractThumbnails( }; } - return { from: 0, to: 0, imgUrl: "" }; + return { from: -1, to: -1, imgUrl: "" }; } diff --git a/src/video/components/actions/ProgressAction.tsx b/src/video/components/actions/ProgressAction.tsx index 789ad1d3..17e081e6 100644 --- a/src/video/components/actions/ProgressAction.tsx +++ b/src/video/components/actions/ProgressAction.tsx @@ -70,9 +70,11 @@ export function ProgressAction() { ); return ( -
+
- {isThumbnailVisible ? ( - - ) : null}
+ {isThumbnailVisible ? ( + + ) : null} ); } diff --git a/src/video/components/actions/ThumbnailAction.tsx b/src/video/components/actions/ThumbnailAction.tsx index 9cc1c3ba..53734d26 100644 --- a/src/video/components/actions/ThumbnailAction.tsx +++ b/src/video/components/actions/ThumbnailAction.tsx @@ -1,11 +1,13 @@ import { RefObject } from "react"; +import { Icon, Icons } from "@/components/Icon"; import { formatSeconds } from "@/utils/formatSeconds"; import { SCALE_FACTOR } from "@/utils/thumbnailCreator"; import { useVideoPlayerDescriptor } from "@/video/state/hooks"; import { VideoProgressEvent } from "@/video/state/logic/progress"; import { useSource } from "@/video/state/logic/source"; +const THUMBNAIL_HEIGHT = 100; export default function ThumbnailAction({ parentRef, hoverPosition, @@ -18,44 +20,61 @@ export default function ThumbnailAction({ const descriptor = useVideoPlayerDescriptor(); const source = useSource(descriptor); if (!parentRef.current) return null; - const offset = - (document.getElementsByTagName("video")[0].videoWidth * SCALE_FACTOR) / 2; + const videoEl = document.getElementsByTagName("video")[0]; + const aspectRatio = videoEl.videoWidth / videoEl.videoHeight; const rect = parentRef.current.getBoundingClientRect(); - + if (!rect.width) return null; const hoverPercent = (hoverPosition - rect.left) / rect.width; const hoverTime = videoTime.duration * hoverPercent; + const thumbnailWidth = THUMBNAIL_HEIGHT * aspectRatio; const pos = () => { const relativePosition = hoverPosition - rect.left; - if (relativePosition <= offset) { - return 0; + if (relativePosition <= thumbnailWidth / 2) { + return rect.left; } - if (relativePosition >= rect.width - offset) { - return rect.width - offset * 2; + if (relativePosition >= rect.width - thumbnailWidth / 2) { + return rect.width + rect.left - thumbnailWidth; } - return relativePosition - offset; + return relativePosition + rect.left - thumbnailWidth / 2; }; - + const src = source.source?.thumbnails.find( + (x) => x.from < hoverTime && x.to > hoverTime + )?.imgUrl; return ( -
- x.from < hoverTime && x.to > hoverTime - )?.imgUrl - } - /> +
+ {!src ? ( +
+ +
+ ) : ( + + )}
- {formatSeconds(hoverTime)} + {formatSeconds(hoverTime, videoEl.duration > 60 * 60)}
);