Skip to content

fix(runtime): respect hidden ancestor clips in Studio preview (#1387)#1395

Merged
miguel-heygen merged 2 commits into
heygen-com:mainfrom
manupareekk:fix/studio-clip-stacking-1387
Jun 13, 2026
Merged

fix(runtime): respect hidden ancestor clips in Studio preview (#1387)#1395
miguel-heygen merged 2 commits into
heygen-com:mainfrom
manupareekk:fix/studio-clip-stacking-1387

Conversation

@manupareekk

Copy link
Copy Markdown
Contributor

Summary

Fixes #1387 — Studio preview showed all caption/telop content stacked simultaneously when GSAP tweens target children of timed clips (the standard caption pattern).

Two changes in packages/core/src/runtime/init.ts:

  • Skip Studio timing stamps on GSAP targets / [id] elements that live inside an authored timed clip ancestor (prevents full-duration pseudo-clips)
  • Respect hidden ancestor clips when applying inline visibility — descendants no longer get visibility: visible when a parent timed clip is hidden

Test plan

@manupareekk manupareekk force-pushed the fix/studio-clip-stacking-1387 branch 3 times, most recently from dd4498b to c927be5 Compare June 12, 2026 23:27
…-com#1387)

Studio-stamped GSAP tween targets inside timed clips were getting
visibility:visible for the full composition, overriding hidden parent
panels. Skip stamping descendants of authored clips and suppress
visibility on children when an ancestor timed clip is hidden.

Co-authored-by: Cursor <cursoragent@cursor.com>
@manupareekk manupareekk force-pushed the fix/studio-clip-stacking-1387 branch from c927be5 to 23da438 Compare June 12, 2026 23:29

@miguel-heygen miguel-heygen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strengths

  • findTimedClipAncestor (init.ts:400–411) correctly identifies the stamping root cause: Studio was iterating GSAP tween targets and stamping any element lacking data-start with a full-composition-duration pseudo-clip, regardless of position in the authored hierarchy. The guard at init.ts:1070 and init.ts:1090 eliminates that injection entirely for tween targets inside authored timed clips.
  • Extracting the old inline visibility-window logic into isTimedElementVisibleAt is a clean refactor with zero behavior risk — it's a direct extraction and re-use.
  • Three regression tests cover the exact failure modes: per-caption stacking (#1387), no-stamp-in-Studio, and the niemmo multi-panel beat pattern. Fixtures are minimal and readable.

Important

Fix 2 (ancestor visibility walk) changes render-mode behavior, not just Studio preview. The seek handler that now walks ancestor data-start elements runs in both Studio and render contexts. If any existing composition intentionally has a child element with a longer time window than its parent timed clip — e.g. a headline that bleeds out slightly past the parent panel's official data-duration — it would now be suppressed when the parent goes hidden. The new tests only cover the caption/panel-stack pattern. Were any existing compositions checked for this pattern before landing?

This isn't a blocker given the bug's severity, but the behavioral scope is wider than the PR description implies.

Nit

findTimedClipAncestor is called with rootComp potentially null (resolveRootCompositionElement() can return null). When null, the guard if (node === rootComp) break becomes if (node === null) break, which the while (node) loop already handles — so it's safe, but a comment acknowledging the null case would reduce reader confusion.


Verdict: APPROVE
Reasoning: Fix 1 eliminates the root cause (spurious Studio stamps on tween targets inside authored clips); Fix 2 enforces correct hierarchical visibility semantics as defense-in-depth. Together they're complete. The important note above is worth the author confirming, but it doesn't gate merge.

— Magi

Address review feedback: the hierarchical visibility guard now runs only
when window.parent !== window, matching the Studio-only stamping fix.
Render mode keeps prior per-element visibility semantics. Adds a render-mode
regression test and documents the null rootComp case in findTimedClipAncestor.

Co-authored-by: Cursor <cursoragent@cursor.com>
@manupareekk

Copy link
Copy Markdown
Contributor Author

Good catch on render scope — pushed a follow-up that gates the ancestor visibility walk to window.parent !== window, matching the stamping fix. Render mode keeps legacy per-element semantics; added a regression test for a child with a longer authored window than its parent. Also added the null rootComp comment. Fix 1 alone eliminates the root cause; Fix 2 is now Studio-only defense-in-depth.

@miguel-heygen miguel-heygen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow-up on the new commit (a3cecdb).

My "important" flag is fully resolved. The ancestor visibility walk is now gated by window.parent !== window (init.ts:1505) — it only fires in the Studio iframe, leaving render mode's per-element visibility semantics untouched. The new render-mode regression test confirms exactly the case I was asking about: a child with a wider data-duration than its parent is not suppressed in render mode.

Null-rootComp comment added — nit cleared.

withStudioIframe helper is a nice cleanup over the inline Object.defineProperty pattern in the original tests.

Approval stands.

— Magi

Copy link
Copy Markdown
Collaborator

Merge activity

  • Jun 12, 11:57 PM UTC: Graphite couldn't merge this PR because it failed for an unknown reason (Fast-forward merges are not supported for forked repositories. Please create a branch in the target repository in order to merge).

@miguel-heygen miguel-heygen merged commit 7fa3696 into heygen-com:main Jun 13, 2026
46 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Studio preview: descendants of hidden timed clips become visible when they are GSAP tween targets (clips "stack" on top of each other)

2 participants