feat(commands): add image asset layer commands
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { describe, expect, test } from "bun:test";
|
import { describe, expect, test } from "bun:test";
|
||||||
import { createInitialAppState } from "@editor/initial-state";
|
import { createInitialAppState } from "@editor/initial-state";
|
||||||
import { documentAddArtboardCommand, documentSetArtboardBoundsCommand } from "./document";
|
import { documentAddArtboardCommand, documentAddAssetCommand, documentAddImageLayerCommand, documentSetArtboardBoundsCommand } from "./document";
|
||||||
|
|
||||||
describe("document commands", () => {
|
describe("document commands", () => {
|
||||||
test("adds transparent artboard", () => {
|
test("adds transparent artboard", () => {
|
||||||
@@ -20,6 +20,43 @@ describe("document commands", () => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("adds assets", () => {
|
||||||
|
const next = documentAddAssetCommand.execute(
|
||||||
|
{ state: createInitialAppState("Test") },
|
||||||
|
{ asset: { id: "asset-1", name: "Image", mimeType: "image/png", source: "blob:test", intrinsicSize: { w: 100, h: 50 } } },
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(next.document.assets).toEqual([
|
||||||
|
{ id: "asset-1", name: "Image", mimeType: "image/png", source: "blob:test", intrinsicSize: { w: 100, h: 50 } },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("adds image layers to artboards", () => {
|
||||||
|
const state = documentAddArtboardCommand.execute(
|
||||||
|
{ state: createInitialAppState("Test") },
|
||||||
|
{ id: "a1", name: "Artboard 1", bounds: { x: 0, y: 0, w: 320, h: 240 } },
|
||||||
|
);
|
||||||
|
|
||||||
|
const next = documentAddImageLayerCommand.execute(
|
||||||
|
{ state },
|
||||||
|
{
|
||||||
|
artboardId: "a1",
|
||||||
|
layer: {
|
||||||
|
id: "l1",
|
||||||
|
type: "image",
|
||||||
|
name: "Image",
|
||||||
|
visible: true,
|
||||||
|
locked: false,
|
||||||
|
opacity: 1,
|
||||||
|
assetId: "asset-1",
|
||||||
|
transform: { position: { x: 10, y: 20 }, scale: { x: 1, y: 1 }, rotation: 0 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(next.document.artboards[0]?.layers.map((layer) => layer.id)).toEqual(["l1"]);
|
||||||
|
});
|
||||||
|
|
||||||
test("sets artboard bounds", () => {
|
test("sets artboard bounds", () => {
|
||||||
const state = documentAddArtboardCommand.execute(
|
const state = documentAddArtboardCommand.execute(
|
||||||
{ state: createInitialAppState("Test") },
|
{ state: createInitialAppState("Test") },
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import type { Asset } from "@core/asset";
|
||||||
|
import type { ImageLayer } from "@core/image-layer";
|
||||||
import type { Rect } from "@core/geometry";
|
import type { Rect } from "@core/geometry";
|
||||||
import type { ArtboardId } from "@core/id";
|
import type { ArtboardId } from "@core/id";
|
||||||
import type { Command } from "./command";
|
import type { Command } from "./command";
|
||||||
@@ -14,6 +16,15 @@ export type DocumentSetArtboardBoundsPayload = {
|
|||||||
bounds: Rect;
|
bounds: Rect;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type DocumentAddAssetPayload = {
|
||||||
|
asset: Asset;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type DocumentAddImageLayerPayload = {
|
||||||
|
artboardId: ArtboardId;
|
||||||
|
layer: ImageLayer;
|
||||||
|
};
|
||||||
|
|
||||||
export const documentAddArtboardCommand: Command<DocumentAddArtboardPayload> = {
|
export const documentAddArtboardCommand: Command<DocumentAddArtboardPayload> = {
|
||||||
id: commandIds.documentAddArtboard,
|
id: commandIds.documentAddArtboard,
|
||||||
name: "Add artboard",
|
name: "Add artboard",
|
||||||
@@ -53,4 +64,41 @@ export const documentSetArtboardBoundsCommand: Command<DocumentSetArtboardBounds
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const documentCommands = [documentAddArtboardCommand, documentSetArtboardBoundsCommand] satisfies Command<unknown>[];
|
export const documentAddAssetCommand: Command<DocumentAddAssetPayload> = {
|
||||||
|
id: commandIds.documentAddAsset,
|
||||||
|
name: "Add asset",
|
||||||
|
execute({ state }, payload) {
|
||||||
|
if (state.document.assets.some((asset) => asset.id === payload.asset.id)) return state;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
document: {
|
||||||
|
...state.document,
|
||||||
|
assets: [...state.document.assets, payload.asset],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const documentAddImageLayerCommand: Command<DocumentAddImageLayerPayload> = {
|
||||||
|
id: commandIds.documentAddImageLayer,
|
||||||
|
name: "Add image layer",
|
||||||
|
execute({ state }, payload) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
document: {
|
||||||
|
...state.document,
|
||||||
|
artboards: state.document.artboards.map((artboard) =>
|
||||||
|
artboard.id === payload.artboardId ? { ...artboard, layers: [...artboard.layers, payload.layer] } : artboard,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const documentCommands = [
|
||||||
|
documentAddArtboardCommand,
|
||||||
|
documentSetArtboardBoundsCommand,
|
||||||
|
documentAddAssetCommand,
|
||||||
|
documentAddImageLayerCommand,
|
||||||
|
] satisfies Command<unknown>[];
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
export const commandIds = {
|
export const commandIds = {
|
||||||
documentAddArtboard: "document.addArtboard",
|
documentAddArtboard: "document.addArtboard",
|
||||||
documentSetArtboardBounds: "document.setArtboardBounds",
|
documentSetArtboardBounds: "document.setArtboardBounds",
|
||||||
|
documentAddAsset: "document.addAsset",
|
||||||
|
documentAddImageLayer: "document.addImageLayer",
|
||||||
selectionSet: "selection.set",
|
selectionSet: "selection.set",
|
||||||
selectionClear: "selection.clear",
|
selectionClear: "selection.clear",
|
||||||
selectionAddLayer: "selection.addLayer",
|
selectionAddLayer: "selection.addLayer",
|
||||||
|
|||||||
@@ -1,6 +1,17 @@
|
|||||||
export type { Command, CommandContext } from "./command";
|
export type { Command, CommandContext } from "./command";
|
||||||
export { documentAddArtboardCommand, documentCommands } from "./document";
|
export {
|
||||||
export type { DocumentAddArtboardPayload } from "./document";
|
documentAddArtboardCommand,
|
||||||
|
documentAddAssetCommand,
|
||||||
|
documentAddImageLayerCommand,
|
||||||
|
documentCommands,
|
||||||
|
documentSetArtboardBoundsCommand,
|
||||||
|
} from "./document";
|
||||||
|
export type {
|
||||||
|
DocumentAddArtboardPayload,
|
||||||
|
DocumentAddAssetPayload,
|
||||||
|
DocumentAddImageLayerPayload,
|
||||||
|
DocumentSetArtboardBoundsPayload,
|
||||||
|
} from "./document";
|
||||||
export type { CommandDispatcher, Dispatch } from "./dispatcher";
|
export type { CommandDispatcher, Dispatch } from "./dispatcher";
|
||||||
export type { CommandId, CommandPayloads } from "./payloads";
|
export type { CommandId, CommandPayloads } from "./payloads";
|
||||||
export { createCommandDispatcher } from "./dispatcher";
|
export { createCommandDispatcher } from "./dispatcher";
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
import { commandIds } from "./ids";
|
import { commandIds } from "./ids";
|
||||||
import type { DocumentAddArtboardPayload, DocumentSetArtboardBoundsPayload } from "./document";
|
import type {
|
||||||
|
DocumentAddArtboardPayload,
|
||||||
|
DocumentAddAssetPayload,
|
||||||
|
DocumentAddImageLayerPayload,
|
||||||
|
DocumentSetArtboardBoundsPayload,
|
||||||
|
} from "./document";
|
||||||
import type { SelectionAddLayerPayload, SelectionSetPayload } from "./selection";
|
import type { SelectionAddLayerPayload, SelectionSetPayload } from "./selection";
|
||||||
import type { ToolSetActivePayload } from "./tool";
|
import type { ToolSetActivePayload } from "./tool";
|
||||||
import type { TransformBeginPayload, TransformUpdatePayload } from "./transform";
|
import type { TransformBeginPayload, TransformUpdatePayload } from "./transform";
|
||||||
@@ -14,6 +19,8 @@ import type {
|
|||||||
export type CommandPayloads = {
|
export type CommandPayloads = {
|
||||||
[commandIds.documentAddArtboard]: DocumentAddArtboardPayload;
|
[commandIds.documentAddArtboard]: DocumentAddArtboardPayload;
|
||||||
[commandIds.documentSetArtboardBounds]: DocumentSetArtboardBoundsPayload;
|
[commandIds.documentSetArtboardBounds]: DocumentSetArtboardBoundsPayload;
|
||||||
|
[commandIds.documentAddAsset]: DocumentAddAssetPayload;
|
||||||
|
[commandIds.documentAddImageLayer]: DocumentAddImageLayerPayload;
|
||||||
[commandIds.selectionSet]: SelectionSetPayload;
|
[commandIds.selectionSet]: SelectionSetPayload;
|
||||||
[commandIds.selectionClear]: void;
|
[commandIds.selectionClear]: void;
|
||||||
[commandIds.selectionAddLayer]: SelectionAddLayerPayload;
|
[commandIds.selectionAddLayer]: SelectionAddLayerPayload;
|
||||||
|
|||||||
Reference in New Issue
Block a user