mirror of
https://github.com/scratchfoundation/scratch-paint.git
synced 2024-12-22 21:42:30 -05:00
Get undo/redo working
This commit is contained in:
parent
15053d15f0
commit
6e4ab3191a
5 changed files with 60 additions and 21 deletions
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue