Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Preview: tl.set holds never render when the root timeline has zero duration

Open
#4,519 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
76/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
html, typescript
Domain
tooling, web-dev

Research direction

Start in packages/core/src/runtime/init.ts and compare the createDurationFloorTimeline path with ensureChildCandidatesActive. Reproduce the supplied static tl.set example or a Studio resize, then verify that preview renders #box at 200×150 at any playhead position while snapshot behavior remains correct.

Written by the indexing model from the issue text.

Description

Describe the bug

A root timeline whose own duration is 0 — e.g. one that only holds tl.set(...) at position 0, which is exactly what Studio writes for a static resize — never renders its sets in the preview. After resizing an element in Studio the file is correct, but the element snaps back to its authored size in the preview (keeping the drag offset), so it looks like the resize was lost.

Cause: in packages/core/src/runtime/init.ts, an unusable (zero) root duration takes the createDurationFloorTimeline fallback: the root timeline is added to a new paused wrapper padded to the composition duration. The author's root was created gsap.timeline({ paused: true }) and stays paused, and a paused child is never rendered when its parent is seeked. The nested-composition path already unpauses held children (ensureChildCandidatesActive); the floor wrapper does not.

Minimal reproduction
<div id="root" data-composition-id="main" data-start="0" data-duration="2" data-width="1920" data-height="1080">
  <div id="box" class="clip" data-start="0" data-duration="2" data-track-index="1"
       style="position:absolute; left:100px; top:100px; width:400px; height:300px; background:tomato"></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/gsap.min.js"></script>
<script>
  window.__timelines = window.__timelines || {};
  const tl = gsap.timeline({ paused: true });
  tl.set("#box", { width: 200, height: 150 }, 0);
  window.__timelines["main"] = tl;
</script>
Steps to reproduce
  1. npx hyperframes preview on the composition above (or produce it by resizing an element in Studio in a composition without tweens).
  2. Look at #box at any playhead position.
Expected behavior

#box renders at 200×150.

Actual behavior

#box stays at 400×300. In the preview iframe, __timelines.main.paused() is true, its children are never initialised, and __player.seek(t) has no effect on it. After __timelines.main.paused(false), __player.seek(0.5) renders 200×150. A single tween in the timeline (non-zero duration) avoids the fallback and the bug. hyperframes snapshot --at 0.5 of the same file renders 200×150 correctly, so only the preview runtime is affected.

Environment

hyperframes CLI 0.8.77 (also on main @ 0985b45), GSAP 3.12.5 and 3.15.0, macOS, Chrome (headed and headless).

Additional context

Fix PR to follow: unpause the root timeline once the floor wrapper actually holds it, mirroring ensureChildCandidatesActive.

Dominant language
TypeScript
Stars
54.1k
Forks
4.9k
Avg merge
10h 29m
Merged PRs (30d)
756

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from heygen-com/hyperframes

All issues in heygen-com/hyperframes

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.