Add output camera framing
This commit is contained in:
1 parent
616ced17ce
commit
23a66c6fdf
19 files changed
+1955
-43
No files matched your search
@@ -71,6 +71,39 @@ function validateRenderRequest(scene, options = {}, limits = DEFAULT_LIMITS) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (scene.camera != null) {
|
||||
const camera = scene.camera
|
||||
if (typeof camera !== 'object') return { ok: false, error: 'camera must be an object' }
|
||||
if (camera.enabled) {
|
||||
const cw = Number(camera.base?.width)
|
||||
const ch = Number(camera.base?.height)
|
||||
if (!Number.isFinite(cw) || cw <= 0 || !Number.isFinite(ch) || ch <= 0) {
|
||||
return { ok: false, error: 'enabled camera must have positive width and height' }
|
||||
}
|
||||
}
|
||||
if (camera.keyframes != null) {
|
||||
if (!Array.isArray(camera.keyframes)) {
|
||||
return { ok: false, error: 'camera keyframes must be an array' }
|
||||
}
|
||||
keyframes += camera.keyframes.length
|
||||
if (keyframes > limits.maxKeyframes) {
|
||||
return { ok: false, error: `scene has more than ${limits.maxKeyframes} keyframes` }
|
||||
}
|
||||
for (const kf of camera.keyframes) {
|
||||
if (!Number.isFinite(Number(kf?.time))) {
|
||||
return { ok: false, error: 'keyframe times must be finite numbers' }
|
||||
}
|
||||
const w = kf?.props?.width
|
||||
const h = kf?.props?.height
|
||||
if (w != null && (!Number.isFinite(Number(w)) || Number(w) <= 0)) {
|
||||
return { ok: false, error: 'camera keyframe width must be positive' }
|
||||
}
|
||||
if (h != null && (!Number.isFinite(Number(h)) || Number(h) <= 0)) {
|
||||
return { ok: false, error: 'camera keyframe height must be positive' }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const duration = Number(scene.duration)
|
||||
if (!Number.isFinite(duration) || duration <= 0 || duration > limits.maxDuration) {
|
||||
return { ok: false, error: `duration must be between 0 and ${limits.maxDuration} seconds` }
|
||||
|
||||
@@ -56,6 +56,37 @@ test('rejects invalid crf and preset', () => {
|
||||
assert.equal(validateRenderRequest(scene(), { preset: 'turbo' }).ok, false)
|
||||
})
|
||||
|
||||
test('validates enabled camera data', () => {
|
||||
const valid = validateRenderRequest(scene({
|
||||
camera: {
|
||||
enabled: true,
|
||||
base: { x: 0, y: 0, width: 320, height: 180 },
|
||||
keyframes: [{ time: 0.5, props: { x: 10 }, easing: 'linear' }],
|
||||
},
|
||||
}))
|
||||
assert.equal(valid.ok, true)
|
||||
|
||||
const invalidSize = validateRenderRequest(scene({
|
||||
camera: {
|
||||
enabled: true,
|
||||
base: { x: 0, y: 0, width: 0, height: 180 },
|
||||
keyframes: [],
|
||||
},
|
||||
}))
|
||||
assert.equal(invalidSize.ok, false)
|
||||
assert.match(invalidSize.error, /camera/)
|
||||
|
||||
const invalidKf = validateRenderRequest(scene({
|
||||
camera: {
|
||||
enabled: true,
|
||||
base: { x: 0, y: 0, width: 320, height: 180 },
|
||||
keyframes: [{ time: Number.NaN, props: {}, easing: 'linear' }],
|
||||
},
|
||||
}))
|
||||
assert.equal(invalidKf.ok, false)
|
||||
assert.match(invalidKf.error, /keyframe/)
|
||||
})
|
||||
|
||||
test('computes playback range from in/out or last keyframe', () => {
|
||||
assert.deepEqual(playbackRange(scene({ inTime: 0.25, outTime: 1.5 })), { start: 0.25, end: 1.5 })
|
||||
assert.deepEqual(playbackRange(scene()), { start: 0, end: 1 })
|
||||
|
||||
Reference in new issue
Block a user