0.9.1: jumpToScene action + auto-play on scene switch

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
thandClaude Opus 4.7 committed 2026-04-22 07:44:43 +02:00
1 parent b57994c754
commit b9f2ba9e47
9 files changed
+436 -15

No files matched your search

+20
View File
@@ -7,9 +7,17 @@ export interface ActionRuntime {
playbackOut: number
duration: number
markers: Record<string, number>
/** Set of valid scene ids the runtime knows about. Used so jumpToScene
* can warn on stale references (e.g., the target scene was deleted)
* instead of silently failing. */
sceneIds?: Set<string>
setPlayhead(t: number): void
play(): void
pause(): void
/** Switch the active scene page. Implementations should preserve the
* current playback state so a script-fired jump doesn't surprise-pause
* the timeline. */
switchScene?(sceneId: string): void
warn(msg: string): void
}
@@ -49,6 +57,18 @@ export function evalAction(action: Action, rt: ActionRuntime): void {
rt.setPlayhead(clamp(t, 0, rt.duration))
return
}
case 'jumpToScene': {
if (!rt.switchScene) {
rt.warn('jumpToScene: runtime does not support scene switching')
return
}
if (rt.sceneIds && !rt.sceneIds.has(action.sceneId)) {
rt.warn(`jumpToScene: unknown scene id "${action.sceneId}"`)
return
}
rt.switchScene(action.sceneId)
return
}
case 'script': {
const parsed = parseScript(action.source)
if (parsed.errors.length) {
+18 -1
View File
@@ -1,6 +1,6 @@
import type { Scene } from '@/types/scene'
const RUNTIME_VERSION = '17'
const RUNTIME_VERSION = '19'
const ENGINE_SOURCE = `(function(){
if (window.AnimatrPlayer && window.AnimatrPlayer.__v === '${RUNTIME_VERSION}') return;
@@ -350,6 +350,15 @@ const ENGINE_SOURCE = `(function(){
runtime.jumpTo=Math.max(0,Math.min(runtime.duration,mt));
return;
}
case 'jumpToScene': {
// Exports only carry one scene at a time, so jumpToScene is a
// warn-and-continue in standalone bundles. The in-editor
// fullscreen preview passes an onJumpToScene hook which routes
// the jump back to the store and re-mounts at the same time.
if (onJumpToScene){ try { onJumpToScene(act.sceneId); } catch(e){ runtime.warn('jumpToScene: '+((e&&e.message)||String(e))); } return; }
runtime.warn('jumpToScene: exported runtime does not support multi-scene playback');
return;
}
case 'script': {
var parsed=parseScriptSource(act.source);
if(parsed.errors.length){
@@ -381,6 +390,7 @@ const ENGINE_SOURCE = `(function(){
var lastNow=0;
var rafId=0;
var onFrame=opts.onFrame||null;
var onJumpToScene=opts.onJumpToScene||null;
var destroyed=false;
function frame(now){
if(destroyed) return;
@@ -866,6 +876,13 @@ export interface PlayerHandle {
export interface MountOptions {
loop?: boolean
onFrame?: (time: number, paused: boolean) => void
/** In-editor hook used by the fullscreen preview: a scripted (or
* button-click) `jumpToScene` calls this instead of the runtime's
* own warn-and-skip path. The host is responsible for swapping the
* Scene the player renders (typically by mutating the store and
* re-mounting with the new active page). Exported bundles omit this
* — they carry a single scene and warn on jumpToScene. */
onJumpToScene?: (sceneId: string) => void
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any