| 156 | // callback; it can only be reused by installing its source as a real page |
| 157 | // global once, up front). |
| 158 | function seekAllAdaptersInBrowser(tt: number): void { |
| 159 | const tryCall = (fn: () => void): void => { |
| 160 | try { |
| 161 | fn(); |
| 162 | } catch { |
| 163 | /* best-effort */ |
| 164 | } |
| 165 | }; |
| 166 | const w = window as unknown as { |
| 167 | __player?: { renderSeek?: (t: number) => void; seek?: (t: number) => void }; |
| 168 | __hfThreeTime?: number; |
| 169 | __hfThreeRender?: () => void; |
| 170 | __hfAnime?: Array<{ pause?: () => void; seek?: (timeMs: number) => void }>; |
| 171 | gsap?: { ticker?: { tick?: () => void } }; |
| 172 | __timelines?: Record< |
| 173 | string, |
| 174 | { |
| 175 | pause?: () => void; |
| 176 | seek?: (t: number) => void; |
| 177 | totalTime?: (t: number, s: boolean) => void; |
| 178 | } |
| 179 | >; |
| 180 | }; |
| 181 | const timeMs = Math.max(0, tt * 1000); |
| 182 | |
| 183 | tryCall(() => { |
| 184 | if (typeof w.__player?.renderSeek === "function") w.__player.renderSeek(tt); |
| 185 | else if (typeof w.__player?.seek === "function") w.__player.seek(tt); |
| 186 | }); |
| 187 | |
| 188 | Object.values(w.__timelines ?? {}).forEach((tl) => { |
| 189 | tryCall(() => { |
| 190 | tl.pause?.(); |
| 191 | if (typeof tl.totalTime === "function") { |
| 192 | tl.totalTime(tt + 0.001, true); |
| 193 | tl.totalTime(tt, false); |
| 194 | } else { |
| 195 | tl.seek?.(tt); |
| 196 | } |
| 197 | }); |
| 198 | }); |
| 199 | |
| 200 | tryCall(() => { |
| 201 | if (typeof document.getAnimations === "function") { |
| 202 | for (const animation of document.getAnimations()) { |
| 203 | tryCall(() => { |
| 204 | animation.currentTime = timeMs; |
| 205 | }); |
| 206 | tryCall(() => animation.pause()); |
| 207 | } |
| 208 | } |
| 209 | }); |
| 210 | |
| 211 | for (const instance of w.__hfAnime ?? []) { |
| 212 | tryCall(() => { |
| 213 | instance.pause?.(); |
| 214 | instance.seek?.(timeMs); |
| 215 | }); |