mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
Feature : Hold shift to preserve shape ratio
- mutualized shape tools common code in a ShapeTool class - when holding shift and drawing a frame, the ratio is preserved - selection and shape tools now support the mouse to leave the drawing area - shape tools can go 'outside' the drawing canvas - Frame set/getPixel now check the pixel is in range instead of crashing
This commit is contained in:
parent
7357614d9a
commit
c9251229fc
|
@ -40,7 +40,7 @@
|
|||
-moz-box-sizing : border-box;
|
||||
|
||||
border-radius: 3px;
|
||||
background: rgba(0,0,0,0.9);
|
||||
background: rgba(0,0,0,1);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@
|
|||
* @private
|
||||
*/
|
||||
ns.DrawingController.prototype.onMouseenter_ = function (event) {
|
||||
this.container.bind('mousemove', $.proxy(this.onMousemove_, this));
|
||||
$('body').bind('mousemove', $.proxy(this.onMousemove_, this));
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,49 +7,15 @@
|
|||
var ns = $.namespace("pskl.drawingtools");
|
||||
|
||||
ns.Circle = function() {
|
||||
ns.ShapeTool.call(this);
|
||||
|
||||
this.toolId = "tool-circle";
|
||||
this.helpText = "Circle tool";
|
||||
|
||||
// Circle's first point coordinates (set in applyToolAt)
|
||||
this.startCol = null;
|
||||
this.startRow = null;
|
||||
};
|
||||
|
||||
pskl.utils.inherit(ns.Circle, ns.BaseTool);
|
||||
pskl.utils.inherit(ns.Circle, ns.ShapeTool);
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
ns.Circle.prototype.applyToolAt = function(col, row, color, frame, overlay, event) {
|
||||
this.startCol = col;
|
||||
this.startRow = row;
|
||||
|
||||
// Drawing the first point of the rectangle in the fake overlay canvas:
|
||||
overlay.setPixel(col, row, color);
|
||||
};
|
||||
|
||||
ns.Circle.prototype.moveToolAt = function(col, row, color, frame, overlay, event) {
|
||||
overlay.clear();
|
||||
if(color == Constants.TRANSPARENT_COLOR) {
|
||||
color = Constants.SELECTION_TRANSPARENT_COLOR;
|
||||
}
|
||||
|
||||
// draw in overlay
|
||||
this.drawCircle_(col, row, color, overlay);
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
ns.Circle.prototype.releaseToolAt = function(col, row, color, frame, overlay, event) {
|
||||
overlay.clear();
|
||||
if(frame.containsPixel(col, row)) { // cancel if outside of canvas
|
||||
// draw in frame to finalize
|
||||
this.drawCircle_(col, row, color, frame);
|
||||
}
|
||||
};
|
||||
|
||||
ns.Circle.prototype.drawCircle_ = function (col, row, color, targetFrame) {
|
||||
ns.Circle.prototype.draw_ = function (col, row, color, targetFrame) {
|
||||
var circlePoints = this.getCirclePixels_(this.startCol, this.startRow, col, row);
|
||||
for(var i = 0; i< circlePoints.length; i++) {
|
||||
// Change model:
|
||||
|
|
|
@ -7,49 +7,15 @@
|
|||
var ns = $.namespace("pskl.drawingtools");
|
||||
|
||||
ns.Rectangle = function() {
|
||||
ns.ShapeTool.call(this);
|
||||
|
||||
this.toolId = "tool-rectangle";
|
||||
this.helpText = "Rectangle tool";
|
||||
|
||||
// Rectangle's first point coordinates (set in applyToolAt)
|
||||
this.startCol = null;
|
||||
this.startRow = null;
|
||||
};
|
||||
|
||||
pskl.utils.inherit(ns.Rectangle, ns.BaseTool);
|
||||
pskl.utils.inherit(ns.Rectangle, ns.ShapeTool);
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
ns.Rectangle.prototype.applyToolAt = function(col, row, color, frame, overlay, event) {
|
||||
this.startCol = col;
|
||||
this.startRow = row;
|
||||
|
||||
// Drawing the first point of the rectangle in the fake overlay canvas:
|
||||
overlay.setPixel(col, row, color);
|
||||
};
|
||||
|
||||
ns.Rectangle.prototype.moveToolAt = function(col, row, color, frame, overlay, event) {
|
||||
overlay.clear();
|
||||
if(color == Constants.TRANSPARENT_COLOR) {
|
||||
color = Constants.SELECTION_TRANSPARENT_COLOR;
|
||||
}
|
||||
|
||||
// draw in overlay
|
||||
this.drawRectangle_(col, row, color, overlay);
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
ns.Rectangle.prototype.releaseToolAt = function(col, row, color, frame, overlay, event) {
|
||||
overlay.clear();
|
||||
if(frame.containsPixel(col, row)) { // cancel if outside of canvas
|
||||
// draw in frame to finalize
|
||||
this.drawRectangle_(col, row, color, frame);
|
||||
}
|
||||
};
|
||||
|
||||
ns.Rectangle.prototype.drawRectangle_ = function (col, row, color, targetFrame) {
|
||||
ns.Rectangle.prototype.draw_ = function (col, row, color, targetFrame) {
|
||||
var strokePoints = pskl.PixelUtils.getBoundRectanglePixels(this.startCol, this.startRow, col, row);
|
||||
for(var i = 0; i< strokePoints.length; i++) {
|
||||
// Change model:
|
||||
|
|
89
src/js/drawingtools/ShapeTool.js
Normal file
89
src/js/drawingtools/ShapeTool.js
Normal file
|
@ -0,0 +1,89 @@
|
|||
(function () {
|
||||
var ns = $.namespace('pskl.drawingtools');
|
||||
/**
|
||||
* Abstract shape tool class, parent to all shape tools (rectangle, circle).
|
||||
* Shape tools should override only the draw_ method
|
||||
*/
|
||||
ns.ShapeTool = function() {
|
||||
// Shapes's first point coordinates (set in applyToolAt)
|
||||
this.startCol = null;
|
||||
this.startRow = null;
|
||||
};
|
||||
|
||||
pskl.utils.inherit(ns.ShapeTool, ns.BaseTool);
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
ns.ShapeTool.prototype.applyToolAt = function(col, row, color, frame, overlay, event) {
|
||||
this.startCol = col;
|
||||
this.startRow = row;
|
||||
|
||||
// Drawing the first point of the rectangle in the fake overlay canvas:
|
||||
overlay.setPixel(col, row, color);
|
||||
};
|
||||
|
||||
ns.ShapeTool.prototype.moveToolAt = function(col, row, color, frame, overlay, event) {
|
||||
overlay.clear();
|
||||
if(color == Constants.TRANSPARENT_COLOR) {
|
||||
color = Constants.SELECTION_TRANSPARENT_COLOR;
|
||||
}
|
||||
|
||||
var coords = this.getCoordinates_(col, row, event);
|
||||
// draw in overlay
|
||||
this.draw_(coords.col, coords.row, color, overlay);
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
ns.ShapeTool.prototype.releaseToolAt = function(col, row, color, frame, overlay, event) {
|
||||
overlay.clear();
|
||||
if (event.shiftKey) {
|
||||
var scaled = this.getScaledCoordinates_(col, row);
|
||||
col = scaled.col;
|
||||
row = scaled.row;
|
||||
}
|
||||
var coords = this.getCoordinates_(col, row, event);
|
||||
this.draw_(coords.col, coords.row, color, frame);
|
||||
};
|
||||
|
||||
/**
|
||||
* Transform the current coordinates based on the original event
|
||||
* @param {Number} col current col/x coordinate in the frame
|
||||
* @param {Number} row current row/y coordinate in the frame
|
||||
* @param {Event} event current event (can be mousemove, mouseup ...)
|
||||
* @return {Object} {row : Number, col : Number}
|
||||
*/
|
||||
ns.ShapeTool.prototype.getCoordinates_ = function(col, row, event) {
|
||||
if (event.shiftKey) {
|
||||
return this.getScaledCoordinates_(col, row);
|
||||
} else {
|
||||
return {col : col, row : row};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Transform the coordinates to preserve a square 1:1 ratio from the origin of the shape
|
||||
* @param {Number} col current col/x coordinate in the frame
|
||||
* @param {Number} row current row/y coordinate in the frame
|
||||
* @return {Object} {row : Number, col : Number}
|
||||
*/
|
||||
ns.ShapeTool.prototype.getScaledCoordinates_ = function(col, row) {
|
||||
var sign;
|
||||
if (Math.abs(this.startCol - col) > Math.abs(this.startRow - row)) {
|
||||
sign = row > this.startRow ? 1 : -1;
|
||||
row = this.startRow + (sign * Math.abs(this.startCol - col));
|
||||
} else {
|
||||
sign = col > this.startCol ? 1 : -1;
|
||||
col = this.startCol + (sign * Math.abs(this.startRow - row));
|
||||
}
|
||||
return {
|
||||
col : col,
|
||||
row : row
|
||||
};
|
||||
};
|
||||
|
||||
ns.ShapeTool.prototype.draw_ = Constants.ABSTRACT_FUNCTION;
|
||||
|
||||
})();
|
|
@ -80,7 +80,7 @@
|
|||
* @override
|
||||
*/
|
||||
ns.BaseSelect.prototype.moveUnactiveToolAt = function(col, row, color, frame, overlay, event) {
|
||||
|
||||
if (overlay.containsPixel(col, row)) {
|
||||
if(overlay.getPixel(col, row) != Constants.SELECTION_TRANSPARENT_COLOR) {
|
||||
// We're hovering the selection, show the move tool:
|
||||
this.BodyRoot.addClass(this.toolId);
|
||||
|
@ -90,6 +90,7 @@
|
|||
this.BodyRoot.addClass(this.secondaryToolId);
|
||||
this.BodyRoot.removeClass(this.toolId);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ns.BaseSelect.prototype.hideHighlightedPixel = function() {
|
||||
|
|
|
@ -83,11 +83,17 @@
|
|||
};
|
||||
|
||||
ns.Frame.prototype.setPixel = function (col, row, color) {
|
||||
if (this.containsPixel(col, row)) {
|
||||
this.pixels[col][row] = color;
|
||||
}
|
||||
};
|
||||
|
||||
ns.Frame.prototype.getPixel = function (col, row) {
|
||||
if (this.containsPixel(col, row)) {
|
||||
return this.pixels[col][row];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
ns.Frame.prototype.forEachPixel = function (callback) {
|
||||
|
@ -107,7 +113,7 @@
|
|||
};
|
||||
|
||||
ns.Frame.prototype.containsPixel = function (col, row) {
|
||||
return col >= 0 && row >= 0 && col < this.pixels.length && row < this.pixels[0].length;
|
||||
return col >= 0 && row >= 0 && col < this.width && row < this.height;
|
||||
};
|
||||
|
||||
ns.Frame.prototype.saveState = function () {
|
||||
|
|
|
@ -100,6 +100,7 @@ exports.scripts = [
|
|||
|
||||
// Tools
|
||||
"js/drawingtools/BaseTool.js",
|
||||
"js/drawingtools/ShapeTool.js",
|
||||
"js/drawingtools/SimplePen.js",
|
||||
"js/drawingtools/VerticalMirrorPen.js",
|
||||
"js/drawingtools/Eraser.js",
|
||||
|
|
Loading…
Reference in New Issue
Block a user