feat: add feather brush tool with adjustable settings and blending functionality
- Implemented feather brush tool in the brushRaster module, allowing for feathered edges in brush strokes. - Added new FeatherControls component for UI adjustments of feather settings including size, radius, strength, and smoothing. - Updated brush preview logic to accommodate feather tool alongside existing brush and eraser tools. - Enhanced layer rendering to support feather mask previews and interactions. - Introduced blending logic for feathered strokes to mix blurred mask values with original pixels. - Added unit tests for feather blending functionality and tool keybindings. - Updated cursor handling to reflect feather tool usage.
This commit is contained in:
@@ -120,10 +120,19 @@ function renderLeafLayer(
|
||||
}
|
||||
const layerMask = getLayerMask(layer);
|
||||
const maskLayer = !editingMaskLayer && layerMask?.enabled ? documentIndex.layerById.get(layerMask.maskLayerId) : undefined;
|
||||
const maskAsset = assetWithBrushStrokePreview(maskLayer && (maskLayer.type === "image" || maskLayer.type === "raster") ? documentIndex.assetById.get(maskLayer.assetId) : undefined, editor);
|
||||
const pendingMaskPreview = editor.brushStrokePreview?.pendingTargetLayerId === layer.id && editor.brushStrokePreview.intrinsicSize
|
||||
? {
|
||||
id: editor.brushStrokePreview.assetId,
|
||||
name: `${layer.name} Mask Preview`,
|
||||
mimeType: "image/png",
|
||||
source: editor.brushStrokePreview.source,
|
||||
intrinsicSize: editor.brushStrokePreview.intrinsicSize,
|
||||
}
|
||||
: undefined;
|
||||
const maskAsset = assetWithBrushStrokePreview(maskLayer && (maskLayer.type === "image" || maskLayer.type === "raster") ? documentIndex.assetById.get(maskLayer.assetId) : undefined, editor) ?? pendingMaskPreview;
|
||||
const maskBounds = maskLayer ? resolveIndexedLayerBounds(documentIndex, maskLayer) : undefined;
|
||||
const maskRect = maskBounds ? documentRectToScreenRect(context.canvas, maskBounds, editor.viewport) : undefined;
|
||||
const activeMaskTarget = Boolean(editor.maskEdit?.targetLayerId === layer.id && editor.maskEdit.maskLayerId === layerMask?.maskLayerId);
|
||||
const maskRect = maskBounds ? documentRectToScreenRect(context.canvas, maskBounds, editor.viewport) : pendingMaskPreview ? rect : undefined;
|
||||
const activeMaskTarget = Boolean((editor.maskEdit?.targetLayerId === layer.id && editor.maskEdit.maskLayerId === layerMask?.maskLayerId) || pendingMaskPreview);
|
||||
const showMaskRevealPreview = editor.tools.activeTool === "brush" && activeMaskTarget && maskViewMode === "composite";
|
||||
|
||||
if (asset && maskAsset && maskRect && activeMaskTarget) {
|
||||
|
||||
Reference in New Issue
Block a user