This commit is contained in:
Maciej Caderek
2022-01-28 01:23:28 +01:00
parent 6c401d1459
commit e000a0083a
24 changed files with 648 additions and 360 deletions

View File

@@ -1,3 +1,4 @@
import { BoardConfig, PiecesStyle } from "./../types";
import { Material, MoveWithPly } from "./../game/Game";
import { Style, BoardData } from "../types";
import drawRectangle from "./layers/drawRectangle";
@@ -8,27 +9,52 @@ import drawHeader from "./layers/drawHeader.ts";
import drawExtraInfo from "./layers/drawExtraInfo";
import boards from "./styles-board";
const defaultConfig: BoardConfig = {
size: 720,
boardStyle: boards.avocado,
piecesStyle: "gioco",
showBorder: true,
showExtraInfo: true,
showMaterial: true,
showMoveIndicator: true,
showChecks: true,
showCoords: true,
flipped: false,
};
class Board {
private size: number = 720;
private cfg: BoardConfig = defaultConfig;
private scale: number = 1;
private tiles: number = 8;
private size: number = 0;
private squareSize: number = 0;
private innerSize: number = 0;
private borderWidth: number = 0;
private margin: number = 0;
private style: Style = boards.standard;
private flipped: boolean = false;
// @ts-ignore
private header: { [key: string]: string | undefined } = {};
private boardData: BoardData | null = null;
private ctx: CanvasRenderingContext2D;
private tempCtx: CanvasRenderingContext2D;
private borderVisible: boolean = true;
private lastMove: MoveWithPly | null = null;
private lastMaterial: Material | undefined = undefined;
public canvas: HTMLCanvasElement = document.createElement("canvas");
private tempCanvas: HTMLCanvasElement = document.createElement("canvas");
private squareSize: number = 84;
private innerSize: number = 672;
private borderWidth: number = 24;
private background: HTMLCanvasElement | null = null;
private extraInfo: boolean = true;
private scale: number = 1;
private margin: number = 0;
private piecesStyle: PiecesStyle = "tatiana";
private showMaterial: boolean = true;
private showMoveIndicator: boolean = true;
private showCoords: boolean = true;
private showChecks: boolean = true;
private currentScreen: "title" | "move" = "move";
constructor(private tiles: number = 8) {
constructor(config: Partial<BoardConfig> = {}) {
const ctx = this.canvas.getContext("2d");
const tempCtx = this.tempCanvas.getContext("2d");
this.canvas.classList.add("board");
@@ -39,18 +65,62 @@ class Board {
this.ctx = ctx;
this.tempCtx = tempCtx;
this.setSize(this.size);
this.updateConfig(config, false);
}
async updateConfig(config: Partial<BoardConfig>, refresh: boolean = true) {
const cfg = { ...this.cfg, ...config };
this.cfg = cfg;
this.extraInfo = cfg.showExtraInfo;
this.piecesStyle = cfg.piecesStyle;
this.showMaterial = cfg.showMaterial;
this.showMoveIndicator = cfg.showMoveIndicator;
this.showCoords = cfg.showCoords;
this.showChecks = cfg.showChecks;
this.flipped = cfg.flipped;
this.borderVisible = cfg.showBorder;
this.setSize(cfg.size);
this.setStyle(cfg.boardStyle);
if (refresh) {
await this.refresh();
}
}
async refresh() {
await this.renderBackground();
if (this.currentScreen === "title") {
await this.titleFrame(this.header);
} else {
await this.frame(
this.boardData,
this.header,
this.lastMove,
this.lastMaterial
);
}
this.render();
}
setSize(size: number) {
this.size = size;
this.scale = size / 720;
this.margin = this.extraInfo ? 50 * this.scale : 0;
this.margin = this.extraInfo ? Math.round(50 * this.scale) : 0;
this.canvas.width = size;
this.canvas.height = size + this.margin * 2;
this.tempCanvas.width = size;
this.tempCanvas.height = size + this.margin * 2;
const height = size + this.margin * 2;
if (this.canvas.width !== size || this.canvas.height !== height) {
this.canvas.width = size;
this.canvas.height = height;
this.tempCanvas.width = size;
this.tempCanvas.height = height;
}
const tempBorderWidth = this.borderVisible ? this.size / 32 : 0;
const tempInnerSize = this.size - tempBorderWidth * 2;
@@ -72,19 +142,35 @@ class Board {
flip() {
this.flipped = !this.flipped;
// this.render(this.boardData, this.lastMove);
this.refresh();
return this;
}
hideBorder() {
this.borderVisible = false;
this.setSize(this.size);
this.refresh();
return this;
}
showBorder() {
this.borderVisible = true;
this.setSize(this.size);
this.refresh();
return this;
}
toggleBorder() {
this.borderVisible = !this.borderVisible;
this.setSize(this.size);
this.refresh();
return this;
}
toggleExtraInfo() {
this.extraInfo = !this.extraInfo;
this.setSize(this.size);
this.refresh();
return this;
}
@@ -113,6 +199,9 @@ class Board {
}
async titleFrame(header: { [key: string]: string | undefined }) {
this.currentScreen = "title";
this.header = header;
await drawHeader(
this.tempCtx,
this.size,
@@ -158,7 +247,7 @@ class Board {
}
}
if (this.borderVisible) {
if (this.borderVisible && this.showCoords) {
drawCoords(
ctx,
coords,
@@ -181,8 +270,10 @@ class Board {
move: MoveWithPly | null = null,
material?: Material
) {
this.currentScreen = "move";
this.lastMove = move;
this.boardData = boardData;
this.lastMaterial = material;
const check = this.isCheck(move)
? this.getOppositeColor(move?.color)
@@ -200,7 +291,7 @@ class Board {
this.tempCtx.drawImage((await this.background) as HTMLCanvasElement, 0, 0);
if (boardData !== null) {
if (this.lastMove) {
if (this.lastMove && this.showMoveIndicator) {
await drawMoveIndicators(
this.tempCtx,
this.lastMove,
@@ -213,7 +304,7 @@ class Board {
);
}
if (!this.borderVisible) {
if (!this.borderVisible && this.showCoords) {
drawCoords(
this.tempCtx,
this.style.coords,
@@ -236,10 +327,11 @@ class Board {
this.borderWidth,
this.tiles,
this.flipped,
check,
mate,
check && this.showChecks ? check : undefined,
mate && this.showChecks ? mate : undefined,
piecesShadow,
this.margin
this.margin,
this.piecesStyle
);
if (this.extraInfo && header) {
@@ -253,7 +345,7 @@ class Board {
header,
this.flipped,
move?.end === 0,
material
material && this.showMaterial ? material : undefined
);
}
}

View File

@@ -23,7 +23,7 @@ const drawExtraInfo = async (
lastMove: boolean,
material?: Material
) => {
const fontSize = 20 * scale;
const fontSize = Math.round(20 * scale);
let offsetX = (margin - fontSize) / 2;
let offsetY = margin / 2;
@@ -39,7 +39,7 @@ const drawExtraInfo = async (
fontSize,
700,
marginLeft,
(flipped ? offsetY : height - offsetY) * scale,
flipped ? offsetY : height - offsetY,
"left"
);
@@ -53,7 +53,7 @@ const drawExtraInfo = async (
fontSize,
500,
marginLeft + w,
(flipped ? offsetY : height - offsetY) * scale,
flipped ? offsetY : height - offsetY,
"left"
);
}
@@ -69,7 +69,7 @@ const drawExtraInfo = async (
fontSize,
700,
marginLeft,
(flipped ? height - offsetY : offsetY) * scale,
flipped ? height - offsetY : offsetY,
"left"
);
@@ -80,7 +80,7 @@ const drawExtraInfo = async (
fontSize,
500,
marginLeft + w,
(flipped ? height - offsetY : offsetY) * scale,
flipped ? height - offsetY : offsetY,
"left"
);
}
@@ -104,7 +104,7 @@ const drawExtraInfo = async (
fontSize,
700,
width - offsetX,
(flipped ? offsetY : height - offsetY) * scale,
flipped ? offsetY : height - offsetY,
"right"
);
@@ -115,7 +115,7 @@ const drawExtraInfo = async (
fontSize,
700,
width - offsetX,
(flipped ? height - offsetY : offsetY) * scale,
flipped ? height - offsetY : offsetY,
"right"
);
@@ -135,7 +135,7 @@ const drawExtraInfo = async (
fontSize,
500,
width - offsetX - rightMarginWhite,
(flipped ? offsetY : height - offsetY) * scale,
flipped ? offsetY : height - offsetY,
"right"
);
@@ -148,7 +148,7 @@ const drawExtraInfo = async (
fontSize,
500,
width - offsetX - rightMarginBlack,
(flipped ? height - offsetY : offsetY) * scale,
flipped ? height - offsetY : offsetY,
"right"
);
@@ -161,12 +161,16 @@ const drawExtraInfo = async (
fontSize,
500,
width - offsetX - rightMarginWhite,
(flipped ? offsetY : height - offsetY) * scale - 2 * scale,
(flipped ? offsetY : height - offsetY) - 2 * scale,
"right"
);
rightMarginWhite +=
i === count - 1 || piece !== "p" ? textWidth * 0.8 : textWidth * 0.4;
i === count - 1
? textWidth * 0.85
: piece === "p"
? textWidth * 0.4
: textWidth * 0.6;
}
}
@@ -179,12 +183,17 @@ const drawExtraInfo = async (
fontSize,
500,
width - offsetX - rightMarginBlack,
(flipped ? height - offsetY : offsetY) * scale - 2 * scale,
(flipped ? height - offsetY : offsetY) - 2 * scale,
"right"
);
rightMarginBlack +=
i === count - 1 || piece !== "p" ? textWidth * 0.8 : textWidth * 0.4;
i === count - 1
? textWidth * 0.85
: piece === "p"
? textWidth * 0.4
: textWidth * 0.6;
// i === count - 1 || piece !== "p" ? textWidth * 0.8 : textWidth * 0.4;
}
}
}

View File

@@ -1,4 +1,4 @@
import { BoardData, PieceType, PieceColor } from "../../types";
import { BoardData, PieceType, PieceColor, PiecesStyle } from "../../types";
import ImagesCache from "../loaders/PiecesCache";
const drawPieces = async (
@@ -11,7 +11,8 @@ const drawPieces = async (
check: "b" | "w" | undefined,
mate: "b" | "w" | undefined,
shadow: boolean,
margin: number
margin: number,
piecesStyle: PiecesStyle
) => {
for (let y = 0; y < 8; y++) {
for (let x = 0; x < 8; x++) {
@@ -20,7 +21,7 @@ const drawPieces = async (
type: PieceType;
color: PieceColor;
};
const img = await ImagesCache.get("tatiana", type, color);
const img = await ImagesCache.get(piecesStyle, type, color);
const rank = flipped ? tiles - 1 - y : y;
const file = flipped ? tiles - 1 - x : x;

View File

@@ -2,6 +2,7 @@ import { Style } from "../../types";
const style: Style = {
name: "Temp",
category: "custom",
background: {
type: "gradient",
data: {

View File

@@ -1,7 +1,8 @@
import { Style } from "../../types";
import { Style } from "../../../types";
const style: Style = {
name: "Avocado",
category: "colorful",
background: {
type: "solid",
data: {

View File

@@ -1,13 +1,8 @@
import { Style } from "../../types";
import { Style } from "../../../types";
const style: Style = {
name: "Calm",
// background: {
// type: "solid",
// data: {
// color: "transparent",
// },
// },
category: "gradient",
background: {
type: "gradient",
data: {

View File

@@ -0,0 +1,45 @@
import { Style } from "../../../types";
const style: Style = {
name: "Laguna",
category: "gradient",
background: {
type: "gradient",
data: {
dir: "diagonal-top",
colors: ["#3df5a7", "#096fe0"],
},
},
dark: {
type: "solid",
data: {
color: "transparent",
},
},
light: {
type: "solid",
data: {
color: "#ffffff55",
},
},
moveIndicator: {
type: "color",
data: "#3cff0055",
},
border: {
type: "gradient",
data: {
dir: "diagonal-top",
colors: ["#00b568", "#0052ad"],
},
},
coords: {
onLight: "#006f75",
onDark: "#fff",
onBorder: "#fff",
},
};
export default style;
// background-image: linear-gradient( 109.6deg, rgba(61,245,167,1) 11.2%, rgba(9,111,224,1) 91.1% );

View File

@@ -0,0 +1,50 @@
import { Style } from "../../../types";
const style: Style = {
name: "Rainbow Light",
category: "gradient",
background: {
type: "gradient",
data: {
dir: "vertical",
colors: [
"hsl(350, 100%, 60%)",
"hsl(35, 100%, 60%)",
"hsl(80, 100%, 60%)",
"hsl(125, 100%, 60%)",
"hsl(215, 100%, 60%)",
"hsl(260, 100%, 60%)",
"hsl(305, 100%, 60%)",
],
},
},
dark: {
type: "solid",
data: {
color: "#ffffff22",
},
},
light: {
type: "solid",
data: {
color: "#ffffff88",
},
},
moveIndicator: {
type: "color",
data: "#00ffff66",
},
border: {
type: "solid",
data: {
color: "#bd2f47",
},
},
coords: {
onLight: "#bd2f47",
onDark: "#000000bb",
onBorder: "#ffffffcc",
},
};
export default style;

View File

@@ -0,0 +1,50 @@
import { Style } from "../../../types";
const style: Style = {
name: "Rainbow",
category: "gradient",
background: {
type: "gradient",
data: {
dir: "vertical",
colors: [
"hsl(350, 70%, 50%)",
"hsl(35, 70%, 50%)",
"hsl(80, 70%, 50%)",
"hsl(125, 70%, 50%)",
"hsl(215, 70%, 50%)",
"hsl(260, 70%, 50%)",
"hsl(305, 70%, 50%)",
],
},
},
dark: {
type: "solid",
data: {
color: "#ffffff22",
},
},
light: {
type: "solid",
data: {
color: "#ffffff99",
},
},
moveIndicator: {
type: "color",
data: "#00ffff66",
},
border: {
type: "solid",
data: {
color: "#271936",
},
},
coords: {
onLight: "#271936",
onDark: "#271936",
onBorder: "#ffffffbb",
},
};
export default style;

View File

@@ -0,0 +1,45 @@
import { Style } from "../../../types";
const style: Style = {
name: "Sunset",
category: "gradient",
background: {
type: "gradient",
data: {
dir: "diagonal-top",
colors: ["hsl(32, 88%, 67%)", "hsl(342, 83%, 57%)"],
},
},
dark: {
type: "solid",
data: {
color: "rgba(0, 0, 0, 0)",
},
},
light: {
type: "solid",
data: {
color: "rgba(255, 255, 255, 0.5)",
},
},
moveIndicator: {
type: "color",
data: "#00ffee55",
},
border: {
type: "gradient",
data: {
dir: "diagonal-top",
colors: ["hsl(22, 68%, 57%)", "hsl(332, 63%, 47%)"],
},
},
coords: {
onLight: "hsl(332, 63%, 47%)",
onDark: "#fff",
onBorder: "#fff",
},
};
export default style;
// background-image: linear-gradient( 68.3deg, rgba(245,177,97,1) 0.4%, rgba(236,54,110,1) 100.2% );

View File

@@ -1,21 +1,30 @@
import avocado from "./avocado";
import calm from "./calm";
import standard from "./standard";
import kittens from "./kittens";
import lichess from "./lichess";
import lila from "./lila";
import mono from "./mono";
import peach from "./peach";
import temp from "./temp";
import lichess from "./mono/lichess";
import lila from "./mono/lila";
import peach from "./mono/peach";
import standard from "./mono/standard";
import violet from "./mono/violet";
import avocado from "./colorful/avocado";
import calm from "./gradient/calm";
import laguna from "./gradient/laguna";
import sunset from "./gradient/sunset";
import rainbow from "./gradient/rainbow";
import rainbowLight from "./gradient/rainbow-light";
import kittens from "./pic/kittens";
export default {
avocado,
calm,
kittens,
lichess,
lila,
mono,
peach,
standard,
temp,
violet,
avocado,
calm,
laguna,
sunset,
rainbow,
rainbowLight,
kittens,
};

View File

@@ -1,7 +1,8 @@
import { Style } from "../../types";
import { Style } from "../../../types";
const style: Style = {
name: "Lichess",
category: "mono",
background: {
type: "solid",
data: {

View File

@@ -1,7 +1,8 @@
import { Style } from "../../types";
import { Style } from "../../../types";
const style: Style = {
name: "Lila",
category: "mono",
background: {
type: "solid",
data: {

View File

@@ -1,7 +1,8 @@
import { Style } from "../../types";
import { Style } from "../../../types";
const style: Style = {
name: "Peach",
category: "mono",
background: {
type: "solid",
data: {

View File

@@ -1,7 +1,8 @@
import { Style } from "../../types";
import { Style } from "../../../types";
const style: Style = {
name: "Standard",
category: "mono",
background: {
type: "solid",
data: {

View File

@@ -1,39 +1,40 @@
import { Style } from "../../types";
import { Style } from "../../../types";
const style: Style = {
name: "Mono",
name: "Violet",
category: "mono",
background: {
type: "solid",
data: {
color: "transparent",
color: "#361b52",
},
},
dark: {
type: "solid",
data: {
color: "#bbb",
color: "#5d3e7d",
},
},
light: {
type: "solid",
data: {
color: "#eee",
color: "#cea9f5",
},
},
moveIndicator: {
type: "color",
data: "#00ff0044",
type: "hueShift",
data: 60,
},
border: {
type: "solid",
data: {
color: "#444",
color: "#271936",
},
},
coords: {
onLight: "#bbb",
onDark: "#eee",
onBorder: "#eee",
onLight: "#271936",
onDark: "#271936",
onBorder: "#cea9f5",
},
};

View File

@@ -1,7 +1,8 @@
import { Style } from "../../types";
import { Style } from "../../../types";
const style: Style = {
name: "Kittens",
category: "pic",
background: {
type: "image",
data: {

View File

@@ -4,7 +4,6 @@ import cburnett from "./cburnett";
import fantasy from "./fantasy";
import gioco from "./gioco";
import horsey from "./horsey";
import kilfiger from "./kilfiger";
import merida from "./merida";
import staunty from "./staunty";
import tatiana from "./tatiana";
@@ -16,7 +15,6 @@ const piecesSets = {
fantasy,
gioco,
horsey,
kilfiger,
merida,
staunty,
tatiana,

File diff suppressed because one or more lines are too long