feat: enhance layer mask handling and opacity management
- 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.
This commit is contained in:
@@ -6,6 +6,7 @@ import {
|
||||
generationApplyCandidateAsLayerCommand,
|
||||
generationRemoveCandidateCommand,
|
||||
generationReplaceCandidatePixelsCommand,
|
||||
generationSetCompareModeCommand,
|
||||
} from "./generation";
|
||||
|
||||
describe("generation commands", () => {
|
||||
@@ -18,8 +19,20 @@ describe("generation commands", () => {
|
||||
|
||||
expect(added.editor.generation.candidates).toEqual([candidate]);
|
||||
expect(added.editor.generation.selectedCandidateId).toBe(candidate.id);
|
||||
expect(added.editor.generation.compareMode).toBe("result");
|
||||
expect(removed.editor.generation.candidates).toEqual([]);
|
||||
expect(removed.editor.generation.selectedCandidateId).toBeUndefined();
|
||||
expect(removed.editor.generation.compareMode).toBe("result");
|
||||
});
|
||||
|
||||
test("sets generation compare mode without touching candidates", () => {
|
||||
const state = generationAddCandidateCommand.execute({ state: createInitialAppState("Test") }, { candidate: generationCandidate("candidate-1") });
|
||||
|
||||
const next = generationSetCompareModeCommand.execute({ state }, { mode: "split" });
|
||||
|
||||
expect(next.editor.generation.candidates).toEqual([generationCandidate("candidate-1")]);
|
||||
expect(next.editor.generation.selectedCandidateId).toBe("candidate-1");
|
||||
expect(next.editor.generation.compareMode).toBe("split");
|
||||
});
|
||||
|
||||
test("applies candidates as top-level layers", () => {
|
||||
@@ -31,9 +44,15 @@ describe("generation commands", () => {
|
||||
);
|
||||
|
||||
expect(next.document.assets.find((asset) => asset.id === "generated-asset")?.source).toBe("generated-source");
|
||||
expect(next.document.assets.find((asset) => asset.id === "generated-asset")?.provenance).toMatchObject({
|
||||
kind: "generated",
|
||||
candidateId: "candidate-1",
|
||||
acceptance: "layer",
|
||||
seed: 123,
|
||||
});
|
||||
expect(next.document.artboards[0]?.layers[0]?.id).toBe("generated-layer");
|
||||
expect(next.editor.selection).toEqual({ artboardId: "a1", layerIds: ["generated-layer"] });
|
||||
expect(next.editor.generation).toEqual({ candidates: [], selectedCandidateId: undefined });
|
||||
expect(next.editor.generation).toEqual({ candidates: [], selectedCandidateId: undefined, compareMode: "result" });
|
||||
});
|
||||
|
||||
test("replaces source asset pixels for inpaint candidates", () => {
|
||||
@@ -46,8 +65,17 @@ describe("generation commands", () => {
|
||||
|
||||
expect(next.document.assets.find((asset) => asset.id === "source-asset")?.source).toBe("composited-source");
|
||||
expect(next.document.assets.find((asset) => asset.id === "source-asset")?.mimeType).toBe("image/png");
|
||||
expect(next.document.assets.find((asset) => asset.id === "source-asset")?.provenance).toMatchObject({
|
||||
kind: "generated",
|
||||
candidateId: "candidate-1",
|
||||
acceptance: "replacement",
|
||||
inpaint: {
|
||||
sourceAssetId: "source-asset",
|
||||
maskAssetId: "mask-asset",
|
||||
},
|
||||
});
|
||||
expect(next.editor.selection).toEqual({ artboardId: "a1", layerIds: ["source-layer"] });
|
||||
expect(next.editor.generation).toEqual({ candidates: [], selectedCandidateId: undefined });
|
||||
expect(next.editor.generation).toEqual({ candidates: [], selectedCandidateId: undefined, compareMode: "result" });
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user