mirror of
https://github.com/scratchfoundation/scratch-paint.git
synced 2024-12-22 13:32:28 -05:00
fix cursor preview
This commit is contained in:
parent
02730cbd58
commit
f139bfada0
4 changed files with 67 additions and 68 deletions
|
@ -44,13 +44,13 @@ class BrushTool extends React.Component {
|
||||||
this.tool = new paper.Tool();
|
this.tool = new paper.Tool();
|
||||||
this.blob.activateTool(false /* isEraser */, this.tool, this.props.brushToolState);
|
this.blob.activateTool(false /* isEraser */, this.tool, this.props.brushToolState);
|
||||||
|
|
||||||
// // Make sure a fill color is set on the brush
|
// TODO Make sure a fill color is set on the brush
|
||||||
// if(!pg.stylebar.getFillColor()) {
|
// if(!pg.stylebar.getFillColor()) {
|
||||||
// pg.stylebar.setFillColor(pg.stylebar.getStrokeColor());
|
// pg.stylebar.setFillColor(pg.stylebar.getStrokeColor());
|
||||||
// pg.stylebar.setStrokeColor(null);
|
// pg.stylebar.setStrokeColor(null);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// // setup floating tool options panel in the editor
|
// TODO setup floating tool options panel in the editor
|
||||||
// pg.toolOptionPanel.setup(options, components, function() {});
|
// pg.toolOptionPanel.setup(options, components, function() {});
|
||||||
|
|
||||||
this.tool.activate();
|
this.tool.activate();
|
||||||
|
@ -58,7 +58,6 @@ class BrushTool extends React.Component {
|
||||||
deactivateTool () {
|
deactivateTool () {
|
||||||
document.getElementById(this.props.canvasId)
|
document.getElementById(this.props.canvasId)
|
||||||
.removeEventListener('mousewheel', this.onScroll);
|
.removeEventListener('mousewheel', this.onScroll);
|
||||||
this.blob.deactivateTool();
|
|
||||||
}
|
}
|
||||||
onScroll (event) {
|
onScroll (event) {
|
||||||
if (event.deltaY < 0) {
|
if (event.deltaY < 0) {
|
||||||
|
|
|
@ -43,24 +43,12 @@ class EraserTool extends React.Component {
|
||||||
|
|
||||||
this.tool = new paper.Tool();
|
this.tool = new paper.Tool();
|
||||||
this.blob.activateTool(true /* isEraser */, this.tool, this.props.eraserToolState);
|
this.blob.activateTool(true /* isEraser */, this.tool, this.props.eraserToolState);
|
||||||
|
|
||||||
// // Make sure a fill color is set on the brush
|
|
||||||
// if(!pg.stylebar.getFillColor()) {
|
|
||||||
// pg.stylebar.setFillColor(pg.stylebar.getStrokeColor());
|
|
||||||
// pg.stylebar.setStrokeColor(null);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // setup floating tool options panel in the editor
|
|
||||||
// pg.toolOptionPanel.setup(options, components, function() {});
|
|
||||||
// get options from local storage if presentz
|
|
||||||
|
|
||||||
this.tool.activate();
|
this.tool.activate();
|
||||||
}
|
}
|
||||||
deactivateTool () {
|
deactivateTool () {
|
||||||
document.getElementById(this.props.canvasId)
|
document.getElementById(this.props.canvasId)
|
||||||
.removeEventListener('mousewheel', this.onScroll);
|
.removeEventListener('mousewheel', this.onScroll);
|
||||||
this.blob.deactivateTool();
|
this.blob.deactivateTool();
|
||||||
this.tool.remove();
|
|
||||||
}
|
}
|
||||||
onScroll (event) {
|
onScroll (event) {
|
||||||
if (event.deltaY < 0) {
|
if (event.deltaY < 0) {
|
||||||
|
@ -89,7 +77,7 @@ EraserTool.propTypes = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
eraserToolState: state.brushTool,
|
eraserToolState: state.eraserTool,
|
||||||
tool: state.tool
|
tool: state.tool
|
||||||
});
|
});
|
||||||
const mapDispatchToProps = dispatch => ({
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
|
|
@ -19,31 +19,45 @@ class BlobTool {
|
||||||
}
|
}
|
||||||
|
|
||||||
setOptions (options) {
|
setOptions (options) {
|
||||||
console.log('setOptions');
|
if (this.tool) {
|
||||||
this.options = options;
|
this.tool.options = options;
|
||||||
if (this.cursorPreview) {
|
this.tool.resizeCursorIfNeeded();
|
||||||
this.cursorPreview = new paper.Path.Circle({
|
|
||||||
center: [this.cursorPreview.center.x, this.cursorPreview.center.y],
|
|
||||||
radius: options.brushSize / 2
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
activateTool (isEraser, tool, options) {
|
activateTool (isEraser, tool, options) {
|
||||||
console.log('activateTool isEraser?'+isEraser);
|
|
||||||
this.tool = tool;
|
this.tool = tool;
|
||||||
this.options = options;
|
|
||||||
|
tool.cursorPreviewLastPoint = new paper.Point(-10000, -10000);
|
||||||
let cursorPreview = this.cursorPreview = new paper.Path.Circle({
|
tool.resizeCursorIfNeeded = function (point) {
|
||||||
center: [-10000, -10000],
|
if (typeof point === 'undefined') {
|
||||||
radius: options.brushSize / 2
|
point = this.cursorPreviewLastPoint;
|
||||||
});
|
} else {
|
||||||
this.brushSize = options.brushSize;
|
this.cursorPreviewLastPoint = point;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.brushSize === this.options.brushSize) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const newPreview = new paper.Path.Circle({
|
||||||
|
center: point,
|
||||||
|
radius: this.options.brushSize / 2
|
||||||
|
});
|
||||||
|
if (this.cursorPreview) {
|
||||||
|
this.cursorPreview.segments = newPreview.segments;
|
||||||
|
newPreview.remove();
|
||||||
|
} else {
|
||||||
|
this.cursorPreview = newPreview;
|
||||||
|
}
|
||||||
|
this.brushSize = this.options.brushSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.setOptions(options);
|
||||||
|
|
||||||
tool.stylePath = function (path) {
|
tool.stylePath = function (path) {
|
||||||
if (isEraser) {
|
if (isEraser) {
|
||||||
path.fillColor = 'white';
|
path.fillColor = 'white';
|
||||||
if (path === cursorPreview) {
|
if (path === this.cursorPreview) {
|
||||||
path.strokeColor = 'cornflowerblue';
|
path.strokeColor = 'cornflowerblue';
|
||||||
path.strokeWidth = 1;
|
path.strokeWidth = 1;
|
||||||
}
|
}
|
||||||
|
@ -54,50 +68,46 @@ class BlobTool {
|
||||||
//TODO FIX
|
//TODO FIX
|
||||||
|
|
||||||
path.fillColor = 'black';
|
path.fillColor = 'black';
|
||||||
if (path === cursorPreview) {
|
if (path === this.cursorPreview) {
|
||||||
path.strokeColor = 'cornflowerblue';
|
path.strokeColor = 'cornflowerblue';
|
||||||
path.strokeWidth = 1;
|
path.strokeWidth = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
tool.stylePath(cursorPreview);
|
tool.stylePath(this.tool.cursorPreview);
|
||||||
|
|
||||||
tool.fixedDistance = 1;
|
tool.fixedDistance = 1;
|
||||||
|
|
||||||
broadBrushHelper(tool, options);
|
broadBrushHelper(tool);
|
||||||
// TODO add
|
// TODO add
|
||||||
//pg.segmentbrushhelper(tool, options);
|
//pg.segmentbrushhelper(tool, options);
|
||||||
|
|
||||||
tool.onMouseMove = function (event) {
|
tool.onMouseMove = function (event) {
|
||||||
if (this.brushSize !== options.brushSize) {
|
tool.resizeCursorIfNeeded(event.point);
|
||||||
cursorPreview.remove();
|
tool.stylePath(this.cursorPreview);
|
||||||
cursorPreview = new paper.Path.Circle({
|
this.cursorPreview.bringToFront();
|
||||||
center: event.point,
|
this.cursorPreview.position = event.point;
|
||||||
radius: options.brushSize / 2
|
|
||||||
});
|
|
||||||
this.brushSize = options.brushSize;
|
|
||||||
}
|
|
||||||
tool.stylePath(cursorPreview);
|
|
||||||
cursorPreview.bringToFront();
|
|
||||||
cursorPreview.position = event.point;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
tool.onMouseDown = function (event) {
|
tool.onMouseDown = function (event) {
|
||||||
|
tool.resizeCursorIfNeeded(event.point);
|
||||||
if (event.event.button > 0) return; // only first mouse button
|
if (event.event.button > 0) return; // only first mouse button
|
||||||
|
|
||||||
if (options.brushSize < BlobTool.THRESHOLD) {
|
if (this.options.brushSize < BlobTool.THRESHOLD) {
|
||||||
this.brush = BlobTool.BROAD;
|
this.brush = BlobTool.BROAD;
|
||||||
this.onBroadMouseDown(event);
|
this.onBroadMouseDown(event);
|
||||||
} else {
|
} else {
|
||||||
this.brush = BlobTool.SEGMENT;
|
this.brush = BlobTool.SEGMENT;
|
||||||
this.onSegmentMouseDown(event);
|
this.onSegmentMouseDown(event);
|
||||||
}
|
}
|
||||||
cursorPreview.bringToFront();
|
this.cursorPreview.bringToFront();
|
||||||
cursorPreview.position = event.point;
|
this.cursorPreview.position = event.point;
|
||||||
paper.view.draw();
|
paper.view.draw();
|
||||||
};
|
};
|
||||||
|
|
||||||
tool.onMouseDrag = function (event) {
|
tool.onMouseDrag = function (event) {
|
||||||
|
tool.resizeCursorIfNeeded(event.point);
|
||||||
if (event.event.button > 0) return; // only first mouse button
|
if (event.event.button > 0) return; // only first mouse button
|
||||||
if (this.brush === BlobTool.BROAD) {
|
if (this.brush === BlobTool.BROAD) {
|
||||||
this.onBroadMouseDrag(event);
|
this.onBroadMouseDrag(event);
|
||||||
|
@ -107,12 +117,13 @@ class BlobTool {
|
||||||
log.warning(`Brush type does not exist: ${this.brush}`);
|
log.warning(`Brush type does not exist: ${this.brush}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
cursorPreview.bringToFront();
|
this.cursorPreview.bringToFront();
|
||||||
cursorPreview.position = event.point;
|
this.cursorPreview.position = event.point;
|
||||||
paper.view.draw();
|
paper.view.draw();
|
||||||
};
|
};
|
||||||
|
|
||||||
tool.onMouseUp = function (event) {
|
tool.onMouseUp = function (event) {
|
||||||
|
tool.resizeCursorIfNeeded(event.point);
|
||||||
if (event.event.button > 0) return; // only first mouse button
|
if (event.event.button > 0) return; // only first mouse button
|
||||||
|
|
||||||
let lastPath;
|
let lastPath;
|
||||||
|
@ -130,8 +141,8 @@ class BlobTool {
|
||||||
tool.mergeBrush(lastPath);
|
tool.mergeBrush(lastPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
cursorPreview.bringToFront();
|
this.cursorPreview.bringToFront();
|
||||||
cursorPreview.position = event.point;
|
this.cursorPreview.position = event.point;
|
||||||
|
|
||||||
// Reset
|
// Reset
|
||||||
this.brush = null;
|
this.brush = null;
|
||||||
|
@ -214,7 +225,8 @@ class BlobTool {
|
||||||
|
|
||||||
// Gather path segments
|
// Gather path segments
|
||||||
const subpaths = [];
|
const subpaths = [];
|
||||||
if (items[i] instanceof paper.PathItem && !items[i].closed) {
|
// TODO handle compound path
|
||||||
|
if (items[i] instanceof paper.Path && !items[i].closed) {
|
||||||
const firstSeg = items[i].clone();
|
const firstSeg = items[i].clone();
|
||||||
const intersections = firstSeg.getIntersections(lastPath);
|
const intersections = firstSeg.getIntersections(lastPath);
|
||||||
// keep first and last segments
|
// keep first and last segments
|
||||||
|
@ -312,15 +324,17 @@ class BlobTool {
|
||||||
|
|
||||||
tool.isMergeable = function (newPath, existingPath) {
|
tool.isMergeable = function (newPath, existingPath) {
|
||||||
return existingPath instanceof paper.PathItem && // path or compound path
|
return existingPath instanceof paper.PathItem && // path or compound path
|
||||||
existingPath !== cursorPreview && // don't merge with the mouse preview
|
existingPath !== this.cursorPreview && // don't merge with the mouse preview
|
||||||
existingPath !== newPath && // don't merge with self
|
existingPath !== newPath && // don't merge with self
|
||||||
existingPath.parent instanceof paper.Layer; // don't merge with nested in group
|
existingPath.parent instanceof paper.Layer; // don't merge with nested in group
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
deactivateTool () {
|
deactivateTool () {
|
||||||
console.log('deactivateTool');
|
if (this.tool) {
|
||||||
this.cursorPreview.remove();
|
this.tool.cursorPreview.remove();
|
||||||
|
this.tool.remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,17 +4,15 @@ const paper = require('paper');
|
||||||
/**
|
/**
|
||||||
* Applies segment brush functions to the tool.
|
* Applies segment brush functions to the tool.
|
||||||
* @param {!Tool} tool paper.js mouse object
|
* @param {!Tool} tool paper.js mouse object
|
||||||
* @param {!options} options brush tool state object
|
|
||||||
* @param {!options.brushSize} brush tool diameter
|
|
||||||
*/
|
*/
|
||||||
const broadBrushHelper = function (tool, options) {
|
const broadBrushHelper = function (tool) {
|
||||||
let lastPoint;
|
let lastPoint;
|
||||||
let secondLastPoint;
|
let secondLastPoint;
|
||||||
let finalPath;
|
let finalPath;
|
||||||
|
|
||||||
tool.onBroadMouseDown = function (event) {
|
tool.onBroadMouseDown = function (event) {
|
||||||
tool.minDistance = options.brushSize / 4;
|
tool.minDistance = this.options.brushSize / 4;
|
||||||
tool.maxDistance = options.brushSize;
|
tool.maxDistance = this.options.brushSize;
|
||||||
if (event.event.button > 0) return; // only first mouse button
|
if (event.event.button > 0) return; // only first mouse button
|
||||||
|
|
||||||
finalPath = new paper.Path();
|
finalPath = new paper.Path();
|
||||||
|
@ -24,14 +22,14 @@ const broadBrushHelper = function (tool, options) {
|
||||||
};
|
};
|
||||||
|
|
||||||
tool.onBroadMouseDrag = function (event) {
|
tool.onBroadMouseDrag = function (event) {
|
||||||
const step = (event.delta).normalize(options.brushSize / 2);
|
const step = (event.delta).normalize(this.options.brushSize / 2);
|
||||||
|
|
||||||
// Move the first point out away from the drag so that the end of the path is rounded
|
// Move the first point out away from the drag so that the end of the path is rounded
|
||||||
if (finalPath.segments && finalPath.segments.length === 1) {
|
if (finalPath.segments && finalPath.segments.length === 1) {
|
||||||
const removedPoint = finalPath.removeSegment(0).point;
|
const removedPoint = finalPath.removeSegment(0).point;
|
||||||
// Add handles to round the end caps
|
// Add handles to round the end caps
|
||||||
const handleVec = step.clone();
|
const handleVec = step.clone();
|
||||||
handleVec.length = options.brushSize / 2;
|
handleVec.length = this.options.brushSize / 2;
|
||||||
handleVec.angle += 90;
|
handleVec.angle += 90;
|
||||||
finalPath.add(new paper.Segment(removedPoint.subtract(step), -handleVec, handleVec));
|
finalPath.add(new paper.Segment(removedPoint.subtract(step), -handleVec, handleVec));
|
||||||
}
|
}
|
||||||
|
@ -50,7 +48,7 @@ const broadBrushHelper = function (tool, options) {
|
||||||
if (finalPath.segments.length === 5) {
|
if (finalPath.segments.length === 5) {
|
||||||
// Flatten is necessary to prevent smooth from getting rid of the effect
|
// Flatten is necessary to prevent smooth from getting rid of the effect
|
||||||
// of the handles on the first point.
|
// of the handles on the first point.
|
||||||
finalPath.flatten(options.brushSize / 5);
|
finalPath.flatten(this.options.brushSize / 5);
|
||||||
}
|
}
|
||||||
finalPath.smooth();
|
finalPath.smooth();
|
||||||
lastPoint = event.point;
|
lastPoint = event.point;
|
||||||
|
@ -68,14 +66,14 @@ const broadBrushHelper = function (tool, options) {
|
||||||
finalPath.remove();
|
finalPath.remove();
|
||||||
finalPath = new paper.Path.Circle({
|
finalPath = new paper.Path.Circle({
|
||||||
center: event.point,
|
center: event.point,
|
||||||
radius: options.brushSize / 2
|
radius: this.options.brushSize / 2
|
||||||
});
|
});
|
||||||
tool.stylePath(finalPath);
|
tool.stylePath(finalPath);
|
||||||
} else {
|
} else {
|
||||||
const step = (event.point.subtract(lastPoint)).normalize(options.brushSize / 2);
|
const step = (event.point.subtract(lastPoint)).normalize(this.options.brushSize / 2);
|
||||||
step.angle += 90;
|
step.angle += 90;
|
||||||
const handleVec = step.clone();
|
const handleVec = step.clone();
|
||||||
handleVec.length = options.brushSize / 2;
|
handleVec.length = this.options.brushSize / 2;
|
||||||
|
|
||||||
const top = event.point.add(step);
|
const top = event.point.add(step);
|
||||||
const bottom = event.point.subtract(step);
|
const bottom = event.point.subtract(step);
|
||||||
|
|
Loading…
Reference in a new issue