This commit is contained in:
th committed 2026-04-19 21:13:53 +02:00
1 parent cc6b11e61d
commit b977ee35a8
11 files changed
+1641 -310

No files matched your search

+59 -19
View File
@@ -1,4 +1,4 @@
import type { Asset, Scene } from '@/types/scene'
import type { Asset, Layer, Scene } from '@/types/scene'
import { sampleLayer } from './interpolate'
export async function loadSceneImages(scene: Scene): Promise<Record<string, HTMLImageElement>> {
@@ -24,27 +24,15 @@ export async function loadSceneImages(scene: Scene): Promise<Record<string, HTML
return result
}
export function drawSceneFrame(
function drawLayers(
ctx: CanvasRenderingContext2D,
scene: Scene,
time: number,
layers: Layer[],
assetMap: Map<string, Asset>,
images: Record<string, HTMLImageElement>,
time: number,
) {
const lw = scene.canvas.width
const lh = scene.canvas.height
ctx.save()
ctx.beginPath()
ctx.rect(0, 0, lw, lh)
ctx.clip()
ctx.fillStyle = scene.canvas.background
ctx.fillRect(0, 0, lw, lh)
const assetMap = new Map<string, Asset>()
for (const a of scene.assets) assetMap.set(a.id, a)
for (let i = scene.layers.length - 1; i >= 0; i--) {
const layer = scene.layers[i]
for (let i = layers.length - 1; i >= 0; i--) {
const layer = layers[i]
if (!layer.visible) continue
const asset = assetMap.get(layer.assetId)
if (!asset) continue
@@ -86,6 +74,58 @@ export function drawSceneFrame(
ctx.restore()
}
}
export function drawSceneFrame(
ctx: CanvasRenderingContext2D,
scene: Scene,
time: number,
images: Record<string, HTMLImageElement>,
) {
const lw = scene.canvas.width
const lh = scene.canvas.height
ctx.save()
ctx.beginPath()
ctx.rect(0, 0, lw, lh)
ctx.clip()
ctx.fillStyle = scene.canvas.background
ctx.fillRect(0, 0, lw, lh)
const assetMap = new Map<string, Asset>()
for (const a of scene.assets) assetMap.set(a.id, a)
const layerById = new Map<string, Layer>()
for (const l of scene.layers) layerById.set(l.id, l)
const instancesByTrack = new Map<string, typeof scene.clipInstances>()
for (const ci of scene.clipInstances ?? []) {
const arr = instancesByTrack.get(ci.clipTrackId) ?? []
arr.push(ci)
instancesByTrack.set(ci.clipTrackId, arr)
}
const clipById = new Map<string, NonNullable<typeof scene.clips>[number]>()
for (const c of scene.clips ?? []) clipById.set(c.id, c)
const order = scene.trackOrder ?? scene.layers.map((l) => l.id)
for (let i = order.length - 1; i >= 0; i--) {
const id = order[i]
const layer = layerById.get(id)
if (layer) {
drawLayers(ctx, [layer], assetMap, images, time)
continue
}
const instances = instancesByTrack.get(id) ?? []
for (const inst of instances) {
const clip = clipById.get(inst.clipId)
if (!clip) continue
const trimStart = inst.trimStart ?? 0
const trimEnd = inst.trimEnd ?? 0
const visible = Math.max(0, clip.duration - trimStart - trimEnd)
const offsetIntoBlock = time - inst.startTime
if (offsetIntoBlock < 0 || offsetIntoBlock > visible) continue
drawLayers(ctx, clip.layers, assetMap, images, trimStart + offsetIntoBlock)
}
}
ctx.restore()
}