diff --git a/src/helper/bit-tools/rect-tool.js b/src/helper/bit-tools/rect-tool.js index cbaef41b..d5de5ebe 100644 --- a/src/helper/bit-tools/rect-tool.js +++ b/src/helper/bit-tools/rect-tool.js @@ -1,6 +1,6 @@ import paper from '@scratch/paper'; import Modes from '../../lib/modes'; -import {drawRect} from '../bitmap'; +import {fillRect} from '../bitmap'; import {createCanvas, getRaster} from '../layer'; import {clearSelection} from '../selection'; import BoundingBoxTool from '../selection-tools/bounding-box-tool'; @@ -25,7 +25,7 @@ class RectTool extends paper.Tool { this.onUpdateImage = onUpdateImage; this.boundingBoxTool = new BoundingBoxTool(Modes.BIT_RECT, setSelectedItems, clearSelectedItems, onUpdateImage); const nudgeTool = new NudgeTool(this.boundingBoxTool, onUpdateImage); - + // We have to set these functions instead of just declaring them because // paper.js tools hook up the listeners in the setter functions. this.onMouseDown = this.handleMouseDown; @@ -98,7 +98,7 @@ class RectTool extends paper.Tool { if (this.rect) this.rect.remove(); this.rect = new paper.Shape.Rectangle(baseRect); this.rect.fillColor = this.color; - + if (event.modifiers.alt) { this.rect.position = event.downPoint; } else { @@ -107,7 +107,7 @@ class RectTool extends paper.Tool { } handleMouseUp (event) { if (event.event.button > 0 || !this.active) return; // only first mouse button - + if (this.isBoundingBoxMode) { this.boundingBoxTool.onMouseUp(event); this.isBoundingBoxMode = null; @@ -134,7 +134,7 @@ class RectTool extends paper.Tool { const tmpCanvas = createCanvas(); const context = tmpCanvas.getContext('2d'); context.fillStyle = this.color; - drawRect(this.rect, context); + fillRect(this.rect, context); getRaster().drawImage(tmpCanvas, new paper.Point()); this.rect.remove(); diff --git a/src/helper/bitmap.js b/src/helper/bitmap.js index 6af4d380..22ef902b 100644 --- a/src/helper/bitmap.js +++ b/src/helper/bitmap.js @@ -523,7 +523,7 @@ const floodFillAll = function (x, y, color, context) { * @param {!paper.Shape.Rectangle} rect The rectangle to draw to the canvas * @param {!HTMLCanvas2DContext} context The context in which to draw */ -const drawRect = function (rect, context) { +const fillRect = function (rect, context) { // No rotation component to matrix if (rect.matrix.b === 0 && rect.matrix.c === 0) { const width = rect.size.width * rect.matrix.a; @@ -541,25 +541,27 @@ const drawRect = function (rect, context) { const heightPoint = rect.matrix.transform(new paper.Point(-rect.size.width / 2, rect.size.height / 2)); const endPoint = rect.matrix.transform(new paper.Point(rect.size.width / 2, rect.size.height / 2)); const center = rect.matrix.transform(new paper.Point()); - forEachLinePoint(startPoint, widthPoint, (x, y) => { - context.fillRect(x, y, 1, 1); - }); - forEachLinePoint(startPoint, heightPoint, (x, y) => { - context.fillRect(x, y, 1, 1); - }); - forEachLinePoint(endPoint, widthPoint, (x, y) => { - context.fillRect(x, y, 1, 1); - }); - forEachLinePoint(endPoint, heightPoint, (x, y) => { - context.fillRect(x, y, 1, 1); - }); - floodFill(~~center.x, ~~center.y, context.fillStyle, context); + const points = [startPoint, widthPoint, heightPoint, endPoint].sort((a, b) => a.x - b.x); + + const solveY = (point1, point2, x) => { + if (point2.x === point1.x) return center.x > point1.x ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY; + return ((point2.y - point1.y) / (point2.x - point1.x) * (x - point1.x)) + point1.y; + }; + for (let x = Math.round(points[0].x); x < Math.round(points[3].x); x++) { + const ys = [ + solveY(startPoint, widthPoint, x + .5), + solveY(startPoint, heightPoint, x + .5), + solveY(endPoint, widthPoint, x + .5), + solveY(endPoint, heightPoint, x + .5) + ].sort((a, b) => a - b); + context.fillRect(x, Math.round(ys[1]), 1, Math.max(1, Math.round(ys[2]) - Math.round(ys[1]))); + } }; export { convertToBitmap, convertToVector, - drawRect, + fillRect, floodFill, floodFillAll, getBrushMark,