0.10.3: preloader + multi-scene export parity, jumpToScene rewinds
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
87de1344c4
commit
fcb8edbb88
6 files changed
+461
-102
No files matched your search
+60
-5
@@ -1018,6 +1018,48 @@ export function registerAllTests(): void {
|
||||
expect(r).toContain('ctx.scale(isx2,isy2)')
|
||||
})
|
||||
|
||||
test('runtime embeds a preloader (spinner + Promise.all) before starting the frame loop', () => {
|
||||
// Loading big images, video metadata and audio `canplaythrough`
|
||||
// must settle before the rAF kicks off — otherwise the first few
|
||||
// frames stutter while the browser decodes. Structural pins:
|
||||
// - A spinner <style> is injected.
|
||||
// - A preloader overlay is appended.
|
||||
// - Image/audio/video promises are awaited together.
|
||||
// - canplaythrough is the event we wait on for audio.
|
||||
const r = generateRuntimeScript()
|
||||
expect(r).toContain('ruwio-spinner-style')
|
||||
expect(r).toContain('ruwio-preloader')
|
||||
expect(r).toContain('Promise.all')
|
||||
expect(r).toContain('canplaythrough')
|
||||
expect(r).toContain('preloadAudioClips')
|
||||
expect(r).toContain('preloadBgVideos')
|
||||
})
|
||||
|
||||
test('runtime honours separated position / rotation keyframes', () => {
|
||||
// Parity regression: the editor samples separated position and
|
||||
// rotation tracks via `sampleLayer()` when `layer.separated`;
|
||||
// the runtime used to only look at the main keyframes array.
|
||||
// Animations set up with Separate-toggled layers played flat
|
||||
// in exports. Pin the helper and the per-branch merge.
|
||||
const r = generateRuntimeScript()
|
||||
expect(r).toContain('sampleKeyframeSet')
|
||||
expect(r).toContain('layer.separated')
|
||||
expect(r).toContain('layer.positionKeyframes')
|
||||
expect(r).toContain('layer.rotationKeyframes')
|
||||
})
|
||||
|
||||
test('runtime supports multi-scene switching (jumpToScene + applySceneSwitch)', () => {
|
||||
// Exported bundles now carry the whole Project and handle
|
||||
// jumpToScene internally. The runtime must expose a scene-
|
||||
// switch helper and NOT fall through to the "unsupported"
|
||||
// warning message anymore.
|
||||
const r = generateRuntimeScript()
|
||||
expect(r).toContain('applySceneSwitch')
|
||||
expect(r).toContain('project.scenes')
|
||||
expect(r).toContain('currentSceneId')
|
||||
expect(r.indexOf('does not support multi-scene')).toBe(-1)
|
||||
})
|
||||
|
||||
test('runtime rangeOut falls back to scene.duration (not last keyframe)', () => {
|
||||
// Regression: the runtime used to fall back to `effectiveEnd(scene)`
|
||||
// — the time of the last keyframe — when scene.outTime was unset.
|
||||
@@ -1356,6 +1398,19 @@ export function registerAllTests(): void {
|
||||
expect(s.project.activeSceneId).toBe(two.id)
|
||||
})
|
||||
|
||||
test('switchScene with resetPlayhead: true rewinds to the in-point', () => {
|
||||
// Script and button jumps should restart the target scene at
|
||||
// its in-point — otherwise chapter-like transitions play from
|
||||
// wherever the previous scene was paused.
|
||||
const s = makeFreshStore()
|
||||
s.setDuration(10)
|
||||
const two = s.addScene('Two')
|
||||
s.setPlayhead(4.5)
|
||||
expect(s.playhead).toBe(4.5)
|
||||
s.switchScene(two.id, { resetPlayhead: true })
|
||||
expect(s.playhead).toBe(0)
|
||||
})
|
||||
|
||||
test('switchScene leaves playback state alone — editor navigation does not force play', () => {
|
||||
// The editor treats scene-switch as a navigation gesture. The
|
||||
// fullscreen preview is the one that auto-plays on switch (via
|
||||
@@ -6381,11 +6436,10 @@ export function registerAllTests(): void {
|
||||
await tick()
|
||||
})
|
||||
|
||||
test('a scripted jumpToScene switches the active scene and keeps playing', async () => {
|
||||
// User-facing contract: a script track fires a scene-switch in the
|
||||
// middle of a running timeline — the active scene flips and the
|
||||
// timeline keeps running on the new page. All pages share
|
||||
// duration/fps, so the playhead stays put and continues onward.
|
||||
test('a scripted jumpToScene switches the scene, keeps playing, and rewinds to the in-point', async () => {
|
||||
// Chapter-transition semantics: the incoming scene starts at
|
||||
// the project's in-point no matter where the outgoing scene was
|
||||
// paused. Keeps playback running across the switch.
|
||||
const s = makeFreshStore()
|
||||
s.setDuration(10)
|
||||
const aId = s.project.activeSceneId
|
||||
@@ -6397,6 +6451,7 @@ export function registerAllTests(): void {
|
||||
s.tick(3)
|
||||
expect(s.project.activeSceneId).toBe(bId)
|
||||
expect(s.playing).toBe(true)
|
||||
expect(s.playhead).toBe(s.playbackIn)
|
||||
await tick()
|
||||
})
|
||||
|
||||
|
||||
Reference in new issue
Block a user