fix: lift filmstrip preview above frame
This commit is contained in:
@@ -2785,7 +2785,7 @@ function TimelineFilmstrip({
|
||||
onDragStart(frame.time)
|
||||
}}
|
||||
onDragEnd={onDragEnd}
|
||||
className={`relative shrink-0 ${index ? "-ml-2.5" : ""} ${tiltClass} cursor-grab transition-transform duration-150 hover:z-30 hover:rotate-0 hover:scale-[2.15] active:cursor-grabbing`}
|
||||
className={`relative shrink-0 ${index ? "-ml-2.5" : ""} ${tiltClass} cursor-grab transition-transform duration-150 hover:z-30 hover:-translate-y-1.5 hover:rotate-0 active:cursor-grabbing`}
|
||||
title={`${frame.time.toFixed(1)}s · 拖到关键帧库才选取`}
|
||||
>
|
||||
<MediaAssetTile
|
||||
@@ -2799,6 +2799,7 @@ function TimelineFilmstrip({
|
||||
mediaClassName="bg-black"
|
||||
objectFit="contain"
|
||||
previewObjectFit="contain"
|
||||
previewSize="large"
|
||||
selected={selected}
|
||||
onClick={() => onSeek(frame.time)}
|
||||
title="点击跳到该时间点,拖入关键帧库才正式选取"
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user