Start at Zero (#6)
This commit is contained in:
@@ -23,15 +23,15 @@ export default class Cartographer {
|
|||||||
|
|
||||||
Object.assign(this, SETTINGS_DEFAULTS, settings);
|
Object.assign(this, SETTINGS_DEFAULTS, settings);
|
||||||
|
|
||||||
|
this._checkScale(this.canvasHeight, this.canvasWidth);
|
||||||
|
|
||||||
this.originX = has(this, 'originX') ? this.originX :
|
this.originX = has(this, 'originX') ? this.originX :
|
||||||
this.canvasWidth ? parseInt(this.canvasWidth / 2) :
|
this.negativeTiles ? parseInt(this.canvasWidth / 2) :
|
||||||
0;
|
this.tileWidth() / 2;
|
||||||
|
|
||||||
this.originY = has(this, 'originY') ? this.originY :
|
this.originY = has(this, 'originY') ? this.originY :
|
||||||
this.canvasHeight ? parseInt(this.canvasHeight / 2) :
|
this.negativeTiles ? parseInt(this.canvasHeight / 2) :
|
||||||
0;
|
this.canvasHeight - (this.tileHeight() / 2);
|
||||||
|
|
||||||
this._checkScale(this.canvasHeight, this.canvasWidth);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getOriginX() {return this.originX;}
|
getOriginX() {return this.originX;}
|
||||||
@@ -39,6 +39,13 @@ export default class Cartographer {
|
|||||||
|
|
||||||
getScale() {return this.scale;}
|
getScale() {return this.scale;}
|
||||||
|
|
||||||
|
_checkScale(canvasHeight, canvasWidth) {
|
||||||
|
const heightMin = this.height ? this.calculateVerticalScale(canvasHeight, this.height) : 0;
|
||||||
|
const widthMin = this.width ? this.calculateHorizontalScale(canvasWidth, this.width) : 0;
|
||||||
|
this.scaleMin = Math.max(this.scaleMin, heightMin, widthMin);
|
||||||
|
this.scale = this.scaleMin > this.scale ? this.scaleMin : this.scale;
|
||||||
|
}
|
||||||
|
|
||||||
move(event) {
|
move(event) {
|
||||||
if (event.deltaX) {
|
if (event.deltaX) {
|
||||||
|
|
||||||
@@ -54,12 +61,49 @@ export default class Cartographer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_checkMove(event) {
|
_checkMove(event) {
|
||||||
|
if (this.negativeTiles) {
|
||||||
|
this._checkMoveNegativeTiles(event);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._checkMovePositiveTiles(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_checkMovePositiveTiles(event) {
|
||||||
|
const canvasWidth = event.target.offsetWidth;
|
||||||
|
const canvasHeight = event.target.offsetHeight;
|
||||||
|
|
||||||
|
const colWidth = this.horizontalDistance();
|
||||||
|
const rowHeight = this.verticalDistance();
|
||||||
|
|
||||||
|
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.height) {
|
||||||
|
const boardHeight = this.height * rowHeight + this.verticalOverhang();
|
||||||
|
const maxY = boardHeight - (this.tileHeight() / 2);
|
||||||
|
|
||||||
|
this.originY = this.originY > maxY ? maxY : this.originY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_checkMoveNegativeTiles(event) {
|
||||||
const colWidth = this.horizontalDistance();
|
const colWidth = this.horizontalDistance();
|
||||||
const rowHeight = this.verticalDistance();
|
const rowHeight = this.verticalDistance();
|
||||||
|
|
||||||
if (this.width) {
|
if (this.width) {
|
||||||
const canvasWidth = event.target.offsetWidth;
|
const canvasWidth = event.target.offsetWidth;
|
||||||
const halfBoardWidth = (this.width * colWidth + colWidth) / 2;
|
const halfBoardWidth = (this.width * colWidth + this.horizontalOverhang()) / 2;
|
||||||
|
|
||||||
this.originX = this.originX > halfBoardWidth ? halfBoardWidth :
|
this.originX = this.originX > halfBoardWidth ? halfBoardWidth :
|
||||||
(canvasWidth - this.originX) > halfBoardWidth ? canvasWidth - halfBoardWidth :
|
(canvasWidth - this.originX) > halfBoardWidth ? canvasWidth - halfBoardWidth :
|
||||||
@@ -68,7 +112,7 @@ export default class Cartographer {
|
|||||||
|
|
||||||
if (this.height) {
|
if (this.height) {
|
||||||
const canvasHeight = event.target.offsetHeight;
|
const canvasHeight = event.target.offsetHeight;
|
||||||
const halfBoardHeight = (this.height * rowHeight + rowHeight) / 2;
|
const halfBoardHeight = (this.height * rowHeight + this.verticalOverhang()) / 2;
|
||||||
|
|
||||||
this.originY = this.originY > halfBoardHeight ? halfBoardHeight :
|
this.originY = this.originY > halfBoardHeight ? halfBoardHeight :
|
||||||
(canvasHeight - this.originY) > halfBoardHeight ? canvasHeight - halfBoardHeight :
|
(canvasHeight - this.originY) > halfBoardHeight ? canvasHeight - halfBoardHeight :
|
||||||
@@ -76,13 +120,6 @@ export default class Cartographer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_checkScale(canvasHeight, canvasWidth) {
|
|
||||||
const heightMin = this.height ? this.calculateVerticalScale(canvasHeight, this.height + 1) : 0;
|
|
||||||
const widthMin = this.width ? this.calculateHorizontalScale(canvasWidth, this.width + 1) : 0;
|
|
||||||
this.scaleMin = Math.max(this.scaleMin, heightMin, widthMin);
|
|
||||||
this.scale = this.scaleMin > this.scale ? this.scaleMin : this.scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
zoom(event) {
|
zoom(event) {
|
||||||
let scaleOrig = this.scale;
|
let scaleOrig = this.scale;
|
||||||
|
|
||||||
|
|||||||
@@ -10,9 +10,15 @@ export default class CartographerFlatXY extends Cartographer {
|
|||||||
super(settings);
|
super(settings);
|
||||||
|
|
||||||
[
|
[
|
||||||
|
'tileHeight',
|
||||||
|
'tileWidth',
|
||||||
|
|
||||||
'maxWidth',
|
'maxWidth',
|
||||||
'minWidth',
|
'minWidth',
|
||||||
|
|
||||||
|
'horizontalOverhang',
|
||||||
|
'verticalOverhang',
|
||||||
|
|
||||||
'horizontalDistance',
|
'horizontalDistance',
|
||||||
'verticalDistance',
|
'verticalDistance',
|
||||||
|
|
||||||
@@ -25,6 +31,14 @@ export default class CartographerFlatXY extends Cartographer {
|
|||||||
].map(method => this[method] = this[method].bind(this));
|
].map(method => this[method] = this[method].bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tileHeight() {
|
||||||
|
return this.minWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
tileWidth() {
|
||||||
|
return this.minWidth();
|
||||||
|
}
|
||||||
|
|
||||||
maxWidth() {
|
maxWidth() {
|
||||||
return this.minWidth() * sqrt2;
|
return this.minWidth() * sqrt2;
|
||||||
}
|
}
|
||||||
@@ -33,6 +47,14 @@ export default class CartographerFlatXY extends Cartographer {
|
|||||||
return this.scale * 2;
|
return this.scale * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
horizontalOverhang() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
verticalOverhang() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
horizontalDistance() {
|
horizontalDistance() {
|
||||||
return this.minWidth();
|
return this.minWidth();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,9 +10,15 @@ export default class CartographerFlatXYZ extends Cartographer {
|
|||||||
super(settings);
|
super(settings);
|
||||||
|
|
||||||
[
|
[
|
||||||
|
'tileHeight',
|
||||||
|
'tileWidth',
|
||||||
|
|
||||||
'maxWidth',
|
'maxWidth',
|
||||||
'minWidth',
|
'minWidth',
|
||||||
|
|
||||||
|
'horizontalOverhang',
|
||||||
|
'verticalOverhang',
|
||||||
|
|
||||||
'horizontalDistance',
|
'horizontalDistance',
|
||||||
'verticalDistance',
|
'verticalDistance',
|
||||||
|
|
||||||
@@ -25,6 +31,14 @@ export default class CartographerFlatXYZ extends Cartographer {
|
|||||||
].map(method => this[method] = this[method].bind(this));
|
].map(method => this[method] = this[method].bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tileHeight() {
|
||||||
|
return this.minWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
tileWidth() {
|
||||||
|
return this.maxWidth();
|
||||||
|
}
|
||||||
|
|
||||||
maxWidth() {
|
maxWidth() {
|
||||||
return this.scale * 2;
|
return this.scale * 2;
|
||||||
}
|
}
|
||||||
@@ -33,6 +47,14 @@ export default class CartographerFlatXYZ extends Cartographer {
|
|||||||
return this.scale * sqrt3;
|
return this.scale * sqrt3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
horizontalOverhang() {
|
||||||
|
return this.maxWidth() * 0.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
verticalOverhang() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
horizontalDistance() {
|
horizontalDistance() {
|
||||||
return this.maxWidth() * (3/4);
|
return this.maxWidth() * (3/4);
|
||||||
}
|
}
|
||||||
@@ -42,7 +64,7 @@ export default class CartographerFlatXYZ extends Cartographer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
calculateHorizontalScale(pixels, tiles) {
|
calculateHorizontalScale(pixels, tiles) {
|
||||||
return pixels / (tiles * (3/4)) / 2;
|
return pixels / (tiles * 0.75 + 0.25) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
calculateVerticalScale(pixels, tiles) {
|
calculateVerticalScale(pixels, tiles) {
|
||||||
|
|||||||
@@ -10,9 +10,15 @@ export default class CartographerPointyXY extends Cartographer {
|
|||||||
super(settings);
|
super(settings);
|
||||||
|
|
||||||
[
|
[
|
||||||
|
'tileHeight',
|
||||||
|
'tileWidth',
|
||||||
|
|
||||||
'maxWidth',
|
'maxWidth',
|
||||||
'minWidth',
|
'minWidth',
|
||||||
|
|
||||||
|
'horizontalOverhang',
|
||||||
|
'verticalOverhang',
|
||||||
|
|
||||||
'horizontalDistance',
|
'horizontalDistance',
|
||||||
'verticalDistance',
|
'verticalDistance',
|
||||||
|
|
||||||
@@ -25,6 +31,14 @@ export default class CartographerPointyXY extends Cartographer {
|
|||||||
].map(method => this[method] = this[method].bind(this));
|
].map(method => this[method] = this[method].bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tileHeight() {
|
||||||
|
return this.maxWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
tileWidth() {
|
||||||
|
return this.maxWidth();
|
||||||
|
}
|
||||||
|
|
||||||
maxWidth() {
|
maxWidth() {
|
||||||
return this.minWidth() * sqrt2;
|
return this.minWidth() * sqrt2;
|
||||||
}
|
}
|
||||||
@@ -33,6 +47,14 @@ export default class CartographerPointyXY extends Cartographer {
|
|||||||
return this.scale * 2;
|
return this.scale * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
horizontalOverhang() {
|
||||||
|
return this.maxWidth() * 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
verticalOverhang() {
|
||||||
|
return this.maxWidth() * 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
horizontalDistance() {
|
horizontalDistance() {
|
||||||
return this.maxWidth() / 2;
|
return this.maxWidth() / 2;
|
||||||
}
|
}
|
||||||
@@ -42,11 +64,11 @@ export default class CartographerPointyXY extends Cartographer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
calculateHorizontalScale(pixels, tiles) {
|
calculateHorizontalScale(pixels, tiles) {
|
||||||
return pixels / sqrt2 / tiles;
|
return pixels / sqrt2 / (tiles + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
calculateVerticalScale(pixels, tiles) {
|
calculateVerticalScale(pixels, tiles) {
|
||||||
return pixels / sqrt2 / tiles;
|
return pixels / sqrt2 / (tiles + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
tileToPixel(square) {
|
tileToPixel(square) {
|
||||||
|
|||||||
@@ -10,9 +10,15 @@ export default class CartographerPointyXYZ extends Cartographer {
|
|||||||
super(settings);
|
super(settings);
|
||||||
|
|
||||||
[
|
[
|
||||||
|
'tileHeight',
|
||||||
|
'tileWidth',
|
||||||
|
|
||||||
'maxWidth',
|
'maxWidth',
|
||||||
'minWidth',
|
'minWidth',
|
||||||
|
|
||||||
|
'horizontalOverhang',
|
||||||
|
'verticalOverhang',
|
||||||
|
|
||||||
'horizontalDistance',
|
'horizontalDistance',
|
||||||
'verticalDistance',
|
'verticalDistance',
|
||||||
|
|
||||||
@@ -25,6 +31,14 @@ export default class CartographerPointyXYZ extends Cartographer {
|
|||||||
].map(method => this[method] = this[method].bind(this));
|
].map(method => this[method] = this[method].bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tileHeight() {
|
||||||
|
return this.maxWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
tileWidth() {
|
||||||
|
return this.minWidth();
|
||||||
|
}
|
||||||
|
|
||||||
maxWidth() {
|
maxWidth() {
|
||||||
return this.scale * 2;
|
return this.scale * 2;
|
||||||
}
|
}
|
||||||
@@ -33,6 +47,14 @@ export default class CartographerPointyXYZ extends Cartographer {
|
|||||||
return this.scale * sqrt3;
|
return this.scale * sqrt3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
horizontalOverhang() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
verticalOverhang() {
|
||||||
|
return this.maxWidth() * 0.25;
|
||||||
|
}
|
||||||
|
|
||||||
horizontalDistance() {
|
horizontalDistance() {
|
||||||
return this.minWidth();
|
return this.minWidth();
|
||||||
}
|
}
|
||||||
@@ -46,7 +68,7 @@ export default class CartographerPointyXYZ extends Cartographer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
calculateVerticalScale(pixels, tiles) {
|
calculateVerticalScale(pixels, tiles) {
|
||||||
return pixels / (tiles * (3/4)) / 2;
|
return pixels / (tiles * 0.75 + 0.25) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
tileToPixel(hex) {
|
tileToPixel(hex) {
|
||||||
|
|||||||
40
src/main.js
40
src/main.js
@@ -14,19 +14,21 @@ const DEFAULTS = {
|
|||||||
class Demo {
|
class Demo {
|
||||||
constructor() {
|
constructor() {
|
||||||
[
|
[
|
||||||
|
'setOriginTile',
|
||||||
'onTap',
|
'onTap',
|
||||||
'createTile',
|
'createTile',
|
||||||
'drawTile',
|
'drawTile',
|
||||||
'draw',
|
'draw',
|
||||||
].map(method => this[method] = this[method].bind(this));
|
].map(method => this[method] = this[method].bind(this));
|
||||||
|
|
||||||
this.map = {};
|
|
||||||
this.taps = [];
|
|
||||||
|
|
||||||
const queryStringObj = utils.getQueryStringObj();
|
const queryStringObj = utils.getQueryStringObj();
|
||||||
|
|
||||||
this.settings = Object.assign({}, DEFAULTS, queryStringObj);
|
this.settings = Object.assign({}, DEFAULTS, queryStringObj);
|
||||||
|
|
||||||
|
this.map = {};
|
||||||
|
this.taps = [];
|
||||||
|
this.setOriginTile();
|
||||||
|
|
||||||
this.tessellate = new Tessellate(Object.assign({
|
this.tessellate = new Tessellate(Object.assign({
|
||||||
element: '#container',
|
element: '#container',
|
||||||
tap: this.onTap,
|
tap: this.onTap,
|
||||||
@@ -41,6 +43,38 @@ class Demo {
|
|||||||
this.styles = ['filled', 'outline'];
|
this.styles = ['filled', 'outline'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setOriginTile() {
|
||||||
|
this.map['0,0'] = new Cell({
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
scale: 1,
|
||||||
|
drawStyle: Tessellate.DRAW_STYLES.FILL,
|
||||||
|
tileStyle: this.settings.tile,
|
||||||
|
orientation: this.settings.orientation,
|
||||||
|
red: 255,
|
||||||
|
green: 255,
|
||||||
|
blue: 0,
|
||||||
|
alpha: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
utils.rangeInclusive(0, 5)
|
||||||
|
.map(interval => interval ? interval * 0.2 : 0.01)
|
||||||
|
.forEach(interval => {
|
||||||
|
this.taps.push(new Cell({
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
scale: interval,
|
||||||
|
drawStyle: Tessellate.DRAW_STYLES.OUTLINE,
|
||||||
|
tileStyle: this.settings.tile,
|
||||||
|
orientation: this.settings.orientation,
|
||||||
|
red: 0,
|
||||||
|
green: 0,
|
||||||
|
blue: 0,
|
||||||
|
alpha: 1,
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
onTap(tap) {
|
onTap(tap) {
|
||||||
console.log(tap.tile.getPoint());
|
console.log(tap.tile.getPoint());
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
import * as utils from './utils';
|
import * as utils from './utils';
|
||||||
export {utils};
|
export {utils};
|
||||||
|
|
||||||
@@ -44,6 +43,7 @@ const DEFAULTS = {
|
|||||||
tap: utils.noop,
|
tap: utils.noop,
|
||||||
draw: utils.noop,
|
draw: utils.noop,
|
||||||
orientation: FLAT,
|
orientation: FLAT,
|
||||||
|
negativeTiles: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
function selectCartographer(board, orientation) {
|
function selectCartographer(board, orientation) {
|
||||||
@@ -70,18 +70,17 @@ export default class Tessellate {
|
|||||||
|
|
||||||
constructor(settings) {
|
constructor(settings) {
|
||||||
[
|
[
|
||||||
|
'checkSettings',
|
||||||
'tap',
|
'tap',
|
||||||
'move',
|
'move',
|
||||||
'zoom',
|
'zoom',
|
||||||
'pixelToTile',
|
'pixelToTile',
|
||||||
'tileToPixel',
|
'tileToPixel',
|
||||||
'getTilePoints',
|
'getTilePoints',
|
||||||
'draw']
|
'draw'
|
||||||
.map(method => {this[method] = this[method].bind(this)});
|
].map(method => {this[method] = this[method].bind(this)});
|
||||||
|
|
||||||
this.settings = Object.assign(DEFAULTS, settings);
|
this.checkSettings(settings);
|
||||||
this.settings.element = this.settings.element instanceof HTMLElement ? this.settings.element :
|
|
||||||
document.querySelector(this.settings.element);
|
|
||||||
|
|
||||||
this.sketch = new Sketch({
|
this.sketch = new Sketch({
|
||||||
element: this.settings.element,
|
element: this.settings.element,
|
||||||
@@ -96,17 +95,27 @@ export default class Tessellate {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const cartographer = selectCartographer(this.settings.board, this.settings.orientation);
|
const cartographer = selectCartographer(this.settings.board, this.settings.orientation);
|
||||||
this.cartographer = new cartographer({
|
this.cartographer = new cartographer(Object.assign({
|
||||||
height: this.settings.height,
|
|
||||||
width: this.settings.width,
|
|
||||||
scale: this.settings.scale,
|
|
||||||
|
|
||||||
canvasWidth: this.sketch.getContext().canvas.width,
|
canvasWidth: this.sketch.getContext().canvas.width,
|
||||||
canvasHeight: this.sketch.getContext().canvas.height,
|
canvasHeight: this.sketch.getContext().canvas.height,
|
||||||
|
}, funky.pick(this.settings, ['originX', 'originY', 'height', 'width', 'scale', 'negativeTiles'])));
|
||||||
|
}
|
||||||
|
|
||||||
originX: this.settings.originX || this.sketch.getContext().canvas.width / 2,
|
checkSettings(settings) {
|
||||||
originY: this.settings.originY || this.sketch.getContext().canvas.height / 2,
|
|
||||||
});
|
this.settings = Object.assign({}, DEFAULTS, settings);
|
||||||
|
this.settings.element = this.settings.element instanceof HTMLElement ? this.settings.element :
|
||||||
|
document.querySelector(this.settings.element);
|
||||||
|
|
||||||
|
if (this.settings.negativeTiles) {
|
||||||
|
if (this.settings.height && (this.settings.height % 2 === 0)) {
|
||||||
|
this.settings.height++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.settings.width && (this.settings.width % 2 === 0)) {
|
||||||
|
this.settings.width++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tap(event) {
|
tap(event) {
|
||||||
|
|||||||
Reference in New Issue
Block a user