- Introduced `getLayerMask` utility to streamline layer mask retrieval. - Updated layer rendering logic to incorporate layer masks and opacity adjustments. - Added functionality to prevent dropping a group into its descendants. - Enhanced image texture rendering to support opacity parameters across various rendering functions. - Implemented group layer bounds application for better scaling and positioning. - Added tests to ensure correct behavior when handling layer masks and group layers. - Created new types for asset generation provenance to track generated assets more effectively.
94 lines
3.1 KiB
TypeScript
94 lines
3.1 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
import { commandIds } from "@commands/ids";
|
|
import type { ImageDocument } from "@core/document";
|
|
import type { Layer } from "@core/layer";
|
|
import { handleDeleteSelectionKey, resolveLayerDrop } from "./layers-panel";
|
|
|
|
const document: ImageDocument = {
|
|
id: "doc",
|
|
name: "Doc",
|
|
version: 1,
|
|
assets: [],
|
|
artboards: [
|
|
{
|
|
id: "a1",
|
|
name: "Artboard",
|
|
bounds: { x: 0, y: 0, w: 100, h: 100 },
|
|
backgroundColor: "transparent",
|
|
visible: true,
|
|
locked: false,
|
|
layers: [group("a"), group("b"), { ...group("g"), children: [group("c")] }],
|
|
},
|
|
],
|
|
};
|
|
|
|
describe("layers panel input", () => {
|
|
test("resolves dropping a layer before another layer", () => {
|
|
expect(resolveLayerDrop({ document, sourceLayerId: "b", target: { artboardId: "a1", layer: group("a") }, verticalRatio: 0.1 })).toEqual({
|
|
layerId: "b",
|
|
toArtboardId: "a1",
|
|
toParentGroupId: undefined,
|
|
toIndex: 0,
|
|
});
|
|
});
|
|
|
|
test("resolves dropping a layer into a group", () => {
|
|
expect(resolveLayerDrop({ document, sourceLayerId: "a", target: { artboardId: "a1", layer: { ...group("g"), children: [group("c")] } }, verticalRatio: 0.5 })).toEqual({
|
|
layerId: "a",
|
|
toArtboardId: "a1",
|
|
toParentGroupId: "g",
|
|
toIndex: 1,
|
|
});
|
|
});
|
|
|
|
test("does not resolve dropping a group into one of its descendants", () => {
|
|
expect(resolveLayerDrop({ document, sourceLayerId: "g", target: { artboardId: "a1", layer: group("c") }, verticalRatio: 0.5 })).toBeUndefined();
|
|
});
|
|
|
|
test("dispatches delete commands for selected layers", () => {
|
|
const dispatched: unknown[] = [];
|
|
const consumed = handleDeleteSelectionKey({
|
|
event: { key: "Backspace", code: "Backspace", altKey: false, ctrlKey: false, metaKey: false, shiftKey: false },
|
|
selection: { artboardId: "a1", layerIds: ["a", "b"] },
|
|
dispatch: (commandId, payload) => {
|
|
dispatched.push({ commandId, payload });
|
|
return undefined as never;
|
|
},
|
|
});
|
|
|
|
expect(consumed).toBe(true);
|
|
expect(dispatched).toEqual([
|
|
{ commandId: commandIds.documentRemoveLayer, payload: { layerId: "a" } },
|
|
{ commandId: commandIds.documentRemoveLayer, payload: { layerId: "b" } },
|
|
]);
|
|
});
|
|
|
|
test("dispatches delete command for selected artboard when no layers are selected", () => {
|
|
const dispatched: unknown[] = [];
|
|
const consumed = handleDeleteSelectionKey({
|
|
event: { key: "Delete", code: "Delete", altKey: false, ctrlKey: false, metaKey: false, shiftKey: false },
|
|
selection: { artboardId: "a1", layerIds: [] },
|
|
dispatch: (commandId, payload) => {
|
|
dispatched.push({ commandId, payload });
|
|
return undefined as never;
|
|
},
|
|
});
|
|
|
|
expect(consumed).toBe(true);
|
|
expect(dispatched).toEqual([{ commandId: commandIds.documentRemoveArtboard, payload: { id: "a1" } }]);
|
|
});
|
|
});
|
|
|
|
function group(id: string): Extract<Layer, { type: "group" }> {
|
|
return {
|
|
id,
|
|
type: "group",
|
|
name: id,
|
|
visible: true,
|
|
locked: false,
|
|
opacity: 1,
|
|
transform: { position: { x: 0, y: 0 }, scale: { x: 1, y: 1 }, rotation: 0 },
|
|
children: [],
|
|
};
|
|
}
|