发布

  • fix(player): drive composition ticks from widget-frame rAF via postMessage (#739)

    frostbyte_neo 发布于 2026-05-13 21:01:53 +00:00

    • fix(player): drive composition ticks from widget-frame rAF via postMessage

    Chromium throttles requestAnimationFrame in deeply nested cross-origin
    iframes. In Claude desktop (Electron), the composition iframe's own rAF
    loop stalls, so GSAP is never seeked and animation freezes even when
    TransportClock.isPlaying() is true.

    The correct fix is to drive ticks from the widget-frame rAF, which lives
    one level up and is not subject to the same throttling. When play() takes
    the runtime bridge path (no direct timeline adapter), the player now starts
    a parent-frame rAF loop that sends "tick" postMessages to the composition
    iframe on every frame. The runtime's control bridge handles "tick" by calling
    seekTimelineAndAdapters(clock.now()) if the clock is playing — identical to
    what transportTick does on each rAF, just driven from outside.

    The composition iframe's own rAF loop is unchanged and keeps running
    normally in standard browsers. Seeking GSAP twice per frame is idempotent,
    so there is no regression on claude.ai or any other non-throttled environment.

    Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

    • fix(player): address review issues in parent tick clock
    • _paused must be false before _startParentTickClock runs; otherwise
      the first RAF callback sees _paused=true and self-terminates immediately

    • Guard _startParentTickClock behind this._ready && !this._directTimelineAdapter
      so tick messages aren't sent into an uninitialized iframe when play() is
      called before the composition probe has resolved

    • Add clock.reachedEnd() check to onTick so end-of-composition handling
      (pause, seek-to-end, postState) runs even when the composition iframe
      RAF is fully throttled

    • Stop the parent tick clock in seek() alongside _stopDirectTimelineClock
      to avoid burning CPU frames while paused after a scrub

    • Add onTick to bridge.test.ts createMockDeps() and add a dispatch test

    Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

    • chore: bump versions to 0.6.5-alpha.0 for testing

    Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com


    Co-authored-by: Claude Sonnet 4.6 noreply@anthropic.com

    下载附件