fix: lift filmstrip preview above frame

This commit is contained in:
2026-05-19 17:33:37 +08:00
parent 1f6eabc819
commit d461c65472
4 changed files with 19 additions and 13 deletions

View File

@@ -29,6 +29,7 @@ type MediaAssetTileProps = {
objectFit?: "contain" | "cover"
previewObjectFit?: "contain" | "cover"
previewClassName?: string
previewSize?: "normal" | "large"
selected?: boolean
disabled?: boolean
busy?: boolean
@@ -55,10 +56,10 @@ function mediaObjectClass(fit: "contain" | "cover") {
return fit === "cover" ? "object-cover" : "object-contain"
}
function previewPosition(event: ReactMouseEvent<HTMLElement>) {
function previewPosition(event: ReactMouseEvent<HTMLElement>, size: "normal" | "large" = "normal") {
const margin = 16
const previewWidth = Math.min(520, window.innerWidth - margin * 2)
const previewHeight = Math.min(760, window.innerHeight - margin * 2)
const previewWidth = Math.min(size === "large" ? 720 : 520, window.innerWidth - margin * 2)
const previewHeight = Math.min(size === "large" ? 880 : 760, window.innerHeight - margin * 2)
let left = event.clientX + 18
let top = event.clientY + 18
if (left + previewWidth > window.innerWidth - margin) left = event.clientX - previewWidth - 18
@@ -81,6 +82,7 @@ export function MediaAssetTile({
objectFit = "contain",
previewObjectFit,
previewClassName = "",
previewSize = "normal",
selected = false,
disabled = false,
busy = false,
@@ -101,10 +103,13 @@ export function MediaAssetTile({
const canPreview = !!mediaSrc && !disablePreview
const fit = mediaObjectClass(objectFit)
const previewFit = mediaObjectClass(previewObjectFit ?? objectFit)
const previewWidthClass = previewSize === "large" ? "w-[min(720px,calc(100vw-32px))]" : "w-[min(520px,calc(100vw-32px))]"
const previewMaxHeightClass = previewSize === "large" ? "max-h-[min(84vh,860px)]" : "max-h-[min(76vh,720px)]"
const previewMediaHeightClass = previewSize === "large" ? "max-h-[min(82vh,840px)]" : "max-h-[min(74vh,700px)]"
const updatePreview = (event: ReactMouseEvent<HTMLElement>) => {
if (!canPreview) return
setPosition(previewPosition(event))
setPosition(previewPosition(event, previewSize))
}
const media = kind === "video" && src ? (
@@ -135,10 +140,10 @@ export function MediaAssetTile({
const preview = position && canPreview && typeof document !== "undefined"
? createPortal(
<div
className={`pointer-events-none fixed z-[10000] w-[min(520px,calc(100vw-32px))] rounded-xl border border-white/15 bg-black/94 p-3 shadow-[0_28px_80px_rgba(0,0,0,0.72)] ${previewClassName}`}
className={`pointer-events-none fixed z-[12000] ${previewWidthClass} rounded-xl border border-white/15 bg-black/94 p-3 shadow-[0_28px_80px_rgba(0,0,0,0.72)] ${previewClassName}`}
style={{ left: position.left, top: position.top }}
>
<div className="flex max-h-[min(76vh,720px)] items-center justify-center overflow-hidden rounded-lg bg-black">
<div className={`flex ${previewMaxHeightClass} items-center justify-center overflow-hidden rounded-lg bg-black`}>
{kind === "video" && src ? (
<video
src={src}
@@ -148,13 +153,13 @@ export function MediaAssetTile({
playsInline
autoPlay
preload="auto"
className={`max-h-[min(74vh,700px)] max-w-full ${previewFit}`}
className={`${previewMediaHeightClass} max-w-full ${previewFit}`}
/>
) : (
<img
src={mediaSrc}
alt=""
className={`max-h-[min(74vh,700px)] max-w-full ${previewFit}`}
className={`${previewMediaHeightClass} max-w-full ${previewFit}`}
/>
)}
</div>