From 9482b113191b622d67a7227379fbe2c6e3b50dc6 Mon Sep 17 00:00:00 2001 From: Maciej Caderek Date: Mon, 17 Jan 2022 04:54:19 +0100 Subject: [PATCH] WIP --- src/board/Board.ts | 41 +++++++++++++++++++------- src/board/layers/drawCoords.ts | 14 +++++++-- src/board/layers/drawMoveIndicators.ts | 26 +++++++++++++--- src/board/styles-board/avocado.ts | 11 ++++--- src/board/styles-board/calm.ts | 11 ++++--- src/board/styles-board/glass.ts | 11 ++++--- src/board/styles-board/index.ts | 4 +-- src/board/styles-board/kittens.ts | 19 ++++++------ src/board/styles-board/lichess.ts | 18 +++++------ src/board/styles-board/lila.ts | 11 ++++--- src/board/styles-board/mono.ts | 11 ++++--- src/board/styles-board/peach.ts | 13 ++++---- src/board/styles-board/standard.ts | 11 ++++--- src/game/Game.ts | 4 +++ src/main.ts | 8 +++-- src/types.ts | 13 +++++--- 16 files changed, 140 insertions(+), 86 deletions(-) diff --git a/src/board/Board.ts b/src/board/Board.ts index 54378d5..19f22e0 100644 --- a/src/board/Board.ts +++ b/src/board/Board.ts @@ -13,20 +13,23 @@ class Board { private flipped: boolean = false; private boardData: BoardData | null = null; private ctx: CanvasRenderingContext2D; + private tempCtx: CanvasRenderingContext2D; private borderVisible: boolean = true; private lastMove: Move | null = null; public canvas: HTMLCanvasElement = document.createElement("canvas"); + private tempCanvas: HTMLCanvasElement = document.createElement("canvas"); constructor(private tiles: number = 8) { - this.canvas; const ctx = this.canvas.getContext("2d"); + const tempCtx = this.tempCanvas.getContext("2d"); this.canvas.classList.add("board"); - if (ctx == null) { + if (ctx === null || tempCtx === null) { throw new Error("Cannot create canvas 2D context"); } this.ctx = ctx; + this.tempCtx = tempCtx; this.setSize(this.size); } @@ -34,6 +37,8 @@ class Board { this.size = size; this.canvas.width = size; this.canvas.height = size; + this.tempCanvas.width = size; + this.tempCanvas.height = size; return this; } @@ -86,6 +91,13 @@ class Board { return color === "w" ? "b" : "w"; } + async renderTitleScreen(header: { [key: string]: string | undefined }) { + this.tempCtx.clearRect(0, 0, this.size, this.size); + await drawSquare(this.tempCtx, this.size, 0, 0, this.style.border); + + this.ctx.drawImage(this.tempCanvas, 0, 0); + } + async render(boardData: BoardData | null, move: Move | null = null) { this.lastMove = move; this.boardData = boardData; @@ -106,13 +118,19 @@ class Board { ? this.getOppositeColor(move?.color) : undefined; - this.ctx.clearRect(0, 0, this.size, this.size); + this.tempCtx.clearRect(0, 0, this.size, this.size); - await drawSquare(this.ctx, innerSize, borderWidth, borderWidth, background); + await drawSquare( + this.tempCtx, + innerSize, + borderWidth, + borderWidth, + background + ); if (hasBorder) { await drawBorder( - this.ctx, + this.tempCtx, this.size - borderWidth, borderWidth / 2, borderWidth / 2, @@ -132,12 +150,12 @@ class Board { const x = file * squareSize + borderWidth; const y = rank * squareSize + borderWidth; - await drawSquare(this.ctx, squareSize, x, y, style); + await drawSquare(this.tempCtx, squareSize, x, y, style); } } drawCoords( - this.ctx, + this.tempCtx, coords, squareSize, this.tiles, @@ -149,10 +167,10 @@ class Board { if (boardData !== null) { if (this.lastMove) { drawMoveIndicators( - this.ctx, + this.tempCtx, this.lastMove, squareSize, - moveIndicator, + this.style, borderWidth, this.tiles, this.flipped @@ -160,7 +178,7 @@ class Board { } await drawPieces( - this.ctx, + this.tempCtx, boardData, squareSize, borderWidth, @@ -171,6 +189,9 @@ class Board { true ); } + + this.ctx.clearRect(0, 0, this.size, this.size); + this.ctx.drawImage(this.tempCanvas, 0, 0); } toImgUrl() { diff --git a/src/board/layers/drawCoords.ts b/src/board/layers/drawCoords.ts index 7396a52..8ec133c 100644 --- a/src/board/layers/drawCoords.ts +++ b/src/board/layers/drawCoords.ts @@ -39,7 +39,12 @@ const drawCoords = ( ctx.font = `${fontSize}px ${FONT_FAMILY}`; orderedRanks.forEach((v, i) => { - ctx.fillStyle = i % 2 === 0 ? coords.darkColor : coords.lightColor; + ctx.fillStyle = + borderWidth > 0 + ? coords.onBorder + : i % 2 === 0 + ? coords.onLight + : coords.onDark; ctx.textAlign = borderWidth > 0 ? "center" : "left"; ctx.fillText(v, offsetRankX, squareSize * i + fontSize + offsetRankY); @@ -49,7 +54,12 @@ const drawCoords = ( const orderedFiles = blackSide ? files.reverse() : files; orderedFiles.forEach((v, i) => { - ctx.fillStyle = i % 2 === 0 ? coords.lightColor : coords.darkColor; + ctx.fillStyle = + borderWidth > 0 + ? coords.onBorder + : i % 2 === 0 + ? coords.onDark + : coords.onLight; ctx.textAlign = borderWidth > 0 ? "center" : "left"; ctx.fillText( diff --git a/src/board/layers/drawMoveIndicators.ts b/src/board/layers/drawMoveIndicators.ts index 2b9749b..6d50870 100644 --- a/src/board/layers/drawMoveIndicators.ts +++ b/src/board/layers/drawMoveIndicators.ts @@ -1,5 +1,5 @@ import { Move } from "chess.js"; -import { SquareStyle } from "../../types"; +import { Style, SquareStyle } from "../../types"; import drawSquare from "./drawSquare"; const FILES = "abcdefghijklmnopqrstuwvxyz"; @@ -15,18 +15,36 @@ const drawMoveIndicators = async ( ctx: CanvasRenderingContext2D, move: Move, squareSize: number, - squareStyle: SquareStyle, + { dark, light, moveIndicator }: Style, borderWidth: number, tiles: number, flipped: boolean = false ) => { + const [x0, y0] = notationToXY(move.from, flipped, tiles); + const [x1, y1] = notationToXY(move.to, flipped, tiles); + const [fromX, fromY, toX, toY] = [ ...notationToXY(move.from, flipped, tiles), ...notationToXY(move.to, flipped, tiles), ].map((v) => v * squareSize + borderWidth); - drawSquare(ctx, squareSize, fromX, fromY, squareStyle); - drawSquare(ctx, squareSize, toX, toY, squareStyle); + let fromStyle; + let toStyle; + + if (moveIndicator.type === "hueShift") { + ctx.filter = `hue-rotate(${moveIndicator.data}deg)`; + fromStyle = (x0 + y0) % 2 === 0 ? light : dark; + toStyle = (x1 + y1) % 2 === 0 ? light : dark; + } else { + fromStyle = { + type: "solid", + data: { color: moveIndicator.data }, + } as SquareStyle; + toStyle = fromStyle; + } + + drawSquare(ctx, squareSize, fromX, fromY, fromStyle); + drawSquare(ctx, squareSize, toX, toY, toStyle); }; export default drawMoveIndicators; diff --git a/src/board/styles-board/avocado.ts b/src/board/styles-board/avocado.ts index 2e5acf9..d45faa2 100644 --- a/src/board/styles-board/avocado.ts +++ b/src/board/styles-board/avocado.ts @@ -21,10 +21,8 @@ const style: Style = { }, }, moveIndicator: { - type: "solid", - data: { - color: "#7D3EC155", - }, + type: "hueShift", + data: 70, }, border: { type: "solid", @@ -33,8 +31,9 @@ const style: Style = { }, }, coords: { - lightColor: "#ececa4", - darkColor: "#ececa4", + onLight: "#72b339", + onDark: "#ececa4", + onBorder: "#ececa4", }, }; diff --git a/src/board/styles-board/calm.ts b/src/board/styles-board/calm.ts index 5f7fdd9..c9a16e4 100644 --- a/src/board/styles-board/calm.ts +++ b/src/board/styles-board/calm.ts @@ -22,10 +22,8 @@ const style: Style = { }, }, moveIndicator: { - type: "solid", - data: { - color: "#0077ff00", - }, + type: "color", + data: "#ee59ff55", }, border: { type: "gradient", @@ -35,8 +33,9 @@ const style: Style = { }, }, coords: { - lightColor: "rgba(255, 255, 255, 0.9)", - darkColor: "rgba(255, 255, 255, 0.9)", + onLight: "rgba(0, 0, 0, 0.5)", + onDark: "rgba(255, 255, 255, 0.9)", + onBorder: "rgba(255, 255, 255, 0.9)", }, }; diff --git a/src/board/styles-board/glass.ts b/src/board/styles-board/glass.ts index 18da501..f7985d0 100644 --- a/src/board/styles-board/glass.ts +++ b/src/board/styles-board/glass.ts @@ -21,10 +21,8 @@ const style: Style = { }, }, moveIndicator: { - type: "solid", - data: { - color: "#0055ff77", - }, + type: "color", + data: "#00ffff55", }, border: { type: "solid", @@ -33,8 +31,9 @@ const style: Style = { }, }, coords: { - lightColor: "#222", - darkColor: "#222", + onLight: "#222", + onDark: "#ddd", + onBorder: "#ddd", }, }; diff --git a/src/board/styles-board/index.ts b/src/board/styles-board/index.ts index 166c649..9a21a4c 100644 --- a/src/board/styles-board/index.ts +++ b/src/board/styles-board/index.ts @@ -2,7 +2,7 @@ import avocado from "./avocado"; import calm from "./calm"; import standard from "./standard"; import glass from "./glass"; -// import kittens from "./kittens"; +import kittens from "./kittens"; import lichess from "./lichess"; import lila from "./lila"; import mono from "./mono"; @@ -12,7 +12,7 @@ export default { avocado, calm, glass, - // kittens, + kittens, lichess, lila, mono, diff --git a/src/board/styles-board/kittens.ts b/src/board/styles-board/kittens.ts index 3c858fd..1ef97fe 100644 --- a/src/board/styles-board/kittens.ts +++ b/src/board/styles-board/kittens.ts @@ -5,26 +5,24 @@ const style: Style = { background: { type: "image", data: { - src: "https://placekitten.com/1024/1024", + src: "https://placekitten.com/720/720", }, }, dark: { - type: "image", + type: "solid", data: { - src: "https://placekitten.com/128/128", + color: "#00000055", }, }, light: { type: "solid", data: { - color: "transparent", + color: "#ffffff55", }, }, moveIndicator: { - type: "solid", - data: { - color: "#0055ff77", - }, + type: "color", + data: "#ffff0055", }, border: { type: "solid", @@ -33,8 +31,9 @@ const style: Style = { }, }, coords: { - lightColor: "#eee", - darkColor: "#eee", + onLight: "#333", + onDark: "#eee", + onBorder: "#eee", }, }; diff --git a/src/board/styles-board/lichess.ts b/src/board/styles-board/lichess.ts index af617cc..e3116d2 100644 --- a/src/board/styles-board/lichess.ts +++ b/src/board/styles-board/lichess.ts @@ -21,21 +21,19 @@ const style: Style = { }, }, moveIndicator: { + type: "hueShift", + data: 40, + }, + border: { type: "solid", data: { - color: "rgba(155,199,0,0.41)", + color: "#896d56", }, }, - border: null, - // border: { - // type: "solid", - // data: { - // color: "#896d56", - // }, - // }, coords: { - lightColor: "#f0d9b5", - darkColor: "#b58863", + onLight: "#b58863", + onDark: "#f0d9b5", + onBorder: "#f0d9b5", }, }; diff --git a/src/board/styles-board/lila.ts b/src/board/styles-board/lila.ts index e58f40a..0f41531 100644 --- a/src/board/styles-board/lila.ts +++ b/src/board/styles-board/lila.ts @@ -21,10 +21,8 @@ const style: Style = { }, }, moveIndicator: { - type: "solid", - data: { - color: "#0055ff77", - }, + type: "hueShift", + data: 180, }, border: { type: "solid", @@ -33,8 +31,9 @@ const style: Style = { }, }, coords: { - lightColor: "#e5d0cb", - darkColor: "#e5d0cb", + onLight: "#c0acb5", + onDark: "#e5d0cb", + onBorder: "#e5d0cb", }, }; diff --git a/src/board/styles-board/mono.ts b/src/board/styles-board/mono.ts index c939f1e..d77cb3b 100644 --- a/src/board/styles-board/mono.ts +++ b/src/board/styles-board/mono.ts @@ -21,10 +21,8 @@ const style: Style = { }, }, moveIndicator: { - type: "solid", - data: { - color: "#0055ff77", - }, + type: "color", + data: "#00ff0044", }, border: { type: "solid", @@ -33,8 +31,9 @@ const style: Style = { }, }, coords: { - lightColor: "#eee", - darkColor: "#eee", + onLight: "#bbb", + onDark: "#eee", + onBorder: "#eee", }, }; diff --git a/src/board/styles-board/peach.ts b/src/board/styles-board/peach.ts index 6553991..f33139d 100644 --- a/src/board/styles-board/peach.ts +++ b/src/board/styles-board/peach.ts @@ -21,16 +21,19 @@ const style: Style = { }, }, moveIndicator: { + type: "hueShift", + data: 330, + }, + border: { type: "solid", data: { - // color: "#0055ff77", - color: "transparent", + color: "#962c2c", }, }, - border: null, coords: { - lightColor: "#ffa987", - darkColor: "#e54b4b", + onLight: "#e54b4b", + onDark: "#ffa987", + onBorder: "#ffa987", }, }; diff --git a/src/board/styles-board/standard.ts b/src/board/styles-board/standard.ts index 031bd74..e1d13ec 100644 --- a/src/board/styles-board/standard.ts +++ b/src/board/styles-board/standard.ts @@ -21,10 +21,8 @@ const style: Style = { }, }, moveIndicator: { - type: "solid", - data: { - color: "#0055ff55", - }, + type: "color", + data: "#0088ff66", }, border: { type: "solid", @@ -33,8 +31,9 @@ const style: Style = { }, }, coords: { - lightColor: "#eee", - darkColor: "#eee", + onLight: "#999", + onDark: "#eee", + onBorder: "#eee", }, }; diff --git a/src/game/Game.ts b/src/game/Game.ts index 31d8969..838bc48 100644 --- a/src/game/Game.ts +++ b/src/game/Game.ts @@ -78,6 +78,10 @@ class Game { return this.replay.board(); } + getHeader() { + return this.replay.header(); + } + pgn() { return this.game.pgn(); } diff --git a/src/main.ts b/src/main.ts index aa2eaa0..f6a7718 100644 --- a/src/main.ts +++ b/src/main.ts @@ -19,6 +19,8 @@ const play = async (board: Board, pgn: string | null, interval: number) => { } // game.goto(28); + // await board.renderTitleScreen(game.getHeader()); + // await delay(interval); await board.render(game.getBoardData()); while (true) { @@ -46,16 +48,16 @@ const createDownloadLink = async (pgn: string, style: Style) => { }; const main = async () => { - const style = styles.avocado; + const style = styles.calm; const hash = window.location.hash; const pgn = hash === "" ? null : decompressPGN(hash.slice(1)); const board = new Board(8).setStyle(style).setSize(720).showBorder(); - window.location.hash = "#alala"; - $app?.appendChild(board.canvas); + console.log(pgn); + play(board, pgn, 1000); // createDownloadLink(pgns[0], style).then((link) => { diff --git a/src/types.ts b/src/types.ts index 41de05d..c1b0b56 100644 --- a/src/types.ts +++ b/src/types.ts @@ -33,19 +33,24 @@ export type Image = { }; export type Coords = { - darkColor: string; - lightColor: string; + onLight: string; + onDark: string; + onBorder: string; }; export type SquareStyle = Gradient | Solid | Image; +export type MoveIndicator = + | { type: "hueShift"; data: number } + | { type: "color"; data: string }; + export type Style = { name: string; background: SquareStyle; light: SquareStyle; dark: SquareStyle; - moveIndicator: SquareStyle; - border: SquareStyle | null; + moveIndicator: MoveIndicator; + border: SquareStyle; coords: Coords; };