Start at Zero (#6)

This commit is contained in:
gavin
2018-07-21 02:17:49 +00:00
committed by Gitea
parent e4b9b87f44
commit 2c19266ca6
7 changed files with 204 additions and 36 deletions

View File

@@ -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;

View File

@@ -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();
} }

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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());

View File

@@ -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) {