Get undo/redo working

This commit is contained in:
DD 2018-04-09 17:47:11 -04:00
parent 15053d15f0
commit 6e4ab3191a
5 changed files with 60 additions and 21 deletions

View file

@ -1,5 +1,6 @@
import paper from '@scratch/paper';
import PropTypes from 'prop-types';
import React from 'react';
import PaintEditorComponent from '../components/paint-editor/paint-editor.jsx';
@ -11,7 +12,8 @@ import {deactivateEyeDropper} from '../reducers/eye-dropper';
import {setTextEditTarget} from '../reducers/text-edit-target';
import {updateViewBounds} from '../reducers/view-bounds';
import {hideGuideLayers, showGuideLayers} from '../helper/layer';
import {getRaster, hideGuideLayers, showGuideLayers} from '../helper/layer';
import {trim} from '../helper/bitmap';
import {performUndo, performRedo, performSnapshot, shouldShowUndo, shouldShowRedo} from '../helper/undo';
import {bringToFront, sendBackward, sendToBack, bringForward} from '../helper/order';
import {groupSelection, ungroupSelection} from '../helper/group';
@ -90,9 +92,20 @@ class PaintEditor extends React.Component {
const oldCenter = paper.project.view.center.clone();
resetZoom();
const guideLayers = hideGuideLayers();
let raster;
if (this.props.format === Formats.BITMAP) {
// @todo export bitmap here
raster = trim(getRaster());
if (raster.width === 0 || raster.height === 0) {
raster.remove();
} else {
paper.project.activeLayer.addChild(raster);
}
}
const guideLayers = hideGuideLayers(true /* includeRaster */);
const bounds = paper.project.activeLayer.bounds;
this.props.onUpdateSvg(
paper.project.exportSVG({
asString: true,
@ -108,6 +121,8 @@ class PaintEditor extends React.Component {
performSnapshot(this.props.undoSnapshot);
}
if (raster) raster.remove();
// Restore old zoom
paper.project.view.zoom = oldZoom;
paper.project.view.center = oldCenter;

View file

@ -79,15 +79,17 @@ class PaperCanvas extends React.Component {
}
}
convertToBitmap () {
this.props.clearSelectedItems();
const raster = paper.project.activeLayer.rasterize(72, false /* insert */);
raster.onLoad = function () {
const subCanvas = raster.canvas;
getRaster().drawImage(subCanvas, raster.bounds.topLeft);
};
paper.project.activeLayer.removeChildren();
performSnapshot(this.props.undoSnapshot);
paper.project.activeLayer.removeChildren();
this.props.onUpdateSvg();
}.bind(this);
}
convertToVector () {
this.props.clearSelectedItems();
const raster = trim(getRaster());
if (raster.width === 0 || raster.height === 0) {
raster.remove();
@ -95,7 +97,7 @@ class PaperCanvas extends React.Component {
paper.project.activeLayer.addChild(raster);
}
clearRaster();
performSnapshot(this.props.undoSnapshot);
this.props.onUpdateSvg();
}
switchCostume (svg, rotationCenterX, rotationCenterY) {
for (const layer of paper.project.layers) {

View file

@ -9,7 +9,6 @@ const _getLayer = function (layerString) {
return layer;
}
}
log.error(`Didn't find layer ${layerString}`);
};
const _getPaintingLayer = function () {
@ -36,22 +35,40 @@ const _getBackgroundGuideLayer = function () {
return _getLayer('isBackgroundGuideLayer');
};
const _makeGuideLayer = function () {
const guideLayer = new paper.Layer();
guideLayer.data.isGuideLayer = true;
return guideLayer;
};
const getGuideLayer = function () {
return _getLayer('isGuideLayer');
let layer = _getLayer('isGuideLayer');
if (!layer) {
layer = _makeGuideLayer();
_getPaintingLayer().activate();
}
return layer;
};
/**
* Removes the guide layers, e.g. for purposes of exporting the image. Must call showGuideLayers to re-add them.
* @param {boolean} includeRaster true if the raster layer should also be hidden
* @return {object} an object of the removed layers, which should be passed to showGuideLayers to re-add them.
*/
const hideGuideLayers = function () {
const hideGuideLayers = function (includeRaster) {
const backgroundGuideLayer = _getBackgroundGuideLayer();
const guideLayer = getGuideLayer();
guideLayer.remove();
backgroundGuideLayer.remove();
let rasterLayer;
if (includeRaster) {
rasterLayer = _getLayer('isRasterLayer');
rasterLayer.remove();
}
return {
guideLayer: guideLayer,
backgroundGuideLayer: backgroundGuideLayer
backgroundGuideLayer: backgroundGuideLayer,
rasterLayer: rasterLayer
};
};
@ -63,6 +80,11 @@ const hideGuideLayers = function () {
const showGuideLayers = function (guideLayers) {
const backgroundGuideLayer = guideLayers.backgroundGuideLayer;
const guideLayer = guideLayers.guideLayer;
const rasterLayer = guideLayers.rasterLayer;
if (rasterLayer && !rasterLayer.index) {
paper.project.addLayer(rasterLayer);
rasterLayer.sendToBack();
}
if (!backgroundGuideLayer.index) {
paper.project.addLayer(backgroundGuideLayer);
backgroundGuideLayer.sendToBack();
@ -77,12 +99,6 @@ const showGuideLayers = function (guideLayers) {
}
};
const _makeGuideLayer = function () {
const guideLayer = new paper.Layer();
guideLayer.data.isGuideLayer = true;
return guideLayer;
};
const _makePaintingLayer = function () {
const paintingLayer = new paper.Layer();
paintingLayer.data.isPaintingLayer = true;

View file

@ -54,7 +54,7 @@ class BoundingBoxTool {
* @param {Array<paper.Item>} selectedItems Array of selected items.
*/
onSelectionChanged (selectedItems) {
if (selectedItems) {
if (selectedItems && selectedItems.length) {
this.setSelectionBounds();
} else {
this.removeBoundsPath();

View file

@ -1,7 +1,7 @@
// undo functionality
// modifed from https://github.com/memononen/stylii
import paper from '@scratch/paper';
import {hideGuideLayers, showGuideLayers} from '../helper/layer';
import {hideGuideLayers, showGuideLayers, getRaster} from '../helper/layer';
const performSnapshot = function (dispatchPerformSnapshot) {
const guideLayers = hideGuideLayers();
@ -12,7 +12,8 @@ const performSnapshot = function (dispatchPerformSnapshot) {
};
const _restore = function (entry, setSelectedItems, onUpdateSvg) {
for (const layer of paper.project.layers) {
for (let i = paper.project.layers.length - 1; i >= 0; i--) {
const layer = paper.project.layers[i];
if (!layer.data.isBackgroundGuideLayer) {
layer.removeChildren();
layer.remove();
@ -21,7 +22,12 @@ const _restore = function (entry, setSelectedItems, onUpdateSvg) {
paper.project.importJSON(entry.json);
setSelectedItems();
onUpdateSvg(true /* skipSnapshot */);
getRaster().onLoad = function () {
onUpdateSvg(true /* skipSnapshot */);
};
if (getRaster().loaded) {
getRaster().onLoad();
}
};
const performUndo = function (undoState, dispatchPerformUndo, setSelectedItems, onUpdateSvg) {