From bc2bc02d9b317cdea5003210be0fbaf32c818ba9 Mon Sep 17 00:00:00 2001 From: funny bot Date: Tue, 7 Jul 2026 20:33:13 -0700 Subject: [PATCH 01/18] Add functioning brush resolution --- engine/src/tools/Brush.js | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/engine/src/tools/Brush.js b/engine/src/tools/Brush.js index 50fe2afeb..36048638b 100644 --- a/engine/src/tools/Brush.js +++ b/engine/src/tools/Brush.js @@ -40,6 +40,13 @@ Wick.Tools.Brush = class extends Wick.Tool { this.MIN_PRESSURE = 0.14; + this.TARGET_BRUSH_SIZE = 50; + this.MAX_RESOLUTION_FACTOR = 2; + this.smoothness = 1; + this.resolutionFactor = 1; + this.canvasScaleFactor = 1; // Resolution: Greater or equal to 1 + this.imageScaleFactor = 1; // Resolution: Lesser or equal to 1 + this.croquis = null; this.croquisDOMElement = null; this.croquisBrush = null; @@ -119,6 +126,11 @@ Wick.Tools.Brush = class extends Wick.Tool { this.croquisDOMElement.style.height = '100%'; this.croquisDOMElement.style.display = 'block'; this.croquisDOMElement.style.pointerEvents = 'none'; + + this.croquisDOMElement.querySelectorAll('canvas').forEach(canvasElement => { + canvasElement.style.width = '100%'; + canvasElement.style.height = '100%'; + }); } this._isInProgress = false; @@ -178,10 +190,13 @@ Wick.Tools.Brush = class extends Wick.Tool { clearTimeout(this._croquisStartTimeout); this._isInProgress = true; + this.resolutionFactor = Math.min(this.TARGET_BRUSH_SIZE/this._getRealBrushSize() * this.smoothness, this.MAX_RESOLUTION_FACTOR); + this.canvasScaleFactor = (this.resolutionFactor > 1) ? this.resolutionFactor : 1; + this.imageScaleFactor = (this.resolutionFactor < 1) ? this.resolutionFactor : 1; this._updateCanvasAttributes(); // Update croquis params - this.croquisBrush.setSize(this._getRealBrushSize()); + this.croquisBrush.setSize(this._getRealBrushSize() * this.canvasScaleFactor); this.croquisBrush.setColor(this.getSetting('fillColor').hex); this.croquisBrush.setSpacing(this.BRUSH_POINT_SPACING); this.croquis.setToolStabilizeLevel(this.BRUSH_STABILIZER_LEVEL); @@ -379,10 +394,12 @@ Wick.Tools.Brush = class extends Wick.Tool { } // Update croquis element canvas size - if(this.croquis.getCanvasWidth() !== this.paper.view._element.width || - this.croquis.getCanvasHeight() !== this.paper.view._element.height) { - this.croquis.setCanvasSize(this.paper.view._element.width, this.paper.view._element.height); + if(this.croquis.getCanvasWidth() !== this.paper.view._element.width * this.canvasScaleFactor || + this.croquis.getCanvasHeight() !== this.paper.view._element.height * this.canvasScaleFactor) { + this.croquis.setCanvasSize(this.paper.view._element.width * this.canvasScaleFactor, this.paper.view._element.height * this.canvasScaleFactor); } + this.croquisDOMElement.style.width = '100%'; + this.croquisDOMElement.style.height = '100%'; // Fake brush opacity in croquis by changing the opacity of the croquis canvas this.croquisDOMElement.style.opacity = this.getSetting('fillColor').a; @@ -391,7 +408,7 @@ Wick.Tools.Brush = class extends Wick.Tool { /* Convert a point in Croquis' canvas space to paper.js's canvas space. */ _croquisToPaperPoint (croquisPoint) { var paperPoint = this.paper.view.projectToView(croquisPoint.x, croquisPoint.y); - return paperPoint; + return paperPoint.multiply(this.canvasScaleFactor); } /* Used for calculating the crop amount for potrace. */ @@ -458,8 +475,8 @@ Wick.Tools.Brush = class extends Wick.Tool { // (and crop out empty space using strokeBounds - this massively speeds up potrace) var croppedCanvas = document.createElement("canvas"); var croppedCanvasCtx = croppedCanvas.getContext("2d"); - croppedCanvas.width = strokeBounds.width; - croppedCanvas.height = strokeBounds.height; + croppedCanvas.width = strokeBounds.width * this.imageScaleFactor; + croppedCanvas.height = strokeBounds.height * this.imageScaleFactor; if(strokeBounds.x < 0) strokeBounds.x = 0; if(strokeBounds.y < 0) strokeBounds.y = 0; croppedCanvasCtx.drawImage( @@ -477,6 +494,7 @@ Wick.Tools.Brush = class extends Wick.Tool { potracePath.position.y += this.paper.view.bounds.y; potracePath.position.x += strokeBounds.x / this.paper.view.zoom; potracePath.position.y += strokeBounds.y / this.paper.view.zoom; + potracePath.scale(1 / this.resolutionFactor, this.paper.view.bounds.topLeft); potracePath.remove(); potracePath.closed = true; potracePath.children[0].closed = true; From 7adf7ff61098001f4c43097d7f016e4f4269d69e Mon Sep 17 00:00:00 2001 From: funny bot Date: Tue, 7 Jul 2026 21:09:30 -0700 Subject: [PATCH 02/18] Add brush smoothness slider to inspector --- src/Editor/Panels/Inspector/Inspector.jsx | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/Editor/Panels/Inspector/Inspector.jsx b/src/Editor/Panels/Inspector/Inspector.jsx index 22ecc5436..7481abe08 100644 --- a/src/Editor/Panels/Inspector/Inspector.jsx +++ b/src/Editor/Panels/Inspector/Inspector.jsx @@ -1045,6 +1045,26 @@ class Inspector extends Component { } render() { + if (this.props.project.selection.numObjects === 0 && this.props.project.activeTool.name === 'brush') { + return ( +
+
+ +
+
+ {this.props.project.tools.brush.smoothness = val; window.editor.projectDidChange(); }} + divider={false} + inputProps={{min: 0.01, max: 1, step: 0.01}} + id="inspector-brush-tool-smoothness"/> +
+
+ ); + } let selectionType = this.props.getSelectionType(); return(
From 5a4d4bc21df3bba12bb5300b5860adbe503defbc Mon Sep 17 00:00:00 2001 From: funny bot Date: Wed, 8 Jul 2026 14:17:43 -0700 Subject: [PATCH 03/18] Fix brush stroke getting cut off and offset from browser zoom --- engine/src/tools/Brush.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/engine/src/tools/Brush.js b/engine/src/tools/Brush.js index 36048638b..27305fb86 100644 --- a/engine/src/tools/Brush.js +++ b/engine/src/tools/Brush.js @@ -394,9 +394,10 @@ Wick.Tools.Brush = class extends Wick.Tool { } // Update croquis element canvas size - if(this.croquis.getCanvasWidth() !== this.paper.view._element.width * this.canvasScaleFactor || - this.croquis.getCanvasHeight() !== this.paper.view._element.height * this.canvasScaleFactor) { - this.croquis.setCanvasSize(this.paper.view._element.width * this.canvasScaleFactor, this.paper.view._element.height * this.canvasScaleFactor); + let width = Math.round(this.paper.view._viewSize.width * this.canvasScaleFactor); + let height = Math.round(this.paper.view._viewSize.height * this.canvasScaleFactor); + if(this.croquis.getCanvasWidth() !== width || this.croquis.getCanvasHeight() !== height) { + this.croquis.setCanvasSize(width, height); } this.croquisDOMElement.style.width = '100%'; this.croquisDOMElement.style.height = '100%'; From 28491c7ae08aafba1619df8c63e634abf6ce29c3 Mon Sep 17 00:00:00 2001 From: funny bot Date: Mon, 13 Jul 2026 14:24:21 -0700 Subject: [PATCH 04/18] Add some test sliders for paper.js tolerance and smoothness factor exponent --- engine/src/tools/Brush.js | 5 ++++- src/Editor/Panels/Inspector/Inspector.jsx | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/engine/src/tools/Brush.js b/engine/src/tools/Brush.js index 27305fb86..275d042a9 100644 --- a/engine/src/tools/Brush.js +++ b/engine/src/tools/Brush.js @@ -46,6 +46,8 @@ Wick.Tools.Brush = class extends Wick.Tool { this.resolutionFactor = 1; this.canvasScaleFactor = 1; // Resolution: Greater or equal to 1 this.imageScaleFactor = 1; // Resolution: Lesser or equal to 1 + this.testPaperTolerance = 0; + this.testSmoothnessExponent = 2; this.croquis = null; this.croquisDOMElement = null; @@ -190,7 +192,7 @@ Wick.Tools.Brush = class extends Wick.Tool { clearTimeout(this._croquisStartTimeout); this._isInProgress = true; - this.resolutionFactor = Math.min(this.TARGET_BRUSH_SIZE/this._getRealBrushSize() * this.smoothness, this.MAX_RESOLUTION_FACTOR); + this.resolutionFactor = Math.min(this.TARGET_BRUSH_SIZE/this._getRealBrushSize() * Math.pow(this.smoothness, this.testSmoothnessExponent), this.MAX_RESOLUTION_FACTOR); this.canvasScaleFactor = (this.resolutionFactor > 1) ? this.resolutionFactor : 1; this.imageScaleFactor = (this.resolutionFactor < 1) ? this.resolutionFactor : 1; this._updateCanvasAttributes(); @@ -501,6 +503,7 @@ Wick.Tools.Brush = class extends Wick.Tool { potracePath.children[0].closed = true; potracePath.children[0].applyMatrix = true; var result = potracePath.children[0]; + if (this.testPaperTolerance > 0) result.simplify(this.testPaperTolerance); // Do special brush mode action var brushMode = this.getSetting('brushMode'); diff --git a/src/Editor/Panels/Inspector/Inspector.jsx b/src/Editor/Panels/Inspector/Inspector.jsx index 7481abe08..3bcbd1dc5 100644 --- a/src/Editor/Panels/Inspector/Inspector.jsx +++ b/src/Editor/Panels/Inspector/Inspector.jsx @@ -1061,6 +1061,20 @@ class Inspector extends Component { divider={false} inputProps={{min: 0.01, max: 1, step: 0.01}} id="inspector-brush-tool-smoothness"/> + {this.props.project.tools.brush.testPaperTolerance = val; window.editor.projectDidChange(); }} + divider={false} + inputProps={{min: 0, max: 10, step: 0.1}} + id="inspector-brush-tool-paper-js-tolerance"/> + {this.props.project.tools.brush.testSmoothnessExponent = val; window.editor.projectDidChange(); }} + divider={false} + inputProps={{min: 1, max: 8, step: 0.1}} + id="inspector-brush-tool-smoothness-exponent"/>
); From f2847ecc4babfe4f29e4fef2648331a2f437bbd1 Mon Sep 17 00:00:00 2001 From: funny bot Date: Mon, 13 Jul 2026 14:55:19 -0700 Subject: [PATCH 05/18] normalized inspector smoothness slider --- engine/src/tools/Brush.js | 2 +- src/Editor/Panels/Inspector/Inspector.jsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/src/tools/Brush.js b/engine/src/tools/Brush.js index 275d042a9..c4119e014 100644 --- a/engine/src/tools/Brush.js +++ b/engine/src/tools/Brush.js @@ -192,7 +192,7 @@ Wick.Tools.Brush = class extends Wick.Tool { clearTimeout(this._croquisStartTimeout); this._isInProgress = true; - this.resolutionFactor = Math.min(this.TARGET_BRUSH_SIZE/this._getRealBrushSize() * Math.pow(this.smoothness, this.testSmoothnessExponent), this.MAX_RESOLUTION_FACTOR); + this.resolutionFactor = Math.min(this.TARGET_BRUSH_SIZE/this._getRealBrushSize() * Math.pow(1-(1-this.smoothness)*(1-Math.pow(0.05, 1/this.testSmoothnessExponent)), this.testSmoothnessExponent), this.MAX_RESOLUTION_FACTOR); this.canvasScaleFactor = (this.resolutionFactor > 1) ? this.resolutionFactor : 1; this.imageScaleFactor = (this.resolutionFactor < 1) ? this.resolutionFactor : 1; this._updateCanvasAttributes(); diff --git a/src/Editor/Panels/Inspector/Inspector.jsx b/src/Editor/Panels/Inspector/Inspector.jsx index 3bcbd1dc5..ab309946e 100644 --- a/src/Editor/Panels/Inspector/Inspector.jsx +++ b/src/Editor/Panels/Inspector/Inspector.jsx @@ -1059,7 +1059,7 @@ class Inspector extends Component { val={this.props.project.tools.brush.smoothness} onChange={(val) => {this.props.project.tools.brush.smoothness = val; window.editor.projectDidChange(); }} divider={false} - inputProps={{min: 0.01, max: 1, step: 0.01}} + inputProps={{min: 0, max: 1, step: 0.01}} id="inspector-brush-tool-smoothness"/> Date: Mon, 13 Jul 2026 20:11:48 -0700 Subject: [PATCH 06/18] Make brush resolution a setting --- engine/src/ToolSettings.js | 7 ++++ engine/src/tools/Brush.js | 7 ++-- src/Editor/Panels/Inspector/Inspector.jsx | 34 ------------------- .../Toolbox/ToolSettings/ToolSettings.jsx | 14 ++++++++ src/Editor/Util/ToolIcon/ToolIcon.jsx | 2 ++ .../property-icons/brushresolution.svg | 10 ++++++ 6 files changed, 36 insertions(+), 38 deletions(-) create mode 100644 src/resources/inspector-icons/property-icons/brushresolution.svg diff --git a/engine/src/ToolSettings.js b/engine/src/ToolSettings.js index 597344ca0..78c1a84d5 100644 --- a/engine/src/ToolSettings.js +++ b/engine/src/ToolSettings.js @@ -62,6 +62,13 @@ Wick.ToolSettings = class { min: 0, max: 100, step: 1, + }, { + type: "number", + name: 'brushResolution', + default: 1, + min: 0, + max: 1, + step: 0.01, }, { type: "boolean", name: 'pressureEnabled', diff --git a/engine/src/tools/Brush.js b/engine/src/tools/Brush.js index c4119e014..4c598c210 100644 --- a/engine/src/tools/Brush.js +++ b/engine/src/tools/Brush.js @@ -46,8 +46,6 @@ Wick.Tools.Brush = class extends Wick.Tool { this.resolutionFactor = 1; this.canvasScaleFactor = 1; // Resolution: Greater or equal to 1 this.imageScaleFactor = 1; // Resolution: Lesser or equal to 1 - this.testPaperTolerance = 0; - this.testSmoothnessExponent = 2; this.croquis = null; this.croquisDOMElement = null; @@ -192,7 +190,9 @@ Wick.Tools.Brush = class extends Wick.Tool { clearTimeout(this._croquisStartTimeout); this._isInProgress = true; - this.resolutionFactor = Math.min(this.TARGET_BRUSH_SIZE/this._getRealBrushSize() * Math.pow(1-(1-this.smoothness)*(1-Math.pow(0.05, 1/this.testSmoothnessExponent)), this.testSmoothnessExponent), this.MAX_RESOLUTION_FACTOR); + var smoothnessFactor = Math.pow(1 - (1-this.getSetting('brushResolution'))*0.486095733599, 4.5); //1-Math.pow(0.05, 1/4.5), 0.486095733599 + this.resolutionFactor = this.TARGET_BRUSH_SIZE/this._getRealBrushSize() * smoothnessFactor; + this.resolutionFactor = Math.min(Math.max(this.resolutionFactor, smoothnessFactor), this.MAX_RESOLUTION_FACTOR); this.canvasScaleFactor = (this.resolutionFactor > 1) ? this.resolutionFactor : 1; this.imageScaleFactor = (this.resolutionFactor < 1) ? this.resolutionFactor : 1; this._updateCanvasAttributes(); @@ -503,7 +503,6 @@ Wick.Tools.Brush = class extends Wick.Tool { potracePath.children[0].closed = true; potracePath.children[0].applyMatrix = true; var result = potracePath.children[0]; - if (this.testPaperTolerance > 0) result.simplify(this.testPaperTolerance); // Do special brush mode action var brushMode = this.getSetting('brushMode'); diff --git a/src/Editor/Panels/Inspector/Inspector.jsx b/src/Editor/Panels/Inspector/Inspector.jsx index ab309946e..22ecc5436 100644 --- a/src/Editor/Panels/Inspector/Inspector.jsx +++ b/src/Editor/Panels/Inspector/Inspector.jsx @@ -1045,40 +1045,6 @@ class Inspector extends Component { } render() { - if (this.props.project.selection.numObjects === 0 && this.props.project.activeTool.name === 'brush') { - return ( -
-
- -
-
- {this.props.project.tools.brush.smoothness = val; window.editor.projectDidChange(); }} - divider={false} - inputProps={{min: 0, max: 1, step: 0.01}} - id="inspector-brush-tool-smoothness"/> - {this.props.project.tools.brush.testPaperTolerance = val; window.editor.projectDidChange(); }} - divider={false} - inputProps={{min: 0, max: 10, step: 0.1}} - id="inspector-brush-tool-paper-js-tolerance"/> - {this.props.project.tools.brush.testSmoothnessExponent = val; window.editor.projectDidChange(); }} - divider={false} - inputProps={{min: 1, max: 8, step: 0.1}} - id="inspector-brush-tool-smoothness-exponent"/> -
-
- ); - } let selectionType = this.props.getSelectionType(); return(
diff --git a/src/Editor/Panels/Toolbox/ToolSettings/ToolSettings.jsx b/src/Editor/Panels/Toolbox/ToolSettings/ToolSettings.jsx index 96051eb0a..3f36c60a8 100644 --- a/src/Editor/Panels/Toolbox/ToolSettings/ToolSettings.jsx +++ b/src/Editor/Panels/Toolbox/ToolSettings/ToolSettings.jsx @@ -71,6 +71,7 @@ class ToolSettings extends Component {
{this.renderBrushSize()} {this.renderBrushSmoothing()} + {this.renderBrushResolution()} {this.renderEnablePressure()} {this.renderEnableRelativeBrushSize()} {this.renderBrushMode()} @@ -234,6 +235,19 @@ class ToolSettings extends Component { ) } + renderBrushResolution = () => { + return ( + this.setToolSetting('brushResolution', val)} + inputRestrictions={this.props.getToolSettingRestrictions('brushResolution')}/> + ) + } + renderFontSize = () => { return ( + + + + + + + + + From a288b2c41271677aa4d6d94f672f9bcb5ea87040 Mon Sep 17 00:00:00 2001 From: funny bot Date: Mon, 13 Jul 2026 20:14:02 -0700 Subject: [PATCH 07/18] Remove unused smoothness property --- engine/src/tools/Brush.js | 1 - 1 file changed, 1 deletion(-) diff --git a/engine/src/tools/Brush.js b/engine/src/tools/Brush.js index 4c598c210..c48cac8e3 100644 --- a/engine/src/tools/Brush.js +++ b/engine/src/tools/Brush.js @@ -42,7 +42,6 @@ Wick.Tools.Brush = class extends Wick.Tool { this.TARGET_BRUSH_SIZE = 50; this.MAX_RESOLUTION_FACTOR = 2; - this.smoothness = 1; this.resolutionFactor = 1; this.canvasScaleFactor = 1; // Resolution: Greater or equal to 1 this.imageScaleFactor = 1; // Resolution: Lesser or equal to 1 From 0c599e4840e0c9f1cfdfeef3455a1050b576b5a2 Mon Sep 17 00:00:00 2001 From: funny bot Date: Tue, 14 Jul 2026 14:02:19 -0700 Subject: [PATCH 08/18] Modify easing of brush resolution setting --- engine/src/tools/Brush.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engine/src/tools/Brush.js b/engine/src/tools/Brush.js index c48cac8e3..3fe53c9ac 100644 --- a/engine/src/tools/Brush.js +++ b/engine/src/tools/Brush.js @@ -189,7 +189,8 @@ Wick.Tools.Brush = class extends Wick.Tool { clearTimeout(this._croquisStartTimeout); this._isInProgress = true; - var smoothnessFactor = Math.pow(1 - (1-this.getSetting('brushResolution'))*0.486095733599, 4.5); //1-Math.pow(0.05, 1/4.5), 0.486095733599 + var t = this.getSetting('brushResolution'); + var smoothnessFactor = 0.05 + (Math.pow(t, 5) + 0.1*t*(1-t)) * 0.95; this.resolutionFactor = this.TARGET_BRUSH_SIZE/this._getRealBrushSize() * smoothnessFactor; this.resolutionFactor = Math.min(Math.max(this.resolutionFactor, smoothnessFactor), this.MAX_RESOLUTION_FACTOR); this.canvasScaleFactor = (this.resolutionFactor > 1) ? this.resolutionFactor : 1; From 59cf8cbe7cdfeb4a48776674d47952ab54ec233b Mon Sep 17 00:00:00 2001 From: alani25 Date: Sat, 1 Aug 2026 02:59:29 -0400 Subject: [PATCH 09/18] scale croquis canvas by canvas scale factor (bug fix) --- engine/src/tools/Brush.js | 13 ++++++++++--- package-lock.json | 26 +++++++++++++------------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/engine/src/tools/Brush.js b/engine/src/tools/Brush.js index 24209ee61..87ed8b5a5 100644 --- a/engine/src/tools/Brush.js +++ b/engine/src/tools/Brush.js @@ -395,11 +395,18 @@ Wick.Tools.Brush = class extends Wick.Tool { this.paper.view._element.parentElement.appendChild(this.croquisDOMElement); } - // use the CSS pixels size (viewSize) rather than trying to predict with device pixels (element.width) — they change when browser zoom ≠ 100% -H.A. - var targetW = Math.round(this.paper.view.viewSize.width); - var targetH = Math.round(this.paper.view.viewSize.height); + // Scale the croquis canvas up by canvasScaleFactor so that brush coordinates map to + // the correct CSS position on screen + // the CSS display stays at 100:100% so the larger canvas is downsampled visually muhehe -H.A. + var targetW = Math.round(this.paper.view.viewSize.width * this.canvasScaleFactor); + var targetH = Math.round(this.paper.view.viewSize.height * this.canvasScaleFactor); if(this.croquis.getCanvasWidth() !== targetW || this.croquis.getCanvasHeight() !== targetH) { this.croquis.setCanvasSize(targetW, targetH); + // setCanvasSize may recreate canvas elements — re-apply CSS so display stays at viewport size + this.croquisDOMElement.querySelectorAll('canvas').forEach(canvasElement => { + canvasElement.style.width = '100%'; + canvasElement.style.height = '100%'; + }); } this.croquisDOMElement.style.width = '100%'; this.croquisDOMElement.style.height = '100%'; diff --git a/package-lock.json b/package-lock.json index eaa284500..7ad800f4f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7049,9 +7049,9 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.16", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", - "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -10785,9 +10785,9 @@ } }, "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.2.tgz", - "integrity": "sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -16063,9 +16063,9 @@ "optional": true }, "node_modules/nanoid": { - "version": "3.3.15", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz", - "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", "funding": [ { "type": "github", @@ -17227,9 +17227,9 @@ } }, "node_modules/postcss": { - "version": "8.5.15", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", - "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "version": "8.5.25", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.25.tgz", + "integrity": "sha512-DTPx3RWSSnWyzLxQnlH0rJP+EW5ekl16ZU4/psbIhA0e53kJfdgaN5vKM+xP7yJtXVu+nfdVFmlgFDEKAe4Pyw==", "funding": [ { "type": "opencollective", @@ -17246,7 +17246,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.12", + "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, From a568862f26cef57c0d17a10a03360921ce2e60fc Mon Sep 17 00:00:00 2001 From: alani25 Date: Sat, 1 Aug 2026 04:23:53 -0400 Subject: [PATCH 10/18] moved brush ui to inspector --- src/Editor/Editor.jsx | 2 + src/Editor/Panels/Inspector/Inspector.jsx | 108 +++++++++++++++++- .../Toolbox/ToolSettings/ToolSettings.jsx | 5 - 3 files changed, 109 insertions(+), 6 deletions(-) diff --git a/src/Editor/Editor.jsx b/src/Editor/Editor.jsx index f5802f8f1..945d75d12 100644 --- a/src/Editor/Editor.jsx +++ b/src/Editor/Editor.jsx @@ -1351,8 +1351,10 @@ class Editor extends EditorCore { { @@ -930,6 +935,93 @@ class Inspector extends Component { ) } + toggleBrushModes = (state) => { + if (state === undefined) state = !this.state.showBrushModes; + this.setState({ showBrushModes: state }); + } + + renderBrushSettings = () => { + let brushModeIcon = 'brushmodenone'; + let brushMode = this.props.getToolSetting('brushMode'); + if (brushMode === 'inside') brushModeIcon = 'brushmodeinside'; + else if (brushMode === 'outside') brushModeIcon = 'brushmodeoutside'; + + return ( +
+ this.props.setToolSetting('brushStabilizerWeight', val)} + inputRestrictions={this.props.getToolSettingRestrictions('brushStabilizerWeight')} + /> + this.props.setToolSetting('brushResolution', val)} + inputRestrictions={this.props.getToolSettingRestrictions('brushResolution')} + /> + this.props.setToolSetting('pressureEnabled', !this.props.getToolSetting('pressureEnabled'))} + /> + this.props.setToolSetting('relativeBrushSize', !this.props.getToolSetting('relativeBrushSize'))} + /> +
+ + +
+
+ this.props.setToolSetting('brushMode', 'none')} + /> + this.props.setToolSetting('brushMode', 'inside')} + /> + this.props.setToolSetting('brushMode', 'outside')} + /> +
+
+
+
+
+ ); + } + /** * Renders a default selection view with no properties. */ @@ -1046,6 +1138,20 @@ class Inspector extends Component { render() { let selectionType = this.props.getSelectionType(); + + if (this.props.activeTool === 'brush') { + return ( +
+
+ +
+
+ {this.renderBrushSettings()} +
+
+ ); + } + return(
{this.renderTitle(selectionType)} diff --git a/src/Editor/Panels/Toolbox/ToolSettings/ToolSettings.jsx b/src/Editor/Panels/Toolbox/ToolSettings/ToolSettings.jsx index 3f36c60a8..c8ad24867 100644 --- a/src/Editor/Panels/Toolbox/ToolSettings/ToolSettings.jsx +++ b/src/Editor/Panels/Toolbox/ToolSettings/ToolSettings.jsx @@ -70,11 +70,6 @@ class ToolSettings extends Component { return (
{this.renderBrushSize()} - {this.renderBrushSmoothing()} - {this.renderBrushResolution()} - {this.renderEnablePressure()} - {this.renderEnableRelativeBrushSize()} - {this.renderBrushMode()}
); } From 9b9445c808746d0f570b09779a4ea369445bb37e Mon Sep 17 00:00:00 2001 From: alani25 Date: Sat, 1 Aug 2026 04:50:59 -0400 Subject: [PATCH 11/18] added brush UI to inspector --- src/Editor/Panels/Inspector/Inspector.jsx | 136 +++++++++--------- .../InspectorNumericSlider.jsx | 14 +- 2 files changed, 80 insertions(+), 70 deletions(-) diff --git a/src/Editor/Panels/Inspector/Inspector.jsx b/src/Editor/Panels/Inspector/Inspector.jsx index 2c118c7e5..2cd58556d 100644 --- a/src/Editor/Panels/Inspector/Inspector.jsx +++ b/src/Editor/Panels/Inspector/Inspector.jsx @@ -947,76 +947,80 @@ class Inspector extends Component { else if (brushMode === 'outside') brushModeIcon = 'brushmodeoutside'; return ( -
- this.props.setToolSetting('brushStabilizerWeight', val)} - inputRestrictions={this.props.getToolSettingRestrictions('brushStabilizerWeight')} - /> - this.props.setToolSetting('brushResolution', val)} - inputRestrictions={this.props.getToolSettingRestrictions('brushResolution')} - /> - this.props.setToolSetting('pressureEnabled', !this.props.getToolSetting('pressureEnabled'))} - /> - this.props.setToolSetting('relativeBrushSize', !this.props.getToolSetting('relativeBrushSize'))} - /> -
+
+ {/* Sliders — same inspector-item wrapper as opacity/transform rows */} +
+ this.props.setToolSetting('brushStabilizerWeight', val)} + inputProps={this.props.getToolSettingRestrictions('brushStabilizerWeight')} + /> + this.props.setToolSetting('brushResolution', val)} + inputProps={this.props.getToolSettingRestrictions('brushResolution')} + /> +
+ {/* Icon buttons — same as toolbar */} +
+ this.props.setToolSetting('pressureEnabled', !this.props.getToolSetting('pressureEnabled'))} + /> this.props.setToolSetting('relativeBrushSize', !this.props.getToolSetting('relativeBrushSize'))} /> - -
-
- this.props.setToolSetting('brushMode', 'none')} - /> - this.props.setToolSetting('brushMode', 'inside')} - /> - this.props.setToolSetting('brushMode', 'outside')} - /> +
+ + +
+
+ this.props.setToolSetting('brushMode', 'none')} + /> + this.props.setToolSetting('brushMode', 'inside')} + /> + this.props.setToolSetting('brushMode', 'outside')} + /> +
-
- + +
); diff --git a/src/Editor/Panels/Inspector/InspectorRow/InspectorRowTypes/InspectorNumericSlider.jsx b/src/Editor/Panels/Inspector/InspectorRow/InspectorRowTypes/InspectorNumericSlider.jsx index 1b9a6bd55..2fbcbc5f8 100644 --- a/src/Editor/Panels/Inspector/InspectorRow/InspectorRowTypes/InspectorNumericSlider.jsx +++ b/src/Editor/Panels/Inspector/InspectorRow/InspectorRowTypes/InspectorNumericSlider.jsx @@ -20,6 +20,7 @@ import React, { Component } from 'react'; import InspectorInput from 'Editor/Panels/Inspector/InspectorRow/InspectorInput/InspectorInput'; +import ToolIcon from 'Editor/Util/ToolIcon/ToolIcon'; import '../_inspectorrow.scss'; @@ -28,15 +29,20 @@ class InspectorNumericSlider extends Component { let idLabel = this.props.tooltip.replace(/\s+/g, '-').toLowerCase(); return(
- {/* Identifier */} -