diff --git a/css/style.css b/css/style.css
index 41b51856..9889c932 100644
--- a/css/style.css
+++ b/css/style.css
@@ -154,6 +154,10 @@ ul, li {
cursor: url(../img/tools/cursors/pen.png) 5 21, pointer;
}
+.tool-rectangle .drawing-canvas-container:hover {
+ cursor: url(../img/tools/cursors/rectangle.png) 4 21, pointer;
+}
+
/**
* Tool section:
@@ -211,6 +215,7 @@ ul, li {
width: 30px;
height: 30px;
border: 5px solid #fff;
+ background-color: #fff
}
.tool-icon:hover {
@@ -243,6 +248,10 @@ ul, li {
background: #fff url(../img/tools/icons/stroke.png) 3px 3px no-repeat;
}
+.tool-icon.tool-rectangle {
+ background: #fff url(../img/tools/icons/rectangle.png) 3px 3px no-repeat;
+}
+
#preview-fps {
width : 200px;
}
diff --git a/img/tools/cursors/rectangle.png b/img/tools/cursors/rectangle.png
new file mode 100644
index 00000000..712daccf
Binary files /dev/null and b/img/tools/cursors/rectangle.png differ
diff --git a/img/tools/icons/rectangle.png b/img/tools/icons/rectangle.png
new file mode 100644
index 00000000..8a148f6d
Binary files /dev/null and b/img/tools/icons/rectangle.png differ
diff --git a/index.html b/index.html
index 5eade9ee..648a11ba 100644
--- a/index.html
+++ b/index.html
@@ -38,6 +38,7 @@
+
@@ -80,6 +81,7 @@
+
diff --git a/js/ToolSelector.js b/js/ToolSelector.js
index 05329808..11d47765 100644
--- a/js/ToolSelector.js
+++ b/js/ToolSelector.js
@@ -12,7 +12,8 @@ pskl.ToolSelector = (function() {
"simplePen" : new pskl.drawingtools.SimplePen(),
"eraser" : new pskl.drawingtools.Eraser(),
"paintBucket" : new pskl.drawingtools.PaintBucket(),
- "stroke" : new pskl.drawingtools.Stroke()
+ "stroke" : new pskl.drawingtools.Stroke(),
+ "rectangle" : new pskl.drawingtools.Rectangle()
};
var currentSelectedTool = toolInstances.simplePen;
var previousSelectedTool = toolInstances.simplePen;
diff --git a/js/drawingtools/Rectangle.js b/js/drawingtools/Rectangle.js
new file mode 100644
index 00000000..d139ee04
--- /dev/null
+++ b/js/drawingtools/Rectangle.js
@@ -0,0 +1,125 @@
+/*
+ * @provide pskl.drawingtools.Rectangle
+ *
+ * @require pskl.utils
+ */
+(function() {
+ var ns = $.namespace("pskl.drawingtools");
+
+ ns.Rectangle = function() {
+ this.toolId = "tool-rectangle"
+
+ // Rectangle's first point coordinates (set in applyToolAt)
+ this.startCol = null;
+ this.startRow = null;
+ // Rectangle's second point coordinates (changing dynamically in moveToolAt)
+ this.endCol = null;
+ this.endRow = null;
+
+ this.canvasOverlay = null;
+ };
+
+ pskl.utils.inherit(ns.Rectangle, ns.BaseTool);
+
+ /**
+ * @override
+ */
+ ns.Rectangle.prototype.applyToolAt = function(col, row, frame, color, canvas, dpi) {
+ this.startCol = col;
+ this.startRow = row;
+
+ // The fake canvas where we will draw the preview of the rectangle:
+ this.canvasOverlay = this.createCanvasOverlay(canvas);
+ // Drawing the first point of the rectangle in the fake overlay canvas:
+ this.drawPixelInCanvas(col, row, this.canvasOverlay, color, dpi);
+ };
+
+ ns.Rectangle.prototype.moveToolAt = function(col, row, frame, color, canvas, dpi) {
+ this.endCol = col;
+ this.endRow = row;
+ // When the user moussemove (before releasing), we dynamically compute the
+ // pixel to draw the line and draw this line in the overlay canvas:
+ var strokePoints = this.getRectanglePixels_(this.startCol, this.endCol, this.startRow, this.endRow);
+
+ // Clean overlay canvas:
+ this.canvasOverlay.getContext("2d").clearRect(
+ 0, 0, this.canvasOverlay.width, this.canvasOverlay.height);
+
+ // Drawing current stroke:
+ for(var i = 0; i< strokePoints.length; i++) {
+
+ if(color == Constants.TRANSPARENT_COLOR) {
+ color = "rgba(255, 255, 255, 0.6)";
+ }
+ this.drawPixelInCanvas(strokePoints[i].col, strokePoints[i].row, this.canvasOverlay, color, dpi);
+ }
+ };
+
+ /**
+ * @override
+ */
+ ns.Rectangle.prototype.releaseToolAt = function(col, row, frame, color, canvas, dpi) {
+ this.endCol = col;
+ this.endRow = row;
+
+ // If the stroke tool is released outside of the canvas, we cancel the stroke:
+ // TODO: Mutualize this check in common method
+ if(col < 0 || row < 0 || col > frame.length || row > frame[0].length) {
+ this.removeCanvasOverlays();
+ return;
+ }
+
+ // The user released the tool to draw a line. We will compute the pixel coordinate, impact
+ // the model and draw them in the drawing canvas (not the fake overlay anymore)
+ var strokePoints = this.getRectanglePixels_(this.startCol, this.endCol, this.startRow, this.endRow);
+
+ for(var i = 0; i< strokePoints.length; i++) {
+ // Change model:
+ frame[strokePoints[i].col][strokePoints[i].row] = color;
+
+ // Draw in canvas:
+ // TODO: Remove that when we have the centralized redraw loop
+ this.drawPixelInCanvas(strokePoints[i].col, strokePoints[i].row, canvas, color, dpi);
+ }
+
+ // For now, we are done with the stroke tool and don't need an overlay anymore:
+ this.removeCanvasOverlays();
+ };
+
+ /**
+ * Get an array of pixels representing the rectangle.
+ *
+ * @private
+ */
+ ns.Rectangle.prototype.getRectanglePixels_ = function(x0, x1, y0, y1) {
+
+ var pixels = [];
+ var swap;
+
+ if(x0 > x1) {
+ swap = x0;
+ x0 = x1;
+ x1 = swap;
+ }
+ if(y0 > y1) {
+ swap = y0;
+ y0 = y1;
+ y1 = swap;
+ }
+
+ // Creating horizontal sides of the rectangle:
+ for(var x = x0; x <= x1; x++) {
+ pixels.push({"col": x, "row": y0});
+ pixels.push({"col": x, "row": y1});
+ }
+
+ // Creating vertical sides of the rectangle:
+ for(var y = y0; y <= y1; y++) {
+ pixels.push({"col": x0, "row": y});
+ pixels.push({"col": x1, "row": y});
+ }
+
+ return pixels;
+ };
+
+})();
diff --git a/js/drawingtools/Stroke.js b/js/drawingtools/Stroke.js
index ca4cdc4b..aa58592f 100644
--- a/js/drawingtools/Stroke.js
+++ b/js/drawingtools/Stroke.js
@@ -1,5 +1,5 @@
/*
- * @provide pskl.drawingtools.SimplePen
+ * @provide pskl.drawingtools.Stroke
*
* @require pskl.utils
*/
@@ -75,7 +75,8 @@
this.endCol = col;
this.endRow = row;
- // If the stroke tool is released outside of the canvas, we cancel the stroke:
+ // If the stroke tool is released outside of the canvas, we cancel the stroke:
+ // TODO: Mutualize this check in common method
if(col < 0 || row < 0 || col > frame.length || row > frame[0].length) {
this.removeCanvasOverlays();
return;