WIP
This commit is contained in:
@@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user