fix: ensure minimum dimensions for timeline items and adjust duration constraints
This commit is contained in:
@@ -79,10 +79,15 @@ export default function Item({
|
||||
[span.start, span.end],
|
||||
);
|
||||
|
||||
// Guarantee a minimum clickable width on the outer wrapper so that
|
||||
// very short items (< 1px) remain visible and interactive.
|
||||
const MIN_ITEM_PX = 16;
|
||||
const safeItemStyle = { ...itemStyle, minWidth: MIN_ITEM_PX };
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={setNodeRef}
|
||||
style={itemStyle}
|
||||
style={safeItemStyle}
|
||||
{...listeners}
|
||||
{...attributes}
|
||||
onPointerDownCapture={() => onSelect?.()}
|
||||
|
||||
@@ -116,16 +116,21 @@ function calculateTimelineScale(durationSeconds: number): TimelineScaleConfig {
|
||||
const intervalMs = Math.round(selectedCandidate.intervalSeconds * 1000);
|
||||
const gridMs = Math.round(selectedCandidate.gridSeconds * 1000);
|
||||
|
||||
// Set minItemDurationMs to 1ms for maximum granularity
|
||||
const minItemDurationMs = 1;
|
||||
// Minimum item duration: at least 500ms or 0.3% of the video, capped at 3s.
|
||||
// Prevents items from being shrunk to invisible sizes.
|
||||
const minItemDurationMs = totalMs > 0
|
||||
? Math.min(Math.max(500, Math.round(totalMs * 0.003)), 3000)
|
||||
: 500;
|
||||
const defaultItemDurationMs = Math.min(
|
||||
Math.max(minItemDurationMs, intervalMs * 2),
|
||||
totalMs > 0 ? totalMs : intervalMs * 2,
|
||||
);
|
||||
|
||||
// Minimum visible range: at least 2s or 0.5% of the video, capped at 15s.
|
||||
// Decoupled from intervalMs so long videos can still zoom in deeply.
|
||||
const minVisibleRangeMs = totalMs > 0
|
||||
? Math.min(Math.max(intervalMs * 3, minItemDurationMs * 6, 1000), totalMs)
|
||||
: Math.max(intervalMs * 3, minItemDurationMs * 6, 1000);
|
||||
? Math.max(2000, Math.min(Math.round(totalMs * 0.005), 15000))
|
||||
: 2000;
|
||||
|
||||
return {
|
||||
intervalMs,
|
||||
|
||||
@@ -135,7 +135,10 @@ export default function TimelineWrapper({
|
||||
const activeItemId = event.active.id as string;
|
||||
let clampedSpan = clampSpanToBounds(updatedSpan);
|
||||
|
||||
if (clampedSpan.end - clampedSpan.start < Math.min(minItemDurationMs, totalMs || minItemDurationMs)) {
|
||||
const effectiveMinDuration = totalMs > 0
|
||||
? Math.min(minItemDurationMs, totalMs)
|
||||
: minItemDurationMs;
|
||||
if (clampedSpan.end - clampedSpan.start < effectiveMinDuration) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user