Tighten bitmap selection bounds

This commit is contained in:
adroitwhiz 2020-05-16 03:41:39 -04:00
parent b0164e7783
commit de502d6843
2 changed files with 19 additions and 8 deletions

View file

@ -320,11 +320,18 @@ const columnBlank_ = function (imageData, width, x, top, bottom) {
return true; return true;
}; };
// Adapted from Tim Down's https://gist.github.com/timdown/021d9c8f2aabc7092df564996f5afbbf /**
// Get bounds, trimming transparent pixels from edges. * Get bounds around the contents of a raster, trimming transparent pixels from edges.
const getHitBounds = function (raster) { * Adapted from Tim Down's https://gist.github.com/timdown/021d9c8f2aabc7092df564996f5afbbf
const width = raster.width; * @param {paper.Raster} raster The raster to get the bounds around
const imageData = raster.getImageData(raster.bounds); * @param {paper.Rectangle} [rect] Optionally, an alternative bounding rectangle to limit the check to.
* @returns {paper.Rectangle} The bounds around the opaque area of the passed raster
* (or opaque within the passed rectangle)
*/
const getHitBounds = function (raster, rect) {
const bounds = rect || raster.bounds;
const width = bounds.width;
const imageData = raster.getImageData(bounds);
let top = 0; let top = 0;
let bottom = imageData.height; let bottom = imageData.height;
let left = 0; let left = 0;
@ -343,7 +350,7 @@ const getHitBounds = function (raster) {
left = right = imageData.width / 2; left = right = imageData.width / 2;
} }
return new paper.Rectangle(left, top, right - left, bottom - top); return new paper.Rectangle(left + bounds.left, top + bounds.top, right - left, bottom - top);
}; };
const trim_ = function (raster) { const trim_ = function (raster) {

View file

@ -3,6 +3,7 @@ import {rectSelect} from '../guides';
import {clearSelection, processRectangularSelection} from '../selection'; import {clearSelection, processRectangularSelection} from '../selection';
import {getRaster} from '../layer'; import {getRaster} from '../layer';
import {ART_BOARD_WIDTH, ART_BOARD_HEIGHT} from '../view'; import {ART_BOARD_WIDTH, ART_BOARD_HEIGHT} from '../view';
import {getHitBounds} from '../../helper/bitmap';
/** Tool to handle drag selection. A dotted line box appears and everything enclosed is selected. */ /** Tool to handle drag selection. A dotted line box appears and everything enclosed is selected. */
class SelectionBoxTool { class SelectionBoxTool {
@ -44,8 +45,8 @@ class SelectionBoxTool {
} }
onMouseUpBitmap (event) { onMouseUpBitmap (event) {
if (event.event.button > 0) return; // only first mouse button if (event.event.button > 0) return; // only first mouse button
if (this.selectionRect && this.selectionRect.bounds.intersects(getRaster().bounds)) { if (this.selectionRect) {
const rect = new paper.Rectangle({ let rect = new paper.Rectangle({
from: new paper.Point( from: new paper.Point(
Math.max(0, Math.round(this.selectionRect.bounds.topLeft.x)), Math.max(0, Math.round(this.selectionRect.bounds.topLeft.x)),
Math.max(0, Math.round(this.selectionRect.bounds.topLeft.y))), Math.max(0, Math.round(this.selectionRect.bounds.topLeft.y))),
@ -54,6 +55,9 @@ class SelectionBoxTool {
Math.min(ART_BOARD_HEIGHT, Math.round(this.selectionRect.bounds.bottomRight.y))) Math.min(ART_BOARD_HEIGHT, Math.round(this.selectionRect.bounds.bottomRight.y)))
}); });
// Trim/tighten selection bounds inwards to only the opaque region, excluding transparent pixels
rect = getHitBounds(getRaster(), rect);
if (rect.area) { if (rect.area) {
// Pull selected raster to active layer // Pull selected raster to active layer
const raster = getRaster().getSubRaster(rect); const raster = getRaster().getSubRaster(rect);