Files
Tessellate/src/main.js
Gavin McDonald 9fc0ca46c5 display FPS
2018-09-24 21:31:13 -04:00

260 lines
6.0 KiB
JavaScript

import FPS from './fps.js';
const ONE_SECOND = 1000;
const PRESS_RIPPLE = ONE_SECOND / 3;
const DEFAULTS = {
board: Tessellate.BOARD_STYLES.HEX,
style: Tessellate.DRAW_STYLES.FILL,
orientation: Tessellate.ORIENTATION_STYLES.FLAT,
tile: Tessellate.TILE_STYLES.HEX,
};
const pressRipple = function() {
const sinStart = 2 * Math.PI;
const halfPi = Math.PI / 2;
return pressFactor => Math.sin(sinStart + (pressFactor * halfPi)) + 1;
}();
const pressFade = function() {
const halfPi = Math.PI / 2;
return pressFactor => Math.sin(Math.PI + (pressFactor * halfPi)) + 1;
}();
class Demo {
constructor() {
[
'setOriginTile',
'setFadeToGray',
'tap',
'pressStart',
'press',
'createTile',
'drawTile',
'draw',
].map(method => this[method] = this[method].bind(this));
const queryStringObj = Tessellate.utils.getQueryStringObj();
this.settings = Object.assign({}, DEFAULTS, queryStringObj);
this.map = {};
this.taps = [];
this.mines = {};
this.ripples = [];
this.fps = new FPS({
element: document.querySelector('#fps'),
});
this.setOriginTile();
this.setFadeToGray();
this.tessellate = new Tessellate(Object.assign({
element: '#container',
tap: this.tap,
pressStart: this.pressStart,
press: this.press,
draw: this.draw,
}, this.settings));
}
setOriginTile() {
this.map['0,0'] = new Tessellate.Cell({
x: 0,
y: 0,
scale: 1,
drawStyle: Tessellate.DRAW_STYLES.FILL,
tileStyle: this.settings.tile,
orientation: this.settings.orientation,
color: {
red: 255,
green: 255,
blue: 0,
alpha: 1,
}
});
Tessellate.utils.rangeInclusive(0, 5)
.map(interval => interval ? interval * 0.2 : 0.01)
.forEach(interval => {
this.taps.push(new Tessellate.Cell({
x: 0,
y: 0,
scale: interval,
drawStyle: Tessellate.DRAW_STYLES.OUTLINE,
tileStyle: this.settings.tile,
orientation: this.settings.orientation,
color: {
red: 0,
green: 0,
blue: 0,
alpha: 1,
},
}));
});
}
setFadeToGray () {
window.addEventListener('keydown', event => {
if (!event.repeat && event.key === 'Enter') {
this.gray = this.gray ? null : Date.now();
}
});
}
tap(tap) {
const {x, y, z} = tap.tile.getPoint();
const key = `${ x },${ z != null ? z : y }`;
const pipMax = this.settings.tile === Tessellate.TILE_STYLES.HEX ? 7 : 9;
this.map[key].pips = Tessellate.utils.random(1, pipMax);
}
pressStart(tap) {
this.ripples.push({
timestamp: tap.event.timeStampUTC,
cell: this.createTile({
x: tap.tile.x,
y: tap.tile.y,
scale: 1.0,
drawStyle: Tessellate.DRAW_STYLES.FILL,
tileStyle: Tessellate.TILE_STYLES.CIRCLE,
orientation: Tessellate.ORIENTATION_STYLES.FLAT,
color: {
red: 128,
green: 128,
blue: 128,
alpha: 0.5,
},
})
});
if (tap.event.mobile) {
this.togglemine(tap.tile)
}
}
press(tap) {
if (!tap.event.mobile) {
this.togglemine(tap.tile)
}
}
togglemine(tile) {
const {x, y, z} = tile.getPoint();
const key = `${ x },${ z != null ? z : y }`;
if (this.mines[key]) {
delete this.mines[key];
}
else {
this.mines[key] = tile;
}
}
createTile({x, y,
drawStyle, tileStyle, orientation,
scale = Tessellate.utils.random(7, 9) / 10,
color = {
red: Tessellate.utils.random(255),
green: Tessellate.utils.random(255),
blue: Tessellate.utils.random(255),
alpha: Tessellate.utils.random(25, 75) / 100,
}
}) {
return new Tessellate.Cell({
x, y,
scale,
drawStyle,
tileStyle,
orientation,
color,
});
}
fadeToGray (tile, fadeFactor) {
tile.color.grayscale = tile.color.grayscale || Tessellate.utils.grayscale(tile.color);
const grayscale = tile.color.grayscale;
const color = {
red: parseInt(tile.color.red - ((tile.color.red - grayscale) * fadeFactor)),
green: parseInt(tile.color.green - ((tile.color.green - grayscale) * fadeFactor)),
blue: parseInt(tile.color.blue - ((tile.color.blue - grayscale) * fadeFactor)),
};
tile = Tessellate.utils.extend(tile, {color});
return tile;
}
drawTile({x, y, z}, context, scale) {
const key = `${ x },${ z != null ? z : y }`;
this.map[key] = this.map[key] || this.createTile({
x, y,
drawStyle: this.settings.style,
tileStyle: this.settings.tile,
orientation: this.settings.orientation,
});
let tile = this.map[key];
const pixelPoint = this.tessellate.tileToPixel(x, y, z);
const fadeFactor = this.gray ? Math.min((Date.now() - this.gray) / 5000, 1) : null;
tile = this.gray ? this.fadeToGray(tile, fadeFactor) : tile;
Tessellate.TILES[tile.tileStyle][tile.drawStyle](context, scale, pixelPoint.getX(), pixelPoint.getY(), tile);
Tessellate.Shapes.pips(context, scale, pixelPoint.getX(), pixelPoint.getY(), tile);
}
draw({context, height, width, scale, tilePoints, now, lastNow}) {
this.fps.frame(now, lastNow);
Tessellate.Shapes.background(context, height, width, {
red: 64,
green: 32,
blue: 128,
});
tilePoints.forEach(tilePoint => this.drawTile(tilePoint, context, scale));
this.ripples.forEach(({timestamp, cell}) => {
const pressFactor = Math.min((now - timestamp) / PRESS_RIPPLE, 1);
Object.assign(cell, {scale: pressRipple(pressFactor)});
Object.assign(cell.color, {alpha: pressFade(pressFactor)});
const pixelPoint = this.tessellate.tileToPixel(cell.x, cell.y);
Tessellate.TILES[cell.tileStyle][cell.drawStyle](context, scale, pixelPoint.getX(), pixelPoint.getY(), cell);
});
this.ripples = this.ripples.filter(ripple => (ripple.timestamp + PRESS_RIPPLE) > now);
this.taps.forEach(cell => {
const pixelPoint = this.tessellate.tileToPixel(cell.x, cell.y);
Tessellate.TILES[cell.tileStyle][cell.drawStyle](context, scale, pixelPoint.getX(), pixelPoint.getY(), cell);
});
Tessellate.funky.forEach(this.mines, cell => {
const pixelPoint = this.tessellate.tileToPixel(cell.x, cell.y);
Tessellate.Shapes.mine(context, scale, pixelPoint.getX(), pixelPoint.getY());
});
}
}
let demo = new Demo();