feat(scene): video map editor parity and help updates
Enable scene editor, overlays, effects, and darkness on video scenes; brighten GM trap markers; document snap, NPC types, materials, and control controls in RU/EN help. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
|
||||
import { containMediaRect } from './containMediaRect';
|
||||
|
||||
void test('containMediaRect: letterboxes 16:9 into square host', () => {
|
||||
const r = containMediaRect({
|
||||
hostW: 400,
|
||||
hostH: 400,
|
||||
mediaW: 1920,
|
||||
mediaH: 1080,
|
||||
scale: 1,
|
||||
ox: 0.5,
|
||||
oy: 0.5,
|
||||
});
|
||||
assert.ok(r);
|
||||
assert.ok(Math.abs(r!.w - 400) < 0.01);
|
||||
assert.ok(Math.abs(r!.h - (400 * 1080) / 1920) < 0.01);
|
||||
assert.ok(Math.abs(r!.x - 0) < 0.01);
|
||||
assert.ok(r!.y > 0);
|
||||
});
|
||||
|
||||
void test('containMediaRect: zoom grows rect around ox/oy', () => {
|
||||
const base = containMediaRect({
|
||||
hostW: 800,
|
||||
hostH: 450,
|
||||
mediaW: 800,
|
||||
mediaH: 450,
|
||||
scale: 1,
|
||||
ox: 0.5,
|
||||
oy: 0.5,
|
||||
});
|
||||
const zoomed = containMediaRect({
|
||||
hostW: 800,
|
||||
hostH: 450,
|
||||
mediaW: 800,
|
||||
mediaH: 450,
|
||||
scale: 2,
|
||||
ox: 0.5,
|
||||
oy: 0.5,
|
||||
});
|
||||
assert.ok(base && zoomed);
|
||||
assert.ok(zoomed!.w > base!.w);
|
||||
assert.ok(zoomed!.x < base!.x);
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Pure layout math shared by ContainedVideo / RotatedImage contain-mode.
|
||||
* Kept free of DOM so unit tests can lock overlay alignment for video scenes.
|
||||
*/
|
||||
export function containMediaRect(args: {
|
||||
hostW: number;
|
||||
hostH: number;
|
||||
mediaW: number;
|
||||
mediaH: number;
|
||||
scale: number;
|
||||
ox: number;
|
||||
oy: number;
|
||||
}): { x: number; y: number; w: number; h: number } | null {
|
||||
const { hostW, hostH, mediaW, mediaH, scale, ox, oy } = args;
|
||||
if (hostW <= 1 || hostH <= 1 || mediaW <= 0 || mediaH <= 0) return null;
|
||||
const fit = Math.min(hostW / mediaW, hostH / mediaH);
|
||||
const s = fit * Math.max(1, scale);
|
||||
const w = mediaW * s;
|
||||
const h = mediaH * s;
|
||||
return {
|
||||
x: hostW / 2 - ox * w,
|
||||
y: hostH / 2 - oy * h,
|
||||
w,
|
||||
h,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user