diff options
| author | Maze Winther <mazewinther@gmail.com> | 2025-07-15 17:07:21 +0200 |
|---|---|---|
| committer | Maze Winther <mazewinther@gmail.com> | 2025-07-15 17:07:21 +0200 |
| commit | a32ffb601a99c06536efa0216320a42f34a0fcc4 (patch) | |
| tree | 920eb93c3dc79340f9103c0a8ee9dcd41fc7140c /apps/web/src/components/editor/timeline-element.tsx | |
| parent | dc0e4783fbacad5c7eb3cf0d1141b0166960f809 (diff) | |
| parent | d53321ec366979512d5e5a8cccc56b00cd84c1cf (diff) | |
| download | opencut-a32ffb601a99c06536efa0216320a42f34a0fcc4.tar.gz | |
Merge branch 'feat/thumbnail-appearance' into staging
Diffstat (limited to 'apps/web/src/components/editor/timeline-element.tsx')
| -rw-r--r-- | apps/web/src/components/editor/timeline-element.tsx | 92 |
1 files changed, 75 insertions, 17 deletions
diff --git a/apps/web/src/components/editor/timeline-element.tsx b/apps/web/src/components/editor/timeline-element.tsx index ee9445f3..ca229818 100644 --- a/apps/web/src/components/editor/timeline-element.tsx +++ b/apps/web/src/components/editor/timeline-element.tsx @@ -24,6 +24,7 @@ import { useTimelineElementResize } from "@/hooks/use-timeline-element-resize"; import { getTrackElementClasses, TIMELINE_CONSTANTS, + getTrackHeight, } from "@/constants/timeline-constants"; import { DropdownMenu, @@ -267,35 +268,92 @@ export function TimelineElement({ ); } + const TILE_ASPECT_RATIO = 16 / 9; + if (mediaItem.type === "image") { + // Calculate tile size based on 16:9 aspect ratio + const trackHeight = getTrackHeight(track.type); + const tileHeight = trackHeight - 8; // Account for padding + const tileWidth = tileHeight * TILE_ASPECT_RATIO; + return ( - <div className="w-full h-full flex items-center justify-center"> - <div className="bg-[#004D52] py-3 w-full h-full"> - <img - src={mediaItem.url} - alt={mediaItem.name} - className="w-full h-full object-cover" - draggable={false} + <div className="w-full h-full flex items-center justify-start overflow-hidden"> + <div className="bg-[#004D52]/20 h-full w-full relative"> + {/* Background with tiled images */} + <div + className="absolute inset-0" + style={{ + backgroundImage: mediaItem.url + ? `url(${mediaItem.url})` + : "none", + backgroundRepeat: "repeat-x", + backgroundSize: `${tileWidth}px ${tileHeight}px`, + backgroundPosition: "left center", + }} + /> + {/* Overlay with vertical borders */} + <div + className="absolute inset-0 pointer-events-none" + style={{ + backgroundImage: `repeating-linear-gradient( + to right, + transparent 0px, + transparent ${tileWidth - 1}px, + rgba(255, 255, 255, 0.6) ${tileWidth - 1}px, + rgba(255, 255, 255, 0.6) ${tileWidth}px + )`, + backgroundPosition: "left center", + }} /> </div> </div> ); } + const VIDEO_TILE_PADDING = 16; + const OVERLAY_SPACE_MULTIPLIER = 1.5; + if (mediaItem.type === "video" && mediaItem.thumbnailUrl) { + const trackHeight = getTrackHeight(track.type); + const tileHeight = trackHeight - VIDEO_TILE_PADDING; + const tileWidth = tileHeight * TILE_ASPECT_RATIO; + return ( - <div className="w-full h-full flex items-center gap-2"> - <div className="w-8 h-8 flex-shrink-0"> - <img - src={mediaItem.thumbnailUrl} - alt={mediaItem.name} - className="w-full h-full object-cover rounded-sm" - draggable={false} + <div className="w-full h-full flex items-center overflow-hidden relative"> + <div className="h-full w-full relative"> + {/* Background with tiled thumbnails */} + <div + className="absolute inset-0" + style={{ + backgroundImage: mediaItem.thumbnailUrl + ? `url(${mediaItem.thumbnailUrl})` + : "none", + backgroundRepeat: "repeat-x", + backgroundSize: `${tileWidth}px ${tileHeight}px`, + backgroundPosition: "left center", + }} + /> + {/* Overlay with vertical borders */} + <div + className="absolute inset-0 pointer-events-none" + style={{ + backgroundImage: `repeating-linear-gradient( + to right, + transparent 0px, + transparent ${tileWidth - 1}px, + rgba(255, 255, 255, 0.6) ${tileWidth - 1}px, + rgba(255, 255, 255, 0.6) ${tileWidth}px + )`, + backgroundPosition: "left center", + }} /> </div> - <span className="text-xs text-foreground/80 truncate flex-1"> - {element.name} - </span> + {/* Show name overlay on the right if there's sufficient space */} + {elementWidth > tileWidth * OVERLAY_SPACE_MULTIPLIER && ( + <div className="absolute right-2 top-1/2 -translate-y-1/2 bg-black/70 text-white text-xs px-2 py-1 rounded pointer-events-none max-w-[40%] truncate"> + {element.name} + </div> + )} </div> ); } |
