Skip to content

Player not driving registered window.__timelines["main"] in src=URL mode (v0.5.3) #672

@TanujaBalthazar98

Description

@TanujaBalthazar98

Repro

Server-side compose a minimal HTML5 composition file matching the canonical blank template, served from a public URL with Access-Control-Allow-Origin: *. Composition source:

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=1280, height=720" />
  <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    html, body { margin: 0; width: 1280px; height: 720px; overflow: hidden; background: #0f172a; }
    #root { width: 100%; height: 100%; position: relative; display: flex; align-items: center; justify-content: center; }
    #title { font-family: -apple-system, sans-serif; font-size: 128px; font-weight: 700; color: #fff; }
  </style>
</head>
<body>
  <div id=\"root\" data-composition-id=\"main\" data-start=\"0\" data-duration=\"5\" data-width=\"1280\" data-height=\"720\">
    <div id=\"title\" class=\"clip\" data-start=\"0\" data-duration=\"5\" data-track-index=\"0\">It works</div>
  </div>
  <script>
    window.__timelines = window.__timelines || {};
    const tl = gsap.timeline({ paused: true });
    tl.from('#title', { opacity: 0, y: 30, duration: 0.8, ease: 'power2.out' }, 0)
      .to('#title', { opacity: 0, y: -20, duration: 0.6, ease: 'power2.in' }, 4.4);
    window.__timelines['main'] = tl;
  </script>
</body>
</html>

Embed in a parent page (same-origin) via:

<script type=\"module\" src=\"https://unpkg.com/@hyperframes/player@0.5.3\"></script>
<hyperframes-player src=\"/compositions/2\" shader-loading=\"none\" controls></hyperframes-player>

Expected

Clicking play (or setting player.currentTime = 2) should advance the registered GSAP timeline so that window.__timelines['main'].time() follows playback and the visible state of #title animates.

Actual

The player loads, parses metadata correctly:

  • duration is reported as 5 (visible in the controls UI as 0:00 / 0:05)
  • customElements.get('hyperframes-player') is defined
  • iframe is same-origin (verified — the parent can read iframe.contentDocument, __timelines.main, gsap, #title)

But:

  • Calling player.play() flips paused=false but currentTime doesn't advance.
  • Setting player.currentTime = 2 updates the player's reported value, but window.__timelines['main'].time() stays at 0.
  • The composition iframe's window has none of the Hyperframes runtime markers (no __hf* keys, no postMessage handlers I could detect).
  • Manually calling tl.time(2) from the parent works correctly — at t=2 the #title element transitions to opacity 1, transform identity. So the timeline itself is healthy.

It looks like the player isn't injecting (or isn't running) its seek runtime in the iframe in src=URL mode, so even though the parent ↔ iframe relationship is same-origin, the seek bridge never fires.

Environment

  • @hyperframes/player 0.5.3 from unpkg
  • Chrome (latest)
  • Composition served from same origin as the embedding page (CORS open just in case)
  • No CSP on either side
  • iframe is sandboxed by the player; same-origin access still works for inspection

Notes / hypothesis

Looking at the player's prototype methods I see both _prepareSrc and _prepareSrcdoc plus _injectRuntime and _promoteToParentProxy. My guess is _injectRuntime runs only on the srcdoc path or after a specific iframe load signal that isn't firing for src-mode same-origin loads. Happy to test a patch or grab more diagnostic output if useful.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions