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:
56
core/asset-provenance.ts
Normal file
56
core/asset-provenance.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import type { Rect, Size } from "./geometry";
|
||||
import type { AssetId, LayerId } from "./id";
|
||||
|
||||
export type GeneratedAssetMode = "text-to-image" | "image-to-image" | "inpaint" | "outpaint";
|
||||
|
||||
export type GeneratedAssetAcceptance = "layer" | "variant-layer" | "replacement";
|
||||
|
||||
export type AssetGenerationProvenance = {
|
||||
kind: "generated";
|
||||
candidateId: string;
|
||||
mode: GeneratedAssetMode;
|
||||
acceptance: GeneratedAssetAcceptance;
|
||||
prompt: string;
|
||||
negativePrompt: string;
|
||||
seed: number;
|
||||
outputSize: Size;
|
||||
settings: {
|
||||
architecture: string;
|
||||
model: string;
|
||||
textEncoder: string;
|
||||
vae: string;
|
||||
strength: number;
|
||||
steps: number;
|
||||
cfg: number;
|
||||
sampler: string;
|
||||
scheduler: string;
|
||||
width: number;
|
||||
height: number;
|
||||
};
|
||||
inpaint?: {
|
||||
targetLayerId: LayerId;
|
||||
maskLayerId: LayerId;
|
||||
sourceAssetId: AssetId;
|
||||
maskAssetId: AssetId;
|
||||
crop: {
|
||||
assetBounds: Rect;
|
||||
documentBounds: Rect;
|
||||
padding: number;
|
||||
maskedAreaOnly: boolean;
|
||||
};
|
||||
mask: {
|
||||
polarity: "hidden" | "revealed";
|
||||
activeBounds: Rect;
|
||||
};
|
||||
backend: {
|
||||
growMaskBy: number;
|
||||
maskedContent: string;
|
||||
maskBlur: number;
|
||||
maskFeather: number;
|
||||
maskExpand: number;
|
||||
cropPadding: number;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
export type AssetProvenance = AssetGenerationProvenance;
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { Size } from "./geometry";
|
||||
import type { AssetId } from "./id";
|
||||
import type { AssetProvenance } from "./asset-provenance";
|
||||
|
||||
export type Asset = {
|
||||
id: AssetId;
|
||||
@@ -7,4 +8,5 @@ export type Asset = {
|
||||
mimeType: string;
|
||||
source: string;
|
||||
intrinsicSize: Size;
|
||||
provenance?: AssetProvenance;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { Transform } from "./geometry";
|
||||
import type { LayerId } from "./id";
|
||||
import type { LayerMask } from "./layer-mask";
|
||||
|
||||
export type LayerClippingMask = {
|
||||
maskLayerId: LayerId;
|
||||
@@ -12,5 +13,7 @@ export type BaseLayer = {
|
||||
locked: boolean;
|
||||
opacity: number;
|
||||
transform: Transform;
|
||||
layerMask?: LayerMask;
|
||||
/** @deprecated Use layerMask. Kept readable for older documents. */
|
||||
clippingMask?: LayerClippingMask;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
export type { Artboard } from "./artboard";
|
||||
export type { Asset } from "./asset";
|
||||
export type { AssetGenerationProvenance, AssetProvenance, GeneratedAssetAcceptance, GeneratedAssetMode } from "./asset-provenance";
|
||||
export type { BaseLayer, LayerClippingMask } from "./base-layer";
|
||||
export type { ImageDocument } from "./document";
|
||||
export type {
|
||||
@@ -15,5 +16,7 @@ export type {
|
||||
export type { ArtboardId, AssetId, DocumentId, LayerId } from "./id";
|
||||
export type { ImageLayer } from "./image-layer";
|
||||
export type { Layer } from "./layer";
|
||||
export type { LayerMask } from "./layer-mask";
|
||||
export { getLayerMask, hasLayerMask } from "./layer-mask-utils";
|
||||
export type { LayerGroup } from "./layer-group";
|
||||
export type { RasterLayer } from "./raster-layer";
|
||||
|
||||
18
core/layer-mask-utils.ts
Normal file
18
core/layer-mask-utils.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import type { Layer } from "./layer";
|
||||
import type { LayerMask } from "./layer-mask";
|
||||
|
||||
export function getLayerMask(layer: Layer | undefined): LayerMask | undefined {
|
||||
if (layer.layerMask) return layer.layerMask;
|
||||
if (!layer.clippingMask) return undefined;
|
||||
|
||||
return {
|
||||
kind: "raster",
|
||||
maskLayerId: layer.clippingMask.maskLayerId,
|
||||
enabled: true,
|
||||
inverted: false,
|
||||
};
|
||||
}
|
||||
|
||||
export function hasLayerMask(layer: Layer): boolean {
|
||||
return Boolean(getLayerMask(layer));
|
||||
}
|
||||
8
core/layer-mask.ts
Normal file
8
core/layer-mask.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import type { LayerId } from "./id";
|
||||
|
||||
export type LayerMask = {
|
||||
kind: "raster";
|
||||
maskLayerId: LayerId;
|
||||
enabled: boolean;
|
||||
inverted: boolean;
|
||||
};
|
||||
Reference in New Issue
Block a user