diff --git a/src/cell.js b/src/cell.js index 83fb501..4116673 100644 --- a/src/cell.js +++ b/src/cell.js @@ -16,7 +16,7 @@ export default class Cell { this.red = 0; this.green = 0; this.blue = 0; - this.alpha = 0; + this.alpha = 0.5; this.created = Date.now(); extend(this, settings); diff --git a/src/exWhyZee.js b/src/exWhyZee.js new file mode 100644 index 0000000..32bbbe3 --- /dev/null +++ b/src/exWhyZee.js @@ -0,0 +1,317 @@ + +import {sqrt3, extend} from './utils.js'; + +import Hex from './hex.js'; +import Point from './point.js'; + +export default class ExWhyZee { + constructor(settings) { + [ + 'maxWidth', + 'minWidth', + 'maxDistance', + 'minDistance', + 'getOriginX', + 'getOriginY', + 'getScale', + 'getCellWidth', + 'getCellHeight', + 'getHorzDistance', + 'getVertDistance', + 'hexToPixel', + 'pixelToHex', + 'boundingBox' + ].map(method => this[method] = this[method].bind(this)); + + this.pointyTop = false; + + // in pixels + this.originX = 0; + this.originY = 0; + + // in pixels + this.scale = 25; + this.scaleMin = 5; + this.scaleMax = 250; + + // in cells + this.width = 0; + this.height = 0; + + extend(this, settings); + + this.originX = parseInt(this.originX); + this.originY = parseInt(this.originY); + + this.width = parseInt(this.width); + this.height = parseInt(this.height); + } + + maxWidth() { + return this.scale * 2; + } + + minWidth() { + return this.maxWidth() * sqrt3; + } + + maxDistance() { + return this.maxWidth() * (3/4); + } + + minDistance() { + return this.minWidth(); + } + + getOriginX() {return this.originX;} + getOriginY() {return this.originY;} + + getScale() {return this.scale;} + getCellWidth() {return this.pointyTop ? this.minWidth() : this.maxWidth();} + getCellHeight() {return this.pointyTop ? this.maxWidth() : this.minWidth();} + getHorzDistance() {return this.pointyTop ? this.minDistance() : this.maxDistance();} + getVertDistance() {return this.pointyTop ? this.maxDistance() : this.minDistance();} + + hexToPixel(hex) { + let scale = this.scale; + + function minWidth(a, b) { + return scale * sqrt3 * (a + (b / 2)) + }; + + function maxWidth(a) { + return scale * 3/2 * a + }; + + let pixelX = this.pointyTop ? minWidth(hex.getQ(), hex.getR()) : maxWidth(hex.getQ()); + let pixelY = this.pointyTop ? maxWidth(hex.getR()) : minWidth(hex.getR(), hex.getQ()); + + pixelX += this.originX; + pixelY += this.originY; + + return new Point(pixelX, pixelY); + } + + pixelToHex(point) { + let scale = this.scale; + + function radiusLong(a, b) { + return ((a * (sqrt3 / 3)) - (b / 3)) / scale; + }; + + function radiusShort(a) { + return (a * (2 / 3)) / scale; + }; + + let pixelX = point.getX() - this.originX; + let pixelY = point.getY() - this.originY; + + let q = this.pointyTop ? radiusLong(pixelX, pixelY) : radiusShort(pixelX); + let r = this.pointyTop ? radiusShort(pixelY) : radiusLong(pixelY, pixelX); + + return new Hex(q, r); + } + + boundingBox(upperLeftPoint, lowerRightPoint) { + let hexagons = []; + let upperRightPoint = new Point(lowerRightPoint.getX(), upperLeftPoint.getY()); + + // push out by a 1 axially to account for interlocking hexagons + // possibly return hexagons not within bounds + let upperLeftHex = this.pixelToHex(upperLeftPoint).moveAxial({q: 0, r: -1}); + let lowerRightHex = this.pixelToHex(lowerRightPoint).moveAxial({q: 0, r: 1}); + let upperRightHex = this.pixelToHex(upperRightPoint).moveAxial({q: 1, r: -1}); + + let height = lowerRightHex.getR() - upperLeftHex.getR(); + let width = upperRightHex.getQ() - upperLeftHex.getQ(); + + for (let row = 0; row <= height; row++) { + hexagons[row] = []; + let r = upperLeftHex.getR() + row; + let qOffset = upperLeftHex.getQ() - Math.floor(row / 2); + + for (let q = qOffset; q <= qOffset + width; q++) { + hexagons[row].push(new Hex(q, r)); + } + } + + return hexagons; + } +} + +// function getCoordinates(canvasX, canvasY) { +// var hexWidth = sqrt3 * scale; +// var graphY = Math.round((originY + (scale/2) - canvasY) / (1.5*scale)); +// var mapY = height ? graphY % height : graphY; +// mapY = mapY < 0 ? mapY + height : mapY; +// var graphX = Math.round(((canvasX - originX) / hexWidth) - (graphY/2)); +// var mapX = width ? graphX % width : graphX; +// mapX = mapX < 0 ? (width + mapX) : mapX; +// var mapZ = -(mapX + mapY); +// +// return {x:mapX, y:mapY, z:mapZ} +// } +// +// var ExWhyZee = { +// boundingBox: function(upperLeftPoint, lowerRightPoint, contained) { +// var hexagons = []; +// var upperRightPoint = Point(lowerRightPoint.getX(), upperLeftPoint.getY()); +// +// // push out by a 1 axially to account for interlocking hexagons +// // possibly return hexagons not within bounds +// var upperLeftHex = this.pixelToHex(upperLeftPoint).moveAxial({q: 0, r: -1}); +// var lowerRightHex = this.pixelToHex(lowerRightPoint).moveAxial({q: 0, r: 1}); +// var upperRightHex = this.pixelToHex(upperRightPoint).moveAxial({q: 1, r: -1}); +// +// var height = lowerRightHex.getR() - upperLeftHex.getR(); +// var width = upperRightHex.getQ() - upperLeftHex.getQ(); +// +// for (var row = 0; row <= height; row++) { +// hexagons[row] = []; +// var r = upperLeftHex.getR() + row; +// var qOffset = upperLeftHex.getQ() - Math.floor(row / 2); +// +// for (var q = qOffset; q <= qOffset + width; q++) { +// hexagons[row].push(Hex(q, r)); +// } +// } +// +// return hexagons; +// }, +// +// cellDistance: function(hex1, hex2) { +// return Math.max( +// Math.abs(hex1.getX() - hex2.getX()), +// Math.abs(hex1.getY() - hex2.getY()), +// Math.abs(hex1.getZ() - hex2.getZ()) +// ); +// }, +// +// setNeighbors: function(distance) { +// if (!neighbors[distance - 1]) { +// var length = 6 * distance; +// for (var i=0; i= map.width ? tempX - map.width : tempX; +//// var tempY = curY < 0 ? curY + map.height : curY; +//// tempY = tempY >= map.height ? tempY - map.height : tempY; +//// +//// neighbors.push({'x':tempX, 'y':tempY, 'z':-(tempX+tempY)}); +//// } +//// } +//// } +//// } +//// +//// return neighbors; +//// }, +// +// hexToPixel: function(hex) { +// var minWidth = function(a, b) { +// return scale * sqrt3 * (a + (b / 2)) +// }; +// +// var maxWidth = function(a) { +// return scale * 3/2 * a +// }; +// +// var pixelX = pointyTop ? minWidth(hex.getQ(), hex.getR()) : maxWidth(hex.getQ()); +// var pixelY = pointyTop ? maxWidth(hex.getR()) : minWidth(hex.getR(), hex.getQ()); +// +// pixelX += originX; +// pixelY += originY; +// +// return Point(pixelX, pixelY); +// }, +// +// pixelToHex: function(point) { +// var radiusLong = function(a, b) { +// return ((a * (sqrt3 / 3)) - (b / 3)) / scale; +// }; +// +// var radiusShort = function(a) { +// return (a * (2 / 3)) / scale; +// }; +// +// var pixelX = point.getX() - originX; +// var pixelY = point.getY() - originY; +// +// var q = pointyTop ? radiusLong(pixelX, pixelY) : radiusShort(pixelX); +// var r = pointyTop ? radiusShort(pixelY) : radiusLong(pixelY, pixelX); +// +// return Hex(q, r); +// }, +// +// move: function(event) { +// if (event.deltaX) { +// +// originX = Math.floor((originX*1000) + (event.deltaX*1000)) / 1000; +// } +// +// if (event.deltaY) { +// +// originY = Math.floor((originY*1000) + (event.deltaY*1000)) / 1000; +// } +// }, +// +// zoom: function(event) { +// var scaleOrig = scale; +// +// var scaleTemp = parseInt((scaleOrig + (event.deltaY / 10)) * 1000) / 1000; +// +// // make sure 'scale' doesn't get too small nor too big +// if (scaleTemp < scaleMin) +// scaleTemp = scaleMin; +// else if (scaleTemp > scaleMax) +// scaleTemp = scaleMax; +// +// if (scaleOrig != scaleTemp) { +// +// scale = scaleTemp; +// +// // zoom to the current mouse location +// this.move({ +// deltaX: (((event.offsetX - originX) / scaleOrig) * (scaleOrig - scaleTemp)), +// deltaY: (((event.offsetY - originY) / scaleOrig) * (scaleOrig - scaleTemp)) +// }); +// } +// } +// }; +// +// return ExWhyZee; +//}; + diff --git a/src/hex.js b/src/hex.js index 366626e..a95217e 100644 --- a/src/hex.js +++ b/src/hex.js @@ -54,70 +54,68 @@ export default class Hex extends Point { roundOff(this.x, this.y, this.z); } - return { - getX: function() {return this.x;}, - getY: function() {return this.y;}, - getZ: function() {return this.z;}, + getX() {return this.x;} + getY() {return this.y;} + getZ() {return this.z;} - setX: function(newX) {this.x = newX; return this;}, - setY: function(newY) {this.y = newY; return this;}, - setZ: function(newZ) {this.z = newZ; return this;}, + setX(newX) {this.x = newX; return this;} + setY(newY) {this.y = newY; return this;} + setZ(newZ) {this.z = newZ; return this;} - moveX: function(byX) {this.x += byX; return this;}, - moveY: function(byY) {this.y += byY; return this;}, - moveZ: function(byZ) {this.z += byZ; return this;}, + moveX(byX) {this.x += byX; return this;} + moveY(byY) {this.y += byY; return this;} + moveZ(byZ) {this.z += byZ; return this;} - getQ: function() {return this.x;}, - getR: function() {return this.z;}, + getQ() {return this.x;} + getR() {return this.z;} - setQ: function(newQ) { - this.x = newQ; - this.y = computeY(this.x, this.z); - return this; - }, - setR: function(newR) { - this.z = newR; - this.y = computeY(this.x, this.z); - return this; - }, + setQ(newQ) { + this.x = newQ; + this.y = computeY(this.x, this.z); + return this; + } + setR(newR) { + this.z = newR; + this.y = computeY(this.x, this.z); + return this; + } - moveQ: function(byQ) { - this.x += byQ; - this.y = computeY(this.x, this.z); - return this; - }, - moveR: function(byR) { - this.z += byR; - this.y = computeY(this.x, this.z); - return this; - }, + moveQ(byQ) { + this.x += byQ; + this.y = computeY(this.x, this.z); + return this; + } + moveR(byR) { + this.z += byR; + this.y = computeY(this.x, this.z); + return this; + } - getHex: function() { return {x: this.x, y: this.y, z: this.z}; }, - setHex: function(newHex) { - this.x = newHex.x; - this.y = newHex.y; - this.z = newHex.z; - return this; - }, - moveHex: function(byHex) { - this.x += byHex.x; - this.y += byHex.y; - this.z += byHex.z; - return this; - }, + getHex() { return {x: this.x, y: this.y, z: this.z}; } + setHex(newHex) { + this.x = newHex.x; + this.y = newHex.y; + this.z = newHex.z; + return this; + } + moveHex(byHex) { + this.x += byHex.x; + this.y += byHex.y; + this.z += byHex.z; + return this; + } - getAxial: function() {return {q: this.x, r: this.z};}, - setAxial: function(newAxial) { - this.x = newAxial.q; - this.z = newAxial.r; - this.y = computeY(this.x, this.y); - return this; - }, - moveAxial: function(byAxial) { - this.x += byAxial.q; - this.z += byAxial.r; - this.y = computeY(this.x, this.z); - return this; - } - }; -}; + getAxial() {return {q: this.x, r: this.z};} + setAxial(newAxial) { + this.x = newAxial.q; + this.z = newAxial.r; + this.y = computeY(this.x, this.y); + return this; + } + moveAxial(byAxial) { + this.x += byAxial.q; + this.z += byAxial.r; + this.y = computeY(this.x, this.z); + return this; + } +} diff --git a/src/point.js b/src/point.js index c5f9e33..f13de93 100644 --- a/src/point.js +++ b/src/point.js @@ -12,4 +12,4 @@ export default class Point { setY(newY) { this.y = newY; } getPoint() { return {x: this.x, y: this.y}; } -}; +} diff --git a/src/tessellate.js b/src/tessellate.js index f0bfe52..00138b4 100644 --- a/src/tessellate.js +++ b/src/tessellate.js @@ -14,9 +14,11 @@ export {DrawCircle, DrawHexagon, DrawSquare}; import Cell from './cell.js'; export {Cell}; +import ExWhyZee from './exWhyZee.js'; + export default class Tessellate { constructor(settings) { - ['click', 'draw'].map(method => {this[method] = this[method].bind(this)}); + ['click', 'draw', 'drawMap'].map(method => {this[method] = this[method].bind(this)}); this.drawCB = settings.draw || utils.noop; this.clickCB = settings.click || utils.noop; @@ -31,12 +33,51 @@ export default class Tessellate { element: this.element, click: this.click }); + + this.xyz = new ExWhyZee({ + pointyTop: true, + originX: this.sketch.getContext().canvas.width / 2, + originY: this.sketch.getContext().canvas.height / 2 + }); + + this.circle = new DrawCircle(); } click(event) { this.clickCB(event); } + drawMap(context) { + let scale = this.xyz.getScale(); + let upperLeft = new Point(0, 0); + let lowerRight = new Point(context.canvas.width, context.canvas.height); + let hexagons = this.xyz.boundingBox(upperLeft, lowerRight); + + let height = hexagons.length; + for (let r=0; r