diff --git a/src/cartographer.js b/src/cartographer.js index 975f91b..0af70b9 100644 --- a/src/cartographer.js +++ b/src/cartographer.js @@ -28,7 +28,13 @@ export default class Cartographer { this.settings = Object.assign({}, DEFAULTS, settings); - Object.assign(this, pick(this.settings, ['height', 'width', 'negativeTiles'])); + Object.assign(this, pick(this.settings, [ + 'height', + 'negativeTiles', + 'radius', + 'width', + 'wrap', + ])); this.checkScale(this.settings.canvasHeight, this.settings.canvasWidth); @@ -102,21 +108,25 @@ export default class Cartographer { const maxX = this.tileWidth() / 2; const minY = canvasHeight - (this.tileHeight() / 2); - this.originX = this.originX > maxX ? maxX : this.originX; - this.originY = this.originY < minY ? minY : this.originY; - - if (this.width) { - const boardWidth = this.width * colWidth + this.horizontalOverhang(); - const minX = maxX - (boardWidth - canvasWidth); - - this.originX = this.originX < minX ? minX : this.originX; + if (this.wrap) { } + else { + this.originX = this.originX > maxX ? maxX : this.originX; + this.originY = this.originY < minY ? minY : this.originY; - if (this.height) { - const boardHeight = this.height * rowHeight + this.verticalOverhang(); - const maxY = boardHeight - (this.tileHeight() / 2); + if (this.width) { + const boardWidth = this.width * colWidth + this.horizontalOverhang(); + const minX = maxX - (boardWidth - canvasWidth); - this.originY = this.originY > maxY ? maxY : this.originY; + this.originX = this.originX < minX ? minX : this.originX; + } + + if (this.height) { + const boardHeight = this.height * rowHeight + this.verticalOverhang(); + const maxY = boardHeight - (this.tileHeight() / 2); + + this.originY = this.originY > maxY ? maxY : this.originY; + } } } @@ -124,22 +134,26 @@ export default class Cartographer { const colWidth = this.horizontalDistance(); const rowHeight = this.verticalDistance(); - if (this.width) { - const canvasWidth = event.width; - const halfBoardWidth = (this.width * colWidth + this.horizontalOverhang()) / 2; - - this.originX = this.originX > halfBoardWidth ? halfBoardWidth : - (canvasWidth - this.originX) > halfBoardWidth ? canvasWidth - halfBoardWidth : - this.originX; + if (this.wrap) { } + else { + if (this.width) { + const canvasWidth = event.width; + const halfBoardWidth = (this.width * colWidth + this.horizontalOverhang()) / 2; - if (this.height) { - const canvasHeight = event.height; - const halfBoardHeight = (this.height * rowHeight + this.verticalOverhang()) / 2; + this.originX = this.originX > halfBoardWidth ? halfBoardWidth : + (canvasWidth - this.originX) > halfBoardWidth ? canvasWidth - halfBoardWidth : + this.originX; + } - this.originY = this.originY > halfBoardHeight ? halfBoardHeight : - (canvasHeight - this.originY) > halfBoardHeight ? canvasHeight - halfBoardHeight : - this.originY; + if (this.height) { + const canvasHeight = event.height; + const halfBoardHeight = (this.height * rowHeight + this.verticalOverhang()) / 2; + + this.originY = this.originY > halfBoardHeight ? halfBoardHeight : + (canvasHeight - this.originY) > halfBoardHeight ? canvasHeight - halfBoardHeight : + this.originY; + } } } diff --git a/src/cartographerFlatXY.js b/src/cartographerFlatXY.js index 13b194e..3ed4eb3 100644 --- a/src/cartographerFlatXY.js +++ b/src/cartographerFlatXY.js @@ -27,6 +27,8 @@ export default class CartographerFlatXY extends Cartographer { 'tileToPixel', 'pixelToTile', + + 'inBounds', 'boundingBox', ].map(method => this[method] = this[method].bind(this)); } @@ -92,6 +94,17 @@ export default class CartographerFlatXY extends Cartographer { return new Square(x, y); } + inBounds (x, y) { + if (this.negativeTiles) { + return (!this.width || Math.abs(x) <= Math.floor(this.width / 2)) + && (!this.height || Math.abs(y) <= Math.floor(this.height / 2)); + } + else { + return (!this.width || (x >= 0 && x < this.width)) + && (!this.height || (y >= 0 && y < this.height)); + } + } + boundingBox(upperLeftPoint, upperRightPoint, lowerLeftPoint, lowerRightPoint) { const upperLeftTile = this.pixelToTile(upperLeftPoint); const lowerRightTile = this.pixelToTile(lowerRightPoint); @@ -100,6 +113,9 @@ export default class CartographerFlatXY extends Cartographer { const columns = rangeInclusive(upperLeftTile.getX(), upperRightTile.getX()); const rows = rangeInclusive(lowerRightTile.getY(), upperLeftTile.getY()); - return columns.map(x => rows.map(y => new Square(x, y))); + return columns.map(x => rows.map(y => ({x, y}))) + .reduce((flat, list) => flat.concat(list), []) + .filter(({x, y}) => this.inBounds(x, y)) + .map(({x, y}) => new Square(x, y)); } } diff --git a/src/cartographerFlatXYZ.js b/src/cartographerFlatXYZ.js index 9ec6194..4623b38 100644 --- a/src/cartographerFlatXYZ.js +++ b/src/cartographerFlatXYZ.js @@ -27,6 +27,8 @@ export default class CartographerFlatXYZ extends Cartographer { 'tileToPixel', 'pixelToTile', + + 'inBounds', 'boundingBox', ].map(method => this[method] = this[method].bind(this)); } @@ -92,6 +94,27 @@ export default class CartographerFlatXYZ extends Cartographer { return new Hex(q, r); } + inBounds (q, r, s = -q - r) { + if (this.radius) { + if (this.negativeTiles) { + return Math.max(Math.abs(q), Math.abs(r), Math.abs(s)) <= Math.floor(this.radius); + } + else { + return Math.max(Math.abs(q - this.radius), Math.abs(r + this.radius), Math.abs(s)) <= this.radius; + } + } + else if (this.width || this.height) { + if (this.negativeTiles) { + return (!this.width || (Math.abs(q) < this.width / 2)) + && (!this.height || (Math.abs(-r - Math.floor(q / 2)) < (this.height / 2))); + } + else { + return (!this.width || (q >= 0 && q < this.width)) + && (!this.height || (r <= (Math.floor(q / 2) * -1) && (-r - Math.floor(q / 2)) < this.height)); + } + } + } + boundingBox(upperLeftPoint, upperRightPoint, lowerLeftPoint, lowerRightPoint) { const upperLeftTile = this.pixelToTile(upperLeftPoint); const lowerLeftTile = this.pixelToTile(lowerLeftPoint); @@ -106,7 +129,10 @@ export default class CartographerFlatXYZ extends Cartographer { const bottom = top + height; const rows = rangeInclusive(top, bottom + 1); - return rows.map(r => new Hex(q, r)); + return rows.map(r => ({q, r})) + .reduce((flat, list) => flat.concat(list), []) + .filter(({q, r}) => this.inBounds(q, r)) + .map(({q, r}) => new Hex(q, r)); }); } } diff --git a/src/cartographerPointyXY.js b/src/cartographerPointyXY.js index a5e1140..763d5f1 100644 --- a/src/cartographerPointyXY.js +++ b/src/cartographerPointyXY.js @@ -27,6 +27,8 @@ export default class CartographerPointyXY extends Cartographer { 'tileToPixel', 'pixelToTile', + + 'inBounds', 'boundingBox', ].map(method => this[method] = this[method].bind(this)); } @@ -97,6 +99,17 @@ export default class CartographerPointyXY extends Cartographer { return new Square(x, y); } + inBounds (x, y) { + if (this.negativeTiles) { + return (!this.width || Math.abs(x) <= Math.floor(this.width / 2)) + && (!this.height || Math.abs(y) <= Math.floor(this.height / 2)); + } + else { + return (!this.width || (x >= 0 && x < this.width)) + && (!this.height || (y >= 0 && y < this.height)); + } + } + boundingBox(upperLeftPoint, upperRightPoint, lowerLeftPoint, lowerRightPoint) { const upperLeftTile = this.pixelToTile(upperLeftPoint); const lowerRightTile = this.pixelToTile(lowerRightPoint); @@ -125,7 +138,10 @@ export default class CartographerPointyXY extends Cartographer { // push out by 1 on either end to account for interlocking tiles const rows = rangeInclusive(bottom - 1, top + 1); - return rows.map(y => new Square(x, y)); + return rows.map(y => ({x, y})) + .reduce((flat, list) => flat.concat(list), []) + .filter(({x, y}) => this.inBounds(x, y)) + .map(({x, y}) => new Square(x, y)); }); } } diff --git a/src/cartographerPointyXYZ.js b/src/cartographerPointyXYZ.js index bd03d6b..7bd11de 100644 --- a/src/cartographerPointyXYZ.js +++ b/src/cartographerPointyXYZ.js @@ -27,6 +27,8 @@ export default class CartographerPointyXYZ extends Cartographer { 'tileToPixel', 'pixelToTile', + + 'inBounds', 'boundingBox', ].map(method => this[method] = this[method].bind(this)); } @@ -92,6 +94,27 @@ export default class CartographerPointyXYZ extends Cartographer { return new Hex(q, r); } + inBounds (q, r, s = -q - r) { + if (this.radius) { + if (this.negativeTiles) { + return Math.max(Math.abs(q), Math.abs(r), Math.abs(s)) <= Math.floor(this.radius); + } + else { + return Math.max(Math.abs(q - this.radius), Math.abs(r + this.radius), Math.abs(s)) <= this.radius; + } + } + else if (this.width || this.height) { + if (this.negativeTiles) { + return (!this.height || (Math.abs(r) < this.height / 2)) + && (!this.width || (Math.abs(-q - Math.floor(r / 2)) < (this.width / 2))); + } + else { + return (!this.height || (r >= 0 && r < this.height)) + && (!this.width || (q <= (Math.floor(r / 2)) && (q - Math.floor(r / 2)) < this.width)); + } + } + } + boundingBox(upperLeftPoint, upperRightPoint, lowerLeftPoint, lowerRightPoint) { const upperLeftTile = this.pixelToTile(upperLeftPoint); const lowerLeftTile = this.pixelToTile(lowerLeftPoint); @@ -106,7 +129,10 @@ export default class CartographerPointyXYZ extends Cartographer { const right = left + width; const columns = rangeInclusive(left, right + 1); - return columns.map(q => new Hex(q, r)); + return columns.map(q => ({q, r})) + .reduce((flat, list) => flat.concat(list), []) + .filter(({q, r}) => this.inBounds(q, r)) + .map(({q, r}) => new Hex(q, r)); }); } } diff --git a/src/main.js b/src/main.js index 4778a87..dde6638 100644 --- a/src/main.js +++ b/src/main.js @@ -131,6 +131,8 @@ class Demo { const pipMax = this.settings.tile === Tessellate.TILE_STYLES.HEX ? 7 : 9; this.map[key].pips = Tessellate.utils.random(1, pipMax); + + console.log({x, y, z}); } pressStart(tap) { diff --git a/src/tessellate.js b/src/tessellate.js index c77aff4..ae458aa 100644 --- a/src/tessellate.js +++ b/src/tessellate.js @@ -116,9 +116,11 @@ export class Tessellate { 'centerX', 'centerY', 'height', - 'width', - 'scale', 'negativeTiles', + 'radius', + 'scale', + 'width', + 'wrap', ]))); }