New state model is magical, introduced special character whose value is 'inferred' from it's surroundings. This may be the coolest thing ever.
This commit is contained in:
parent
7d508e2ede
commit
e0b0505332
|
@ -46,19 +46,19 @@ DrawBox.prototype.draw = function() {
|
|||
var x2 = Math.max(this.startPosition.x, this.endPosition.x);
|
||||
var y2 = Math.max(this.startPosition.y, this.endPosition.y);
|
||||
|
||||
this.state.drawValue(new ascii.Vector(x1, y1), '+');
|
||||
this.state.drawValue(new ascii.Vector(x1, y2), '+');
|
||||
this.state.drawValue(new ascii.Vector(x2, y1), '+');
|
||||
this.state.drawValue(new ascii.Vector(x2, y2), '+');
|
||||
this.state.drawSpecial(new ascii.Vector(x1, y1));
|
||||
this.state.drawSpecial(new ascii.Vector(x1, y2));
|
||||
this.state.drawSpecial(new ascii.Vector(x2, y1));
|
||||
this.state.drawSpecial(new ascii.Vector(x2, y2));
|
||||
|
||||
|
||||
for (var x = x1 + 1; x < x2; x++) {
|
||||
this.state.drawValue(new ascii.Vector(x, y1), '\u2014');
|
||||
this.state.drawValue(new ascii.Vector(x, y2), '\u2014');
|
||||
this.state.drawSpecial(new ascii.Vector(x, y1));
|
||||
this.state.drawSpecial(new ascii.Vector(x, y2));
|
||||
}
|
||||
for (var y = y1 + 1; y < y2; y++) {
|
||||
this.state.drawValue(new ascii.Vector(x1, y), '|');
|
||||
this.state.drawValue(new ascii.Vector(x2, y), '|');
|
||||
this.state.drawSpecial(new ascii.Vector(x1, y));
|
||||
this.state.drawSpecial(new ascii.Vector(x2, y));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -87,10 +87,21 @@ DrawLine.prototype.end = function(position) {
|
|||
this.state.commitDraw();
|
||||
};
|
||||
|
||||
/** Draws the currently dragged out line. */
|
||||
/**
|
||||
* Draws the currently dragged out line.
|
||||
*/
|
||||
DrawLine.prototype.draw = function() {
|
||||
// TODO: Infer line direction.
|
||||
var isClockwise = true;
|
||||
var upStart = this.state.isSpecial(
|
||||
this.startPosition.add(new ascii.Vector(0, -1)));
|
||||
var downStart = this.state.isSpecial(
|
||||
this.startPosition.add(new ascii.Vector(0, 1)));
|
||||
var leftEnd = this.state.isSpecial(
|
||||
this.endPosition.add(new ascii.Vector(-1, 0)));
|
||||
var rightEnd = this.state.isSpecial(
|
||||
this.endPosition.add(new ascii.Vector(1, 0)));
|
||||
|
||||
// Look at the start and end contexts to infer line orientation.
|
||||
var isClockwise = (upStart && downStart) || (leftEnd && rightEnd);
|
||||
|
||||
var hX1 = Math.min(this.startPosition.x, this.endPosition.x);
|
||||
var vY1 = Math.min(this.startPosition.y, this.endPosition.y);
|
||||
|
@ -101,34 +112,35 @@ DrawLine.prototype.draw = function() {
|
|||
var vX = isClockwise ? this.endPosition.x : this.startPosition.x;
|
||||
|
||||
while (hX1++ < hX2) {
|
||||
this.state.drawValue(new ascii.Vector(hX1, hY), '\u2014');
|
||||
this.state.drawSpecial(new ascii.Vector(hX1, hY));
|
||||
}
|
||||
while (vY1++ < vY2) {
|
||||
this.state.drawValue(new ascii.Vector(vX, vY1), '|');
|
||||
this.state.drawSpecial(new ascii.Vector(vX, vY1));
|
||||
}
|
||||
this.state.drawValue(new ascii.Vector(this.startPosition.x, this.startPosition.y), '+');
|
||||
this.state.drawValue(new ascii.Vector(this.endPosition.x, this.endPosition.y), '+');
|
||||
this.state.drawValue(new ascii.Vector(vX, hY), '+');
|
||||
this.state.drawSpecial(new ascii.Vector(this.startPosition.x, this.startPosition.y));
|
||||
this.state.drawSpecial(new ascii.Vector(this.endPosition.x, this.endPosition.y));
|
||||
this.state.drawSpecial(new ascii.Vector(vX, hY));
|
||||
};
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @implements {DrawFunction}
|
||||
* @param {ascii.State} state
|
||||
* @param {?string} value
|
||||
*/
|
||||
function DrawFreeform(state) {
|
||||
function DrawFreeform(state, value) {
|
||||
this.state = state;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
DrawFreeform.prototype.start = function(position) {
|
||||
this.state.drawValue(position, 'O');
|
||||
this.state.setValue(position, this.value);
|
||||
};
|
||||
DrawFreeform.prototype.move = function(position) {
|
||||
this.state.drawValue(position, 'O');
|
||||
this.state.setValue(position, this.value);
|
||||
};
|
||||
|
||||
DrawFreeform.prototype.end = function(position) {
|
||||
this.state.commitDraw();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -151,7 +163,11 @@ ascii.StateController = function(state) {
|
|||
}.bind(this));
|
||||
|
||||
$('#freeform-button').click(function(e) {
|
||||
this.drawFunction = new DrawFreeform(state);
|
||||
this.drawFunction = new DrawFreeform(state, 'O');
|
||||
}.bind(this));
|
||||
|
||||
$('#erase-button').click(function(e) {
|
||||
this.drawFunction = new DrawFreeform(state, null);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
goog.provide('ascii.State');
|
||||
|
||||
/** @const */ var MAX_GRID_SIZE = 1000;
|
||||
/** @const */ var SPECIAL_VALUE = '+';
|
||||
|
||||
/** @const */ var SPECIAL_LINE_H = '\u2014';
|
||||
/** @const */ var SPECIAL_LINE_V = '|';
|
||||
|
||||
/**
|
||||
* An individual cell within the diagram and it's current value.
|
||||
|
@ -51,17 +55,17 @@ ascii.State.prototype.getCell = function(vector) {
|
|||
* be used directly in many cases. Used drawValue instead.
|
||||
*
|
||||
* @param {ascii.Vector} position
|
||||
* @param {string} value
|
||||
* @param {?string} value
|
||||
*/
|
||||
ascii.State.prototype.setValue = function(position, value) {
|
||||
this.getCell(position).value = value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the cells scratch (uncommitted) value at the given position.
|
||||
*
|
||||
* @param {ascii.Vector} position
|
||||
* @param {string} value
|
||||
* @param {?string} value
|
||||
*/
|
||||
ascii.State.prototype.drawValue = function(position, value) {
|
||||
var cell = this.getCell(position);
|
||||
|
@ -69,6 +73,15 @@ ascii.State.prototype.drawValue = function(position, value) {
|
|||
cell.scratchValue = value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the cells scratch value to be the special value.
|
||||
*
|
||||
* @param {ascii.Vector} position
|
||||
*/
|
||||
ascii.State.prototype.drawSpecial = function(position) {
|
||||
this.drawValue(position, SPECIAL_VALUE);
|
||||
};
|
||||
|
||||
/**
|
||||
* Clears the current drawing scratchpad.
|
||||
*/
|
||||
|
@ -79,6 +92,49 @@ ascii.State.prototype.clearDraw = function() {
|
|||
this.scratchCells.length = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the cell at the given position is special.
|
||||
*
|
||||
* @param {ascii.Vector} position
|
||||
* @return {boolean}
|
||||
*/
|
||||
ascii.State.prototype.isSpecial = function(position) {
|
||||
var cell = this.getCell(position);
|
||||
var value = cell.scratchValue != null ? cell.scratchValue : cell.value;
|
||||
return value == SPECIAL_VALUE;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the draw value of a cell at the given position.
|
||||
*
|
||||
* @param {ascii.Vector} position
|
||||
* @return {?string}
|
||||
*/
|
||||
ascii.State.prototype.getDrawValue = function(position) {
|
||||
var cell = this.getCell(position);
|
||||
var value = cell.scratchValue != null ? cell.scratchValue : cell.value;
|
||||
if (value != SPECIAL_VALUE) {
|
||||
return value;
|
||||
}
|
||||
|
||||
// Magic time.
|
||||
var left = this.isSpecial(position.add(new ascii.Vector(-1, 0)));
|
||||
var right = this.isSpecial(position.add(new ascii.Vector(1, 0)));
|
||||
var up = this.isSpecial(position.add(new ascii.Vector(0, -1)));
|
||||
var down = this.isSpecial(position.add(new ascii.Vector(0, 1)));
|
||||
|
||||
if (left && right && !up && !down) {
|
||||
return SPECIAL_LINE_H;
|
||||
}
|
||||
if (!left && !right && up && down) {
|
||||
return SPECIAL_LINE_V;
|
||||
}
|
||||
if (left && right && up && down) {
|
||||
return SPECIAL_LINE_H;
|
||||
}
|
||||
return SPECIAL_VALUE;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ends the current draw, commiting anything currently drawn the scratchpad.
|
||||
*/
|
||||
|
|
|
@ -96,7 +96,7 @@ 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++) {
|
||||
var cellValue = this.state.cells[i][j].getDrawValue();
|
||||
var cellValue = this.state.getDrawValue(new ascii.Vector(i, j));
|
||||
if (cellValue != null) {
|
||||
context.fillText(cellValue,
|
||||
i * CHARACTER_PIXELS - this.offset.x + 3,
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
left: 0px;
|
||||
right: 0px;
|
||||
z-index: 100;
|
||||
width: 300px;
|
||||
width: 400px;
|
||||
background: #EEE;
|
||||
text-align: center;
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ button {
|
|||
<button id="box-button">Box</button>
|
||||
<button id="line-button">Line</button>
|
||||
<button id="freeform-button">Freeform</button>
|
||||
<button id="erase-button">Erase</button>
|
||||
</div>
|
||||
<canvas id="ascii-canvas"></canvas>
|
||||
<script src="jquery-1.9.1.min.js"></script>
|
||||
|
|
Loading…
Reference in New Issue