diff --git a/js-lib/common.js b/js-lib/common.js index e1eeb19..d64d31b 100644 --- a/js-lib/common.js +++ b/js-lib/common.js @@ -92,6 +92,11 @@ ascii.Cell.prototype.isSpecial = function() { return this.getRawValue() == SPECIAL_VALUE; }; +/** @return {boolean} */ +ascii.Cell.prototype.hasScratch = function() { + return this.scratchValue != null; +}; + /** * The context for a cell, i.e. the status of the cells around it. * diff --git a/js-lib/controller.js b/js-lib/controller.js index cd1f75d..5caa8e9 100644 --- a/js-lib/controller.js +++ b/js-lib/controller.js @@ -174,10 +174,10 @@ ascii.Controller.prototype.updateButtons = function(id) { this.drawFunction = new ascii.DrawLine(this.state); } if (id == 'freeform-button') { - this.drawFunction = new ascii.DrawFreeform(this.state, '+'); + this.drawFunction = new ascii.DrawFreeform(this.state, SPECIAL_VALUE); } if (id == 'erase-button') { - this.drawFunction = new ascii.DrawFreeform(this.state, null); + this.drawFunction = new ascii.DrawErase(this.state); } if (id == 'move-button') { this.drawFunction = new ascii.DrawMove(this.state); diff --git a/js-lib/draw.js b/js-lib/draw.js index 2003d4c..16d32ff 100644 --- a/js-lib/draw.js +++ b/js-lib/draw.js @@ -14,23 +14,23 @@ function drawLine(state, startPosition, endPosition, clockwise, opt_value) { var value = opt_value || SPECIAL_VALUE; - var hX1 = Math.min(startPosition.x, endPosition.x); - var vY1 = Math.min(startPosition.y, endPosition.y); - var hX2 = Math.max(startPosition.x, endPosition.x); - var vY2 = Math.max(startPosition.y, endPosition.y); + var startX = Math.min(startPosition.x, endPosition.x); + var startY = Math.min(startPosition.y, endPosition.y); + var endX = Math.max(startPosition.x, endPosition.x); + var endY = Math.max(startPosition.y, endPosition.y); - var hY = clockwise ? startPosition.y : endPosition.y; - var vX = clockwise ? endPosition.x : startPosition.x; + var midX = clockwise ? endPosition.x : startPosition.x; + var midY = clockwise ? startPosition.y : endPosition.y; - while (hX1++ < hX2) { - state.drawValue(new ascii.Vector(hX1, hY), value); + while (startX++ < endX) { + state.drawValue(new ascii.Vector(startX, midY), value); } - while (vY1++ < vY2) { - state.drawValue(new ascii.Vector(vX, vY1), value); + while (startY++ < endY) { + state.drawValue(new ascii.Vector(midX, startY), value); } state.drawValue(startPosition, value); state.drawValue(endPosition, value); - state.drawValue(new ascii.Vector(vX, hY), value); + state.drawValue(new ascii.Vector(midX, midY), value); } /** @@ -120,17 +120,55 @@ ascii.DrawFreeform = function(state, value) { }; ascii.DrawFreeform.prototype.start = function(position) { - this.state.setValue(position, this.value); + this.state.drawValue(position, this.value); }; ascii.DrawFreeform.prototype.move = function(position) { - this.state.setValue(position, this.value); + this.state.drawValue(position, this.value); }; ascii.DrawFreeform.prototype.end = function(position) { + this.state.commitDraw(); }; ascii.DrawFreeform.prototype.getCursor = function(position) { return 'crosshair'; }; +/** + * @constructor + * @implements {ascii.DrawFunction} + * @param {ascii.State} state + */ +ascii.DrawErase = function(state) { + this.state = state; + this.startPosition = null; + this.endPosition = null; +}; + +ascii.DrawErase.prototype.start = function(position) { + this.startPosition = position; + this.move(position); +}; +ascii.DrawErase.prototype.move = function(position) { + this.state.clearDraw(); + this.endPosition = position; + + var startX = Math.min(this.startPosition.x, this.endPosition.x); + var startY = Math.min(this.startPosition.y, this.endPosition.y); + var endX = Math.max(this.startPosition.x, this.endPosition.x); + var endY = Math.max(this.startPosition.y, this.endPosition.y); + + for (var i = startX; i < endX; i++) { + for (var j = startY; j < endY; j++) { + this.state.drawValue(new ascii.Vector(i, j), ' '); + } + } +}; +ascii.DrawErase.prototype.end = function(position) { + this.state.commitDraw(); +}; +ascii.DrawErase.prototype.getCursor = function(position) { + return 'crosshair'; +}; + /** * @constructor * @implements {ascii.DrawFunction} diff --git a/js-lib/state.js b/js-lib/state.js index c49fd91..e605df4 100644 --- a/js-lib/state.js +++ b/js-lib/state.js @@ -106,8 +106,13 @@ ascii.State.prototype.getContext = function(position) { */ ascii.State.prototype.commitDraw = function() { for (var i in this.scratchCells) { - this.scratchCells[i].value = this.scratchCells[i].getRawValue(); + var newValue = this.scratchCells[i].getRawValue(); + // Cheeky little hack for making erase play nicely. + if (newValue == ' ') { + newValue = null; + } this.scratchCells[i].scratchValue = null; + this.scratchCells[i].value = newValue; } }; diff --git a/js-lib/view.js b/js-lib/view.js index 31ef383..34c4d81 100644 --- a/js-lib/view.js +++ b/js-lib/view.js @@ -89,8 +89,9 @@ ascii.View.prototype.render = function() { this.context.font = '15px Courier New'; for (var i = startOffset.x; i < endOffset.x; i++) { for (var j = startOffset.y; j < endOffset.y; j++) { - if (this.state.getCell(new ascii.Vector(i, j)).isSpecial()) { - this.context.fillStyle = '#F5F5F5'; + var cell = this.state.getCell(new ascii.Vector(i, j)); + if (cell.hasScratch() || cell.isSpecial()) { + this.context.fillStyle = cell.hasScratch() ? '#DEF' : '#F5F5F5'; context.fillRect( i * CHARACTER_PIXELS - this.offset.x, (j - 1) * CHARACTER_PIXELS - this.offset.y,