Move convert to bitmap into bitmap helper (#490)

This commit is contained in:
DD Liu 2018-06-07 11:26:26 -04:00 committed by GitHub
parent a9ba5eac9b
commit ebed37390d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 68 additions and 65 deletions

View file

@ -7,13 +7,11 @@ import Formats from '../lib/format';
import Modes from '../lib/modes'; import Modes from '../lib/modes';
import log from '../log/log'; import log from '../log/log';
import {inlineSvgFonts} from 'scratch-svg-renderer'; import {convertToBitmap, convertToVector} from '../helper/bitmap';
import {trim} from '../helper/bitmap';
import {performSnapshot} from '../helper/undo'; import {performSnapshot} from '../helper/undo';
import {undoSnapshot, clearUndoState} from '../reducers/undo'; import {undoSnapshot, clearUndoState} from '../reducers/undo';
import {isGroup, ungroupItems} from '../helper/group'; import {isGroup, ungroupItems} from '../helper/group';
import {clearRaster, getRaster, setupLayers, hideGuideLayers, showGuideLayers} from '../helper/layer'; import {clearRaster, getRaster, setupLayers} from '../helper/layer';
import {deleteSelection, getSelectedLeafItems} from '../helper/selection'; import {deleteSelection, getSelectedLeafItems} from '../helper/selection';
import {clearSelectedItems, setSelectedItems} from '../reducers/selected-items'; import {clearSelectedItems, setSelectedItems} from '../reducers/selected-items';
import {ART_BOARD_WIDTH, ART_BOARD_HEIGHT, pan, resetZoom, zoomOnFixedPoint} from '../helper/view'; import {ART_BOARD_WIDTH, ART_BOARD_HEIGHT, pan, resetZoom, zoomOnFixedPoint} from '../helper/view';
@ -31,8 +29,6 @@ class PaperCanvas extends React.Component {
constructor (props) { constructor (props) {
super(props); super(props);
bindAll(this, [ bindAll(this, [
'convertToBitmap',
'convertToVector',
'setCanvas', 'setCanvas',
'importSvg', 'importSvg',
'handleKeyDown', 'handleKeyDown',
@ -61,9 +57,9 @@ class PaperCanvas extends React.Component {
this.switchCostume( this.switchCostume(
newProps.imageFormat, newProps.image, newProps.rotationCenterX, newProps.rotationCenterY); newProps.imageFormat, newProps.image, newProps.rotationCenterX, newProps.rotationCenterY);
} else if (isVector(this.props.format) && newProps.format === Formats.BITMAP) { } else if (isVector(this.props.format) && newProps.format === Formats.BITMAP) {
this.convertToBitmap(); convertToBitmap(this.props.clearSelectedItems, this.props.onUpdateImage);
} else if (isBitmap(this.props.format) && newProps.format === Formats.VECTOR) { } else if (isBitmap(this.props.format) && newProps.format === Formats.VECTOR) {
this.convertToVector(); convertToVector(this.props.clearSelectedItems, this.props.onUpdateImage);
} }
} }
componentWillUnmount () { componentWillUnmount () {
@ -82,60 +78,6 @@ class PaperCanvas extends React.Component {
} }
} }
} }
convertToBitmap () {
// @todo if the active layer contains only rasters, drawing them directly to the raster layer
// would be more efficient.
// Export svg
const guideLayers = hideGuideLayers(true /* includeRaster */);
const bounds = paper.project.activeLayer.bounds;
const svg = paper.project.exportSVG({
bounds: 'content',
matrix: new paper.Matrix().translate(-bounds.x, -bounds.y)
});
showGuideLayers(guideLayers);
// Get rid of anti-aliasing
// @todo get crisp text?
svg.setAttribute('shape-rendering', 'crispEdges');
inlineSvgFonts(svg);
const svgString = (new XMLSerializer()).serializeToString(svg);
// Put anti-aliased SVG into image, and dump image back into canvas
const img = new Image();
img.onload = () => {
if (img.width && img.height) {
getRaster().drawImage(
img,
new paper.Point(Math.floor(bounds.topLeft.x), Math.floor(bounds.topLeft.y)));
}
paper.project.activeLayer.removeChildren();
this.props.onUpdateImage();
};
img.onerror = () => {
// Fallback if browser does not support SVG data URIs in images.
// The problem with rasterize is that it will anti-alias.
const raster = paper.project.activeLayer.rasterize(72, false /* insert */);
raster.onLoad = () => {
if (raster.canvas.width && raster.canvas.height) {
getRaster().drawImage(raster.canvas, raster.bounds.topLeft);
}
paper.project.activeLayer.removeChildren();
this.props.onUpdateImage();
};
};
// Hash tags will break image loading without being encoded first
img.src = `data:image/svg+xml;utf8,${encodeURIComponent(svgString)}`;
}
convertToVector () {
this.props.clearSelectedItems();
const trimmedRaster = trim(getRaster());
if (trimmedRaster) {
paper.project.activeLayer.addChild(trimmedRaster);
}
clearRaster();
this.props.onUpdateImage();
}
switchCostume (format, image, rotationCenterX, rotationCenterY) { switchCostume (format, image, rotationCenterX, rotationCenterY) {
for (const layer of paper.project.layers) { for (const layer of paper.project.layers) {
if (layer.data.isRasterLayer) { if (layer.data.isRasterLayer) {

View file

@ -1,4 +1,6 @@
import paper from '@scratch/paper'; import paper from '@scratch/paper';
import {clearRaster, getRaster, hideGuideLayers, showGuideLayers} from '../helper/layer';
import {inlineSvgFonts} from 'scratch-svg-renderer';
const forEachLinePoint = function (point1, point2, callback) { const forEachLinePoint = function (point1, point2, callback) {
// Bresenham line algorithm // Bresenham line algorithm
@ -141,7 +143,7 @@ const getHitBounds = function (raster) {
return new paper.Rectangle(left, top, right - left, bottom - top); return new paper.Rectangle(left, top, right - left, bottom - top);
}; };
const trim = function (raster) { const trim_ = function (raster) {
const hitBounds = getHitBounds(raster); const hitBounds = getHitBounds(raster);
if (hitBounds.width && hitBounds.height) { if (hitBounds.width && hitBounds.height) {
return raster.getSubRaster(getHitBounds(raster)); return raster.getSubRaster(getHitBounds(raster));
@ -149,10 +151,69 @@ const trim = function (raster) {
return null; return null;
}; };
const convertToBitmap = function (clearSelectedItems, onUpdateImage) {
// @todo if the active layer contains only rasters, drawing them directly to the raster layer
// would be more efficient.
clearSelectedItems();
// Export svg
const guideLayers = hideGuideLayers(true /* includeRaster */);
const bounds = paper.project.activeLayer.bounds;
const svg = paper.project.exportSVG({
bounds: 'content',
matrix: new paper.Matrix().translate(-bounds.x, -bounds.y)
});
showGuideLayers(guideLayers);
// Get rid of anti-aliasing
// @todo get crisp text?
svg.setAttribute('shape-rendering', 'crispEdges');
inlineSvgFonts(svg);
const svgString = (new XMLSerializer()).serializeToString(svg);
// Put anti-aliased SVG into image, and dump image back into canvas
const img = new Image();
img.onload = () => {
if (img.width && img.height) {
getRaster().drawImage(
img,
new paper.Point(Math.floor(bounds.topLeft.x), Math.floor(bounds.topLeft.y)));
}
paper.project.activeLayer.removeChildren();
onUpdateImage();
};
img.onerror = () => {
// Fallback if browser does not support SVG data URIs in images.
// The problem with rasterize is that it will anti-alias.
const raster = paper.project.activeLayer.rasterize(72, false /* insert */);
raster.onLoad = () => {
if (raster.canvas.width && raster.canvas.height) {
getRaster().drawImage(raster.canvas, raster.bounds.topLeft);
}
paper.project.activeLayer.removeChildren();
onUpdateImage();
};
};
// Hash tags will break image loading without being encoded first
img.src = `data:image/svg+xml;utf8,${encodeURIComponent(svgString)}`;
};
const convertToVector = function (clearSelectedItems, onUpdateImage) {
clearSelectedItems();
const trimmedRaster = trim_(getRaster());
if (trimmedRaster) {
paper.project.activeLayer.addChild(trimmedRaster);
}
clearRaster();
onUpdateImage();
};
export { export {
convertToBitmap,
convertToVector,
getBrushMark, getBrushMark,
getHitBounds, getHitBounds,
fillEllipse, fillEllipse,
forEachLinePoint, forEachLinePoint
trim
}; };