feat(studio): lanes and ruler span the full timeline width at any zoom

When the composition is narrower than the panel (zoomed out) the track
lanes, ruler bar, and context header now fill the whole timeline instead
of stopping at the content width and leaving a flat dark void. Content
stays in composition coordinates, so ticks, clips, and the playhead are
unaffected.
This commit is contained in:
Miguel Angel Simon Sierra
2026-07-08 23:46:29 -04:00
parent ffd513130b
commit eb31e86d4f
3 changed files with 15 additions and 4 deletions
@@ -204,7 +204,12 @@ export const TimelineCanvas = memo(function TimelineCanvas({
draggedClip?.started === true ? (draggedClip.previewStackingReorder?.placement ?? null) : null;
return (
<div className="relative" style={{ height: totalH, width: GUTTER + trackContentWidth }}>
// minWidth:100% makes the lanes and ruler fill the panel when the composition
// is narrower than the viewport (zoomed out); content stays in time coords.
<div
className="relative"
style={{ height: totalH, width: GUTTER + trackContentWidth, minWidth: "100%" }}
>
<TimelineRuler
major={major}
minor={minor}
@@ -46,7 +46,11 @@ export function TimelineLayerGroupHeader({
className="relative"
style={{
height: TIMELINE_LAYER_GROUP_HEADER_H,
width: GUTTER + trackContentWidth,
// Fill the full canvas width (min 100% of the panel) so the context
// header spans the timeline at any zoom; minWidth preserves the intrinsic
// composition width when zoomed in and scrolling.
width: "100%",
minWidth: GUTTER + trackContentWidth,
background: theme.gutterBackground,
borderBottom: `1px solid ${theme.rowBorder}`,
}}
@@ -79,13 +79,15 @@ export const TimelineRuler = memo(function TimelineRuler({
})}
</svg>
{/* Ruler */}
{/* Ruler. The bar fills the full panel width (canvas is min 100% wide);
calc(100% - GUTTER) equals trackContentWidth when zoomed in and extends
past the content when zoomed out. Ticks stay at composition coordinates. */}
<div
className="relative overflow-hidden"
style={{
height: RULER_H,
marginLeft: GUTTER,
width: trackContentWidth,
width: `calc(100% - ${GUTTER}px)`,
background: theme.gutterBackground,
borderBottom: `1px solid ${theme.rulerBorder}`,
}}