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 50fe2afeb..3fe53c9ac 100644 --- a/engine/src/tools/Brush.js +++ b/engine/src/tools/Brush.js @@ -40,6 +40,12 @@ Wick.Tools.Brush = class extends Wick.Tool { this.MIN_PRESSURE = 0.14; + this.TARGET_BRUSH_SIZE = 50; + this.MAX_RESOLUTION_FACTOR = 2; + 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 +125,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 +189,16 @@ Wick.Tools.Brush = class extends Wick.Tool { clearTimeout(this._croquisStartTimeout); this._isInProgress = true; + 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; + 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 +396,13 @@ 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); + 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%'; // Fake brush opacity in croquis by changing the opacity of the croquis canvas this.croquisDOMElement.style.opacity = this.getSetting('fillColor').a; @@ -391,7 +411,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 +478,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 +497,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; 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 {