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:
@@ -41,6 +41,10 @@ describe("layers panel input", () => {
|
||||
});
|
||||
});
|
||||
|
||||
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({
|
||||
|
||||
@@ -41,6 +41,7 @@ export function resolveLayerDrop(options: {
|
||||
const targetInfo = findLayerInfoInDocument(options.document, options.target.layer.id);
|
||||
const sourceInfo = findLayerInfoInDocument(options.document, options.sourceLayerId);
|
||||
if (!targetInfo || !sourceInfo || options.sourceLayerId === options.target.layer.id) return undefined;
|
||||
if (isDescendantLayer(sourceInfo.layer, options.target.layer.id)) return undefined;
|
||||
|
||||
const verticalRatio = Math.max(0, Math.min(1, options.verticalRatio));
|
||||
const dropIntoGroup = options.target.layer.type === "group" && verticalRatio >= 0.33 && verticalRatio <= 0.66;
|
||||
@@ -97,3 +98,11 @@ function findLayerInfo(layers: Layer[], layerId: LayerId, artboardId: ArtboardId
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isDescendantLayer(layer: Layer, descendantLayerId: LayerId): boolean {
|
||||
if (layer.type !== "group") return false;
|
||||
for (const child of layer.children) {
|
||||
if (child.id === descendantLayerId || isDescendantLayer(child, descendantLayerId)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { commandIds } from "@commands/ids";
|
||||
import type { Dispatch } from "@commands/dispatcher";
|
||||
import type { ImageDocument } from "@core/document";
|
||||
import type { Layer } from "@core/layer";
|
||||
import { getLayerMask } from "@core/layer-mask-utils";
|
||||
import { resolveTransformTargetBounds, viewportPointToDocumentPoint, type InputViewportState } from "./document-geometry";
|
||||
import type { PointerInputEvent } from "./pointer";
|
||||
|
||||
@@ -65,9 +66,9 @@ function findTopmostLayerInTreeAtPoint(document: ImageDocument, layers: Layer[],
|
||||
|
||||
function collectMaskLayerIds(layers: readonly Layer[], ids = new Set<string>()): Set<string> {
|
||||
for (const layer of layers) {
|
||||
if (layer.clippingMask) ids.add(layer.clippingMask.maskLayerId);
|
||||
const layerMask = getLayerMask(layer);
|
||||
if (layerMask) ids.add(layerMask.maskLayerId);
|
||||
if (layer.type === "group") collectMaskLayerIds(layer.children, ids);
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user