feat: add named canvas presets with YouTube Shorts entry
Introduces NAMED_CANVAS_PRESETS with id/label/aspectRatio/projectType metadata so the UI can show meaningful preset names (e.g. "YouTube Shorts (1080×1920)") and so downstream code can resolve a preset by intent rather than dimensions. - NAMED_CANVAS_PRESETS: landscape 16:9, YouTube Shorts 9:16, square, landscape 4:3 - SHORTS_CANVAS_PRESET convenience export for 9:16 vertical - DEFAULT_CANVAS_PRESETS preserved (derived from NAMED) so existing editor-store consumers keep working - Unit tests verify shape, ordering, and back-compat derivation
This commit is contained in:
parent
7131f88bf4
commit
4254dec19f
|
|
@ -0,0 +1,58 @@
|
|||
import { describe, expect, test } from "bun:test";
|
||||
import {
|
||||
DEFAULT_CANVAS_PRESETS,
|
||||
DEFAULT_CANVAS_SIZE,
|
||||
NAMED_CANVAS_PRESETS,
|
||||
SHORTS_CANVAS_PRESET,
|
||||
} from "@/canvas/sizes";
|
||||
|
||||
describe("NAMED_CANVAS_PRESETS", () => {
|
||||
test("has the four canonical presets in declared order", () => {
|
||||
const ids = NAMED_CANVAS_PRESETS.map((p) => p.id);
|
||||
expect(ids).toEqual([
|
||||
"landscape-1080p",
|
||||
"shorts-1080x1920",
|
||||
"square-1080",
|
||||
"landscape-1440",
|
||||
]);
|
||||
});
|
||||
|
||||
test("every preset has consistent shape", () => {
|
||||
for (const preset of NAMED_CANVAS_PRESETS) {
|
||||
expect(preset.id.length).toBeGreaterThan(0);
|
||||
expect(preset.label.length).toBeGreaterThan(0);
|
||||
expect(preset.size.width).toBeGreaterThan(0);
|
||||
expect(preset.size.height).toBeGreaterThan(0);
|
||||
expect(preset.aspectRatio).toMatch(/^\d+:\d+$/);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("SHORTS_CANVAS_PRESET", () => {
|
||||
test("is 1080x1920 vertical 9:16", () => {
|
||||
expect(SHORTS_CANVAS_PRESET.size).toEqual({ width: 1080, height: 1920 });
|
||||
expect(SHORTS_CANVAS_PRESET.aspectRatio).toBe("9:16");
|
||||
expect(SHORTS_CANVAS_PRESET.projectType).toBe("shorts");
|
||||
});
|
||||
});
|
||||
|
||||
describe("DEFAULT_CANVAS_PRESETS (back-compat)", () => {
|
||||
test("derives from NAMED_CANVAS_PRESETS in order", () => {
|
||||
expect(DEFAULT_CANVAS_PRESETS).toEqual(
|
||||
NAMED_CANVAS_PRESETS.map((p) => p.size),
|
||||
);
|
||||
});
|
||||
|
||||
test("contains the Shorts preset 1080x1920", () => {
|
||||
expect(DEFAULT_CANVAS_PRESETS).toContainEqual({
|
||||
width: 1080,
|
||||
height: 1920,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("DEFAULT_CANVAS_SIZE", () => {
|
||||
test("remains 1920x1080 (landscape default)", () => {
|
||||
expect(DEFAULT_CANVAS_SIZE).toEqual({ width: 1920, height: 1080 });
|
||||
});
|
||||
});
|
||||
|
|
@ -1,10 +1,63 @@
|
|||
import type { TCanvasSize } from "@/project/types";
|
||||
import type { TCanvasSize, TProjectType } from "@/project/types";
|
||||
|
||||
export const DEFAULT_CANVAS_PRESETS: TCanvasSize[] = [
|
||||
{ width: 1920, height: 1080 },
|
||||
{ width: 1080, height: 1920 },
|
||||
{ width: 1080, height: 1080 },
|
||||
{ width: 1440, height: 1080 },
|
||||
/**
|
||||
* A canvas preset bundles the raw size with display metadata (label,
|
||||
* aspect ratio) and the project intent it implies. UIs should prefer
|
||||
* NAMED_CANVAS_PRESETS when rendering preset pickers; consumers that
|
||||
* only need the size array continue to use DEFAULT_CANVAS_PRESETS.
|
||||
*/
|
||||
export interface TCanvasPreset {
|
||||
id: string;
|
||||
label: string;
|
||||
size: TCanvasSize;
|
||||
aspectRatio: string;
|
||||
projectType?: TProjectType;
|
||||
}
|
||||
|
||||
export const NAMED_CANVAS_PRESETS: readonly TCanvasPreset[] = [
|
||||
{
|
||||
id: "landscape-1080p",
|
||||
label: "Landscape 1920×1080",
|
||||
size: { width: 1920, height: 1080 },
|
||||
aspectRatio: "16:9",
|
||||
projectType: "standard",
|
||||
},
|
||||
{
|
||||
id: "shorts-1080x1920",
|
||||
label: "YouTube Shorts (1080×1920)",
|
||||
size: { width: 1080, height: 1920 },
|
||||
aspectRatio: "9:16",
|
||||
projectType: "shorts",
|
||||
},
|
||||
{
|
||||
id: "square-1080",
|
||||
label: "Square 1080×1080",
|
||||
size: { width: 1080, height: 1080 },
|
||||
aspectRatio: "1:1",
|
||||
projectType: "standard",
|
||||
},
|
||||
{
|
||||
id: "landscape-1440",
|
||||
label: "Landscape 1440×1080",
|
||||
size: { width: 1440, height: 1080 },
|
||||
aspectRatio: "4:3",
|
||||
projectType: "standard",
|
||||
},
|
||||
];
|
||||
|
||||
export const DEFAULT_CANVAS_SIZE: TCanvasSize = { width: 1920, height: 1080 };
|
||||
/**
|
||||
* Convenience reference to the YouTube Shorts preset.
|
||||
*/
|
||||
export const SHORTS_CANVAS_PRESET: TCanvasPreset = NAMED_CANVAS_PRESETS.find(
|
||||
(p) => p.id === "shorts-1080x1920",
|
||||
)!;
|
||||
|
||||
/**
|
||||
* Back-compat: existing consumers (editor-store, etc.) read a bare
|
||||
* TCanvasSize[]. Derived from NAMED_CANVAS_PRESETS to keep them in sync.
|
||||
*/
|
||||
export const DEFAULT_CANVAS_PRESETS: TCanvasSize[] = NAMED_CANVAS_PRESETS.map(
|
||||
(p) => p.size,
|
||||
);
|
||||
|
||||
export const DEFAULT_CANVAS_SIZE: TCanvasSize = NAMED_CANVAS_PRESETS[0].size;
|
||||
|
|
|
|||
Loading…
Reference in New Issue