diff --git a/src/containers/paper-canvas.jsx b/src/containers/paper-canvas.jsx index 4da7a5b6..79592495 100644 --- a/src/containers/paper-canvas.jsx +++ b/src/containers/paper-canvas.jsx @@ -7,6 +7,7 @@ import Formats from '../lib/format'; import Modes from '../lib/modes'; import log from '../log/log'; +import {trim} from '../helper/bitmap'; import {performSnapshot} from '../helper/undo'; import {undoSnapshot, clearUndoState} from '../reducers/undo'; import {isGroup, ungroupItems} from '../helper/group'; @@ -26,6 +27,7 @@ class PaperCanvas extends React.Component { super(props); bindAll(this, [ 'convertToBitmap', + 'convertToVector', 'setCanvas', 'importSvg', 'handleKeyDown', @@ -57,7 +59,7 @@ class PaperCanvas extends React.Component { } else if (this.props.format === Formats.VECTOR && newProps.format === Formats.BITMAP) { this.convertToBitmap(); } else if (this.props.format === Formats.BITMAP && newProps.format === Formats.VECTOR) { - // do vector conversion + this.convertToVector(); } } componentWillUnmount () { @@ -85,6 +87,16 @@ class PaperCanvas extends React.Component { paper.project.activeLayer.removeChildren(); performSnapshot(this.props.undoSnapshot); } + convertToVector () { + const raster = trim(getRaster()); + if (raster.width === 0 || raster.height === 0) { + raster.remove(); + } else { + paper.project.activeLayer.addChild(raster); + } + clearRaster(); + performSnapshot(this.props.undoSnapshot); + } switchCostume (svg, rotationCenterX, rotationCenterY) { for (const layer of paper.project.layers) { if (layer.data.isRasterLayer) { diff --git a/src/helper/bitmap.js b/src/helper/bitmap.js new file mode 100644 index 00000000..5c1db739 --- /dev/null +++ b/src/helper/bitmap.js @@ -0,0 +1,37 @@ +import paper from '@scratch/paper'; + +const rowBlank_ = function (imageData, width, y) { + for (let x = 0; x < width; ++x) { + if (imageData.data[(y * width << 2) + (x << 2) + 3] !== 0) return false; + } + return true; +}; + +const columnBlank_ = function (imageData, width, x, top, bottom) { + for (let y = top; y < bottom; ++y) { + if (imageData.data[(y * width << 2) + (x << 2) + 3] !== 0) return false; + } + return true; +}; + +// Adapted from Tim Down's https://gist.github.com/timdown/021d9c8f2aabc7092df564996f5afbbf +// Trims transparent pixels from edges. +const trim = function (raster) { + const width = raster.width; + const imageData = raster.getImageData(raster.bounds); + let top = 0; + let bottom = imageData.height; + let left = 0; + let right = imageData.width; + + while (top < bottom && rowBlank_(imageData, width, top)) ++top; + while (bottom - 1 > top && rowBlank_(imageData, width, bottom - 1)) --bottom; + while (left < right && columnBlank_(imageData, width, left, top, bottom)) ++left; + while (right - 1 > left && columnBlank_(imageData, width, right - 1, top, bottom)) --right; + + return raster.getSubRaster(new paper.Rectangle(left, top, right - left, bottom - top)); +}; + +export { + trim +};