Add the background guide layer

This commit is contained in:
DD 2017-10-24 13:21:57 -04:00
parent dacc17d6c4
commit 29a3d74143
7 changed files with 103 additions and 10 deletions

View file

@ -6,7 +6,7 @@ import {changeMode} from '../reducers/modes';
import {undo, redo, undoSnapshot} from '../reducers/undo';
import {clearSelectedItems, setSelectedItems} from '../reducers/selected-items';
import {getGuideLayer} from '../helper/layer';
import {getGuideLayer, getBackgroundGuideLayer} from '../helper/layer';
import {performUndo, performRedo, performSnapshot} from '../helper/undo';
import {bringToFront, sendBackward, sendToBack, bringForward} from '../helper/order';
import {groupSelection, ungroupSelection} from '../helper/group';
@ -41,7 +41,9 @@ class PaintEditor extends React.Component {
handleUpdateSvg (skipSnapshot) {
// Hide guide layer
const guideLayer = getGuideLayer();
const backgroundGuideLayer = getBackgroundGuideLayer();
guideLayer.remove();
backgroundGuideLayer.remove();
const bounds = paper.project.activeLayer.bounds;
this.props.onUpdateSvg(
paper.project.exportSVG({
@ -53,6 +55,8 @@ class PaintEditor extends React.Component {
if (!skipSnapshot) {
performSnapshot(this.props.undoSnapshot);
}
paper.project.addLayer(backgroundGuideLayer);
backgroundGuideLayer.sendToBack();
paper.project.addLayer(guideLayer);
}
handleUndo () {

View file

@ -7,6 +7,7 @@ import paper from '@scratch/paper';
import {performSnapshot} from '../helper/undo';
import {undoSnapshot, clearUndoState} from '../reducers/undo';
import {isGroup, ungroupItems} from '../helper/group';
import {setupLayers} from '../helper/layer';
import styles from './paper-canvas.css';
@ -22,6 +23,8 @@ class PaperCanvas extends React.Component {
paper.setup(this.canvas);
// Don't show handles by default
paper.settings.handleSize = 0;
// Make layers.
setupLayers();
if (this.props.svg) {
this.importSvg(this.props.svg, this.props.rotationCenterX, this.props.rotationCenterY);
} else {
@ -31,7 +34,9 @@ class PaperCanvas extends React.Component {
componentWillReceiveProps (newProps) {
if (this.props.svgId === newProps.svgId) return;
for (const layer of paper.project.layers) {
layer.removeChildren();
if (!layer.data.isBackgroundGuideLayer) {
layer.removeChildren();
}
}
this.props.clearUndo();
if (newProps.svg) {

View file

@ -3,7 +3,7 @@ import log from '../../log/log';
import BroadBrushHelper from './broad-brush-helper';
import SegmentBrushHelper from './segment-brush-helper';
import {MIXED, styleCursorPreview} from '../../helper/style-path';
import {clearSelection} from '../../helper/selection';
import {clearSelection, getItems} from '../../helper/selection';
import {getGuideLayer} from '../../helper/layer';
/**
@ -193,7 +193,7 @@ class Blobbiness {
const blob = this;
// Get all path items to merge with
const paths = paper.project.getItems({
const paths = getItems({
match: function (item) {
return blob.isMergeable(lastPath, item) &&
item.parent instanceof paper.Layer; // don't merge with nested in group
@ -245,7 +245,7 @@ class Blobbiness {
// Get all path items to merge with
// If there are selected items, try to erase from amongst those.
let items = paper.project.getItems({
let items = getItems({
match: function (item) {
return item.selected && blob.isMergeable(lastPath, item) && blob.touches(lastPath, item);
}
@ -254,7 +254,7 @@ class Blobbiness {
// and deselect the selection
if (items.length === 0) {
clearSelection(this.clearSelectedItems);
items = paper.project.getItems({
items = getItems({
match: function (item) {
return blob.isMergeable(lastPath, item) && blob.touches(lastPath, item);
}

View file

@ -15,4 +15,70 @@ const getGuideLayer = function () {
return guideLayer;
};
export {getGuideLayer};
const getBackgroundGuideLayer = function () {
for (let i = 0; i < paper.project.layers.length; i++) {
const layer = paper.project.layers[i];
if (layer.data && layer.data.isBackgroundGuideLayer) {
return layer;
}
}
};
const _makePaintingLayer = function () {
const paintingLayer = new paper.Layer();
paintingLayer.data.isPaintingLayer = true;
return paintingLayer;
};
const _makeBackgroundGuideLayer = function () {
const BLOCK_WIDTH = 4;
const guideLayer = new paper.Layer();
guideLayer.locked = true;
for (let i = 0; i < 500 / BLOCK_WIDTH; i += 2) {
for (let j = 0; j < 400 / BLOCK_WIDTH; j++) {
const rect = new paper.Shape.Rectangle(
new paper.Point((i + (j % 2)) * BLOCK_WIDTH, j * BLOCK_WIDTH),
new paper.Point((i + (j % 2) + 1) * BLOCK_WIDTH, (j + 1) * BLOCK_WIDTH)
);
rect.fillColor = '#E5E5E5';
rect.guide = true;
rect.locked = true;
}
}
const vLine = new paper.Path.Line(new paper.Point(0, -7), new paper.Point(0, 7));
vLine.strokeWidth = 2;
vLine.strokeColor = '#ccc';
vLine.position = paper.view.center;
vLine.guide = true;
vLine.locked = true;
const hLine = new paper.Path.Line(new paper.Point(-7, 0), new paper.Point(7, 0));
hLine.strokeWidth = 2;
hLine.strokeColor = '#ccc';
hLine.position = paper.view.center;
hLine.guide = true;
hLine.locked = true;
const circle = new paper.Shape.Circle(new paper.Point(0, 0), 5);
circle.strokeWidth = 2;
circle.strokeColor = '#ccc';
circle.position = paper.view.center;
circle.guide = true;
circle.locked = true;
guideLayer.data.isBackgroundGuideLayer = true;
guideLayer.sendToBack();
return guideLayer;
};
const setupLayers = function () {
_makeBackgroundGuideLayer();
_makePaintingLayer().activate();
};
export {
getGuideLayer,
getBackgroundGuideLayer,
setupLayers
};

View file

@ -1,4 +1,5 @@
import paper from '@scratch/paper';
import {getItems} from '../selection';
/**
* Tool to handle scaling items by pulling on the handles around the edges of the bounding
@ -55,9 +56,9 @@ class ScaleTool {
const modOrigSize = this.origSize;
// get item to insert below so that scaled items stay in same z position
const items = paper.project.getItems({
const items = getItems({
match: function (item) {
if (item instanceof paper.Layer || item.data.isHelperItem) {
if (item instanceof paper.Layer) {
return false;
}
for (const scaleItem of scaleTool.scaleItems) {

View file

@ -5,6 +5,21 @@ import {getItemsGroup, isGroup} from './group';
import {getRootItem, isCompoundPathItem, isBoundsItem, isPathItem, isPGTextItem} from './item';
import {getItemsCompoundPath, isCompoundPath, isCompoundPathChild} from './compound-path';
/**
* Wrapper for paper.project.getItems that excludes our helper items
* @param {?object} options See paper.js docs for paper.Item.getItems
* @return {Array<paper.Item>} items that match options
*/
const getItems = function (options) {
const newMatcher = function (item) {
return !item.locked &&
!(item.data && item.data.isHelperItem) &&
(!options.match || options.match(item));
};
const newOptions = {...options, match: newMatcher};
return paper.project.getItems(newOptions);
};
/**
* @param {boolean} includeGuides True if guide layer items like the bounding box should
* be included in the returned items.
@ -389,6 +404,7 @@ const shouldShowSelectAll = function () {
};
export {
getItems,
getAllRootItems,
selectAllItems,
selectAllSegments,

View file

@ -1,4 +1,5 @@
import paper from '@scratch/paper';
import {getItems} from './selection';
/**
* @param {paper.Point} point1 point 1
@ -19,7 +20,7 @@ const touching = function (point1, point2, tolerance) {
* tolerance distance of the given point, or null if none exists.
*/
const endPointHit = function (point, tolerance, excludePath) {
const lines = paper.project.getItems({
const lines = getItems({
class: paper.Path
});
// Prefer more recent lines