This commit is contained in:
Maciej Caderek
2022-01-26 09:44:37 +01:00
parent 0c2f804021
commit 6c401d1459
13 changed files with 308 additions and 57 deletions

View File

@@ -1,4 +1,4 @@
import { Move } from "chess.js";
import { Material, MoveWithPly } from "./../game/Game";
import { Style, BoardData } from "../types";
import drawRectangle from "./layers/drawRectangle";
import drawCoords from "./layers/drawCoords";
@@ -17,7 +17,7 @@ class Board {
private ctx: CanvasRenderingContext2D;
private tempCtx: CanvasRenderingContext2D;
private borderVisible: boolean = true;
private lastMove: Move | null = null;
private lastMove: MoveWithPly | null = null;
public canvas: HTMLCanvasElement = document.createElement("canvas");
private tempCanvas: HTMLCanvasElement = document.createElement("canvas");
private squareSize: number = 84;
@@ -88,7 +88,7 @@ class Board {
return this;
}
isCheck(move: Move | null) {
isCheck(move: MoveWithPly | null) {
if (!move) {
return false;
}
@@ -96,7 +96,7 @@ class Board {
return move.san.includes("+");
}
isMate(move: Move | null) {
isMate(move: MoveWithPly | null) {
if (!move) {
return false;
}
@@ -178,7 +178,8 @@ class Board {
async frame(
boardData: BoardData | null,
header: { [key: string]: string | undefined },
move: Move | null = null
move: MoveWithPly | null = null,
material?: Material
) {
this.lastMove = move;
this.boardData = boardData;
@@ -250,7 +251,9 @@ class Board {
this.margin,
this.style,
header,
this.flipped
this.flipped,
move?.end === 0,
material
);
}
}

View File

@@ -1,6 +1,16 @@
import { Material } from "../../game/Game";
import { Style } from "./../../types";
import drawText from "./drawText";
const chessFontMapping: { [key: string]: string } = {
k: "l",
q: "w",
r: "t",
b: "n",
n: "j",
p: "o",
};
const drawExtraInfo = async (
ctx: CanvasRenderingContext2D,
width: number,
@@ -10,47 +20,74 @@ const drawExtraInfo = async (
style: Style,
data: { [key: string]: string | undefined },
flipped: boolean,
lastMove: boolean = true
lastMove: boolean,
material?: Material
) => {
const fontSize = 20 * scale;
let offsetX = (margin - fontSize) / 2;
let offsetY = margin / 2;
const marginLeft = offsetX;
ctx.fillStyle = style.coords.onBorder;
const fontSize = 20 * scale;
const offsetX = (margin - fontSize) / 2;
const offsetY = margin / 2;
if (data.White) {
const text =
data.White +
(data.WhiteElo && data.WhiteElo !== "?" ? ` (${data.WhiteElo})` : "");
const w = drawText(
ctx,
data.White,
"Ubuntu",
fontSize,
700,
marginLeft,
(flipped ? offsetY : height - offsetY) * scale,
"left"
);
const elo =
data.WhiteElo && data.WhiteElo !== "?" ? ` ${data.WhiteElo}` : "";
drawText(
ctx,
text,
elo,
"Fira Mono",
fontSize,
500,
offsetX,
marginLeft + w,
(flipped ? offsetY : height - offsetY) * scale,
"left"
);
}
if (data.Black) {
const text =
data.Black +
(data.BlackElo && data.BlackElo !== "?" ? ` (${data.BlackElo})` : "");
const elo =
data.BlackElo && data.BlackElo !== "?" ? ` ${data.BlackElo}` : "";
const w = drawText(
ctx,
data.Black,
"Ubuntu",
fontSize,
700,
marginLeft,
(flipped ? height - offsetY : offsetY) * scale,
"left"
);
drawText(
ctx,
text,
elo,
"Fira Mono",
fontSize,
500,
offsetX,
marginLeft + w,
(flipped ? height - offsetY : offsetY) * scale,
"left"
);
}
let rightMarginWhite = 0;
let rightMarginBlack = 0;
if (lastMove && data.Result) {
const [resultWhite, resultBlack] = data.Result.split("-");
@@ -60,25 +97,96 @@ const drawExtraInfo = async (
const textBlack =
resultBlack === "0" ? "Lost" : resultBlack === "1" ? "Won" : "Draw";
drawText(
const widthWhite = drawText(
ctx,
textWhite,
"Ubuntu",
fontSize,
500,
700,
width - offsetX,
(flipped ? offsetY : height - offsetY) * scale,
"right"
);
drawText(
const widthBlack = drawText(
ctx,
textBlack,
"Ubuntu",
fontSize,
500,
700,
width - offsetX,
(flipped ? height - offsetY : offsetY) * scale,
"right"
);
const w = Math.max(widthWhite, widthBlack);
rightMarginWhite = w + 20 * scale;
rightMarginBlack = w + 20 * scale;
}
if (material) {
const textWhite = material.diff > 0 ? `+${Math.abs(material.diff)}` : "";
rightMarginWhite += drawText(
ctx,
textWhite,
"Fira Mono",
fontSize,
500,
width - offsetX - rightMarginWhite,
(flipped ? offsetY : height - offsetY) * scale,
"right"
);
const textBlack = material.diff < 0 ? `+${Math.abs(material.diff)}` : "";
rightMarginBlack += drawText(
ctx,
textBlack,
"Fira Mono",
fontSize,
500,
width - offsetX - rightMarginBlack,
(flipped ? height - offsetY : offsetY) * scale,
"right"
);
for (const [piece, count] of Object.entries(material.imbalance.w)) {
for (let i = 0; i < count; i++) {
const textWidth = drawText(
ctx,
chessFontMapping[piece],
"Chess",
fontSize,
500,
width - offsetX - rightMarginWhite,
(flipped ? offsetY : height - offsetY) * scale - 2 * scale,
"right"
);
rightMarginWhite +=
i === count - 1 || piece !== "p" ? textWidth * 0.8 : textWidth * 0.4;
}
}
for (const [piece, count] of Object.entries(material.imbalance.b)) {
for (let i = 0; i < count; i++) {
const textWidth = drawText(
ctx,
chessFontMapping[piece],
"Chess",
fontSize,
500,
width - offsetX - rightMarginBlack,
(flipped ? height - offsetY : offsetY) * scale - 2 * scale,
"right"
);
rightMarginBlack +=
i === count - 1 || piece !== "p" ? textWidth * 0.8 : textWidth * 0.4;
}
}
}
};

View File

@@ -52,13 +52,15 @@ const drawHeader = async (
ctx.clearRect(0, 0, size, size);
await drawRectangle(ctx, size, size + margin * 2, 0, 0, style.border);
const font = "Ubuntu";
const allSizes = [
{ key: "White", line: 60 * scale, font: 42 * scale, n: 0 },
{ key: "Black", line: 60 * scale, font: 42 * scale, n: 2 },
{ key: "Event", line: 30 * scale, font: 20 * scale, n: 4 },
{ key: "Round", line: 30 * scale, font: 20 * scale, n: 5 },
{ key: "Date", line: 30 * scale, font: 20 * scale, n: 7 },
{ key: "Site", line: 30 * scale, font: 20 * scale, n: 8 },
{ key: "White", line: 60 * scale, fontSize: 42 * scale, n: 0 },
{ key: "Black", line: 60 * scale, fontSize: 42 * scale, n: 2 },
{ key: "Event", line: 30 * scale, fontSize: 20 * scale, n: 4 },
{ key: "Round", line: 30 * scale, fontSize: 20 * scale, n: 5 },
{ key: "Date", line: 30 * scale, fontSize: 20 * scale, n: 7 },
{ key: "Site", line: 30 * scale, fontSize: 20 * scale, n: 8 },
];
const keys = new Set(Object.keys(data));
@@ -66,16 +68,16 @@ const drawHeader = async (
const sizes = allSizes.filter(({ key }) => keys.has(key));
if (data.White && data.Black) {
sizes.push({ key: "vs", line: 50, font: 20, n: 1 });
sizes.push({ key: "vs", line: 50, fontSize: 20, n: 1 });
}
if (data.Event || data.Round) {
sizes.push({ key: "margin", line: 100, font: 0, n: 3 });
sizes.push({ key: "margin", line: 100, fontSize: 0, n: 3 });
}
if (data.Date || data.Site) {
const line = data.Event || data.Round ? 20 : 100;
sizes.push({ key: "margin", line, font: 0, n: 6 });
sizes.push({ key: "margin", line, fontSize: 0, n: 6 });
}
const totalHeight = sizes.reduce((a, b) => a + b.line, 0);
@@ -85,10 +87,10 @@ const drawHeader = async (
sizes
.sort((a, b) => a.n - b.n)
.forEach(({ key, line, font }) => {
.forEach(({ key, line, fontSize }) => {
if (key === "vs") {
const y = fromTop + line / 2;
drawText(ctx, "vs", font, 700, size / 2, y, "center");
drawText(ctx, "vs", font, fontSize, 700, size / 2, y, "center");
fromTop += line;
return;
@@ -113,7 +115,17 @@ const drawHeader = async (
const y = fromTop + line / 2;
drawText(ctx, text, font, 700, size / 2, y, "center", size * 0.9);
drawText(
ctx,
text,
font,
fontSize,
700,
size / 2,
y,
"center",
size * 0.9
);
}
fromTop += line;

View File

@@ -1,6 +1,7 @@
const drawText = (
ctx: CanvasRenderingContext2D,
text: string,
font: string,
fontSize: number,
fontWeight: number,
x: number,
@@ -8,10 +9,12 @@ const drawText = (
align: CanvasTextAlign,
maxWidth?: number
) => {
ctx.font = `${fontWeight} ${fontSize}px Ubuntu`;
ctx.font = `${fontWeight} ${fontSize}px ${font}`;
ctx.textAlign = align;
ctx.textBaseline = "middle";
ctx.fillText(text, x, y, maxWidth);
return Math.ceil(ctx.measureText(text).width);
};
export default drawText;