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:
1 parent
b57994c754
commit
b9f2ba9e47
9 files changed
+436
-15
No files matched your search
@@ -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
@@ -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
|
||||
|
||||
Reference in new issue
Block a user