feat: add non-destructive adjustment layers
This commit is contained in:
@@ -31,7 +31,7 @@ export function TransformControls({ bounds, target, documentIndex, layerInfo, di
|
||||
const layer = layerInfo?.layer;
|
||||
const locked = layer?.locked ?? false;
|
||||
const mask = layer ? getLayerMask(layer) : undefined;
|
||||
const rotatedMaskEditingUnsupported = Boolean(layer && layer.type !== "group" && layer.transform.rotation !== 0);
|
||||
const rotatedMaskEditingUnsupported = Boolean(layer && layer.type !== "group" && layer.type !== "adjustment" && layer.transform.rotation !== 0);
|
||||
|
||||
useEffect(() => {
|
||||
setDraft(draftFromBounds(bounds));
|
||||
@@ -39,7 +39,7 @@ export function TransformControls({ bounds, target, documentIndex, layerInfo, di
|
||||
|
||||
useEffect(() => setOpacityDraft(String(Math.round((layer?.opacity ?? 1) * 100))), [layer?.id, layer?.opacity]);
|
||||
useEffect(() => setRotationDraft(rotationDegrees(layerInfo)), [layer?.id, layer?.transform.rotation]);
|
||||
useEffect(() => setCropDraft(cropDraftFor(layerInfo, documentIndex)), [documentIndex, layer?.id, layer?.type === "group" ? undefined : layer?.sourceRect]);
|
||||
useEffect(() => setCropDraft(cropDraftFor(layerInfo, documentIndex)), [documentIndex, layer?.id, layer?.type === "image" || layer?.type === "raster" ? layer.sourceRect : undefined]);
|
||||
useEffect(() => setResizeDraft((current) => ({ ...current, w: String(Math.round(bounds.w)), h: String(Math.round(bounds.h)) })), [bounds.w, bounds.h, target]);
|
||||
|
||||
const commitField = (field: BoundsField) => {
|
||||
@@ -89,8 +89,8 @@ export function TransformControls({ bounds, target, documentIndex, layerInfo, di
|
||||
label="Rotation"
|
||||
suffix="°"
|
||||
value={rotationDraft}
|
||||
disabled={locked || layer.type === "group"}
|
||||
title={layer.type === "group" ? "Group rotation is not supported" : undefined}
|
||||
disabled={locked || layer.type === "group" || layer.type === "adjustment"}
|
||||
title={layer.type === "group" || layer.type === "adjustment" ? "Group rotation is not supported" : undefined}
|
||||
onChange={setRotationDraft}
|
||||
onCommit={() => {
|
||||
const value = Number.parseFloat(rotationDraft);
|
||||
@@ -102,12 +102,12 @@ export function TransformControls({ bounds, target, documentIndex, layerInfo, di
|
||||
<button type="button" className={actionButtonClass()} disabled={locked} title={locked ? "Unlock the layer to duplicate it" : "Duplicate layer"} onClick={() => duplicateLayer(documentIndex, layerInfo!, dispatch)}>
|
||||
<Copy size={20} /> Duplicate
|
||||
</button>
|
||||
{layer.type !== "group" ? (
|
||||
{layer.type !== "group" && layer.type !== "adjustment" ? (
|
||||
<button type="button" className={actionButtonClass()} disabled={locked || layer.transform.rotation !== 0} title={layer.transform.rotation !== 0 ? "Reset rotation before cropping" : "Crop visible source pixels"} onClick={() => setCropOpen((open) => !open)}>
|
||||
<Crop size={20} /> Crop
|
||||
</button>
|
||||
) : null}
|
||||
{layer.type !== "group" ? (
|
||||
{layer.type !== "group" && layer.type !== "adjustment" ? (
|
||||
<button
|
||||
type="button"
|
||||
className={actionButtonClass()}
|
||||
@@ -122,7 +122,7 @@ export function TransformControls({ bounds, target, documentIndex, layerInfo, di
|
||||
</button>
|
||||
) : null}
|
||||
{locked ? <span className="text-xs text-amber-200/70">Unlock to edit</span> : null}
|
||||
{cropOpen && layer.type !== "group" ? <CropEditor draft={cropDraft} setDraft={setCropDraft} onCancel={() => { setCropDraft(cropDraftFor(layerInfo, documentIndex)); setCropOpen(false); }} onReset={() => { dispatch(commandIds.documentSetLayerSourceRect, { layerId: layer.id }); setCropOpen(false); }} onApply={() => { const sourceRect = parseRectDraft(cropDraft); if (sourceRect) { dispatch(commandIds.documentSetLayerSourceRect, { layerId: layer.id, sourceRect }); setCropOpen(false); } }} /> : null}
|
||||
{cropOpen && layer.type !== "group" && layer.type !== "adjustment" ? <CropEditor draft={cropDraft} setDraft={setCropDraft} onCancel={() => { setCropDraft(cropDraftFor(layerInfo, documentIndex)); setCropOpen(false); }} onReset={() => { dispatch(commandIds.documentSetLayerSourceRect, { layerId: layer.id }); setCropOpen(false); }} onApply={() => { const sourceRect = parseRectDraft(cropDraft); if (sourceRect) { dispatch(commandIds.documentSetLayerSourceRect, { layerId: layer.id, sourceRect }); setCropOpen(false); } }} /> : null}
|
||||
</>
|
||||
) : target.type === "artboard" ? (
|
||||
<>
|
||||
@@ -154,7 +154,7 @@ function ArtboardResizeEditor({ draft, setDraft, onApply, onCancel }: { draft: {
|
||||
}
|
||||
|
||||
function cropDraftFor(layerInfo: IndexedLayerInfo | undefined, index: DocumentReadIndex): CropDraft {
|
||||
if (!layerInfo || layerInfo.layer.type === "group") return { x: "0", y: "0", w: "1", h: "1" };
|
||||
if (!layerInfo || layerInfo.layer.type === "group" || layerInfo.layer.type === "adjustment") return { x: "0", y: "0", w: "1", h: "1" };
|
||||
const asset = index.assetById.get(layerInfo.layer.assetId);
|
||||
const rect = layerInfo.layer.sourceRect ?? { x: 0, y: 0, w: asset?.intrinsicSize.w ?? 1, h: asset?.intrinsicSize.h ?? 1 };
|
||||
return draftFromBounds(rect);
|
||||
|
||||
Reference in New Issue
Block a user