Add debt and potion

This commit is contained in:
Dylan Pizzo 2025-01-06 21:06:13 -08:00
parent a5979647fc
commit 7f4268f960
3 changed files with 135 additions and 22 deletions

View File

@ -5,7 +5,9 @@ export type Piece =
| { type: "text"; text: string; isBold?: boolean; isItalic?: boolean } | { type: "text"; text: string; isBold?: boolean; isItalic?: boolean }
| { type: "space" } | { type: "space" }
| { type: "break" } | { type: "break" }
| { type: "coin"; text: string }; | { type: "coin"; text: string }
| { type: "debt"; text: string }
| { type: "potion"; text: string };
type PromiseOr<T> = T | Promise<T>; type PromiseOr<T> = T | Promise<T>;
@ -163,7 +165,96 @@ const coinPiece = pieceDef({
}, },
}); });
const pieceDefs = [textPiece, spacePiece, breakPiece, coinPiece]; const debtPiece = pieceDef({
type: "debt",
measure(context, _piece) {
context.save();
const metrics = context.measureText(" ");
const height =
metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent;
const coinImage = getImage("debt");
context.restore();
return {
type: "content",
width: coinImage.width * (height / coinImage.height),
ascent: metrics.fontBoundingBoxAscent,
descent: metrics.fontBoundingBoxDescent,
};
},
render(context, piece, x, y, measure) {
context.save();
// context.fillStyle = "yellow";
const height = measure.ascent + measure.descent;
// context.fillRect(x, y - measure.ascent, measure.width, height);
context.drawImage(
getImage("debt"),
x,
y - measure.ascent,
measure.width,
height
);
const fontInfo = parseFont(context.font);
fontInfo.family = ["DominionSpecial"];
fontInfo.weight = "bold";
fontInfo.size = parseInt(fontInfo.size.toString()) * 1.2;
const font = stringifyFont(fontInfo);
context.font = font;
context.fillStyle = "white";
context.textAlign = "center";
context.fillText(piece.text, x + measure.width / 2, y);
context.restore();
},
});
const potionPiece = pieceDef({
type: "potion",
measure(context, _piece) {
context.save();
const metrics = context.measureText(" ");
const height =
metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent;
const coinImage = getImage("potion");
context.restore();
return {
type: "content",
width: coinImage.width * (height / coinImage.height),
ascent: metrics.fontBoundingBoxAscent,
descent: metrics.fontBoundingBoxDescent,
};
},
render(context, piece, x, y, measure) {
context.save();
// context.fillStyle = "yellow";
const height = measure.ascent + measure.descent;
// context.fillRect(x, y - measure.ascent, measure.width, height);
context.drawImage(
getImage("potion"),
x,
y - measure.ascent,
measure.width,
height
);
const fontInfo = parseFont(context.font);
fontInfo.family = ["DominionSpecial"];
fontInfo.weight = "bold";
fontInfo.size = parseInt(fontInfo.size.toString()) * 1.2;
const font = stringifyFont(fontInfo);
context.font = font;
context.fillStyle = "white";
context.textAlign = "center";
context.fillText(piece.text, x + measure.width / 2, y);
context.restore();
},
});
const pieceDefs = [
textPiece,
spacePiece,
breakPiece,
coinPiece,
debtPiece,
potionPiece,
];
const tools: PieceTools = {} as any; const tools: PieceTools = {} as any;
@ -267,7 +358,7 @@ export const renderDominionText = async (
pieces: Piece[], pieces: Piece[],
x: number, x: number,
y: number, y: number,
maxWidth: number maxWidth = Infinity
) => { ) => {
const { lines, height } = await measureDominionText( const { lines, height } = await measureDominionText(
context, context,
@ -325,6 +416,14 @@ export const parse = (text: string): Piece[] => {
const end = text.slice(i).match(/\$\d*/)![0].length; const end = text.slice(i).match(/\$\d*/)![0].length;
pieces.push({ type: "coin", text: text.slice(i + 1, i + end) }); pieces.push({ type: "coin", text: text.slice(i + 1, i + end) });
i += end - 1; i += end - 1;
} else if (char === "@") {
const end = text.slice(i).match(/@\d*/)![0].length;
pieces.push({ type: "debt", text: text.slice(i + 1, i + end) });
i += end - 1;
} else if (char === "^") {
const end = text.slice(i).match(/\^\d*/)![0].length;
pieces.push({ type: "potion", text: text.slice(i + 1, i + end) });
i += end - 1;
} else if (char === "+") { } else if (char === "+") {
const match = text.slice(i).match(/\+\d* \S+/); const match = text.slice(i).match(/\+\d* \S+/);
if (match) { if (match) {

View File

@ -51,6 +51,14 @@ const imageList = [
key: "coin", key: "coin",
src: "/static/assets/Coin.png", src: "/static/assets/Coin.png",
}, },
{
key: "debt",
src: "/static/assets/Debt.png",
},
{
key: "potion",
src: "/static/assets/Potion.png",
},
]; ];
export const loadImages = async () => { export const loadImages = async () => {
@ -124,6 +132,7 @@ const drawStandardCard = async (
): Promise<void> => { ): Promise<void> => {
const w = context.canvas.width; const w = context.canvas.width;
const h = context.canvas.height; const h = context.canvas.height;
let size;
context.save(); context.save();
// Draw the image // Draw the image
const image = await loadImage(card.image); const image = await loadImage(card.image);
@ -151,8 +160,15 @@ const drawStandardCard = async (
context.drawImage(colorImage(getImage("card-brown"), "#ff9911"), 0, 0); context.drawImage(colorImage(getImage("card-brown"), "#ff9911"), 0, 0);
context.drawImage(getImage("card-description-focus"), 44, 1094); context.drawImage(getImage("card-description-focus"), 44, 1094);
// Draw the name // Draw the name
context.font = "78pt DominionTitle"; size = 78;
await renderDominionText(context, parse(card.title), w / 2, 220, 1100); context.font = `${size}pt DominionTitle`;
while (
(await measureDominionText(context, parse(card.title))).width > 1050
) {
size -= 1;
context.font = `${size}pt DominionTitle`;
}
await renderDominionText(context, parse(card.title), w / 2, 220);
// Draw the description // Draw the description
context.font = "60pt DominionText"; context.font = "60pt DominionText";
await renderDominionText( await renderDominionText(
@ -163,7 +179,7 @@ const drawStandardCard = async (
1000 1000
); );
// Draw the types // Draw the types
let size = 65; size = 65;
context.font = `${size}pt DominionTitle`; context.font = `${size}pt DominionTitle`;
while ( while (
( (
@ -185,18 +201,18 @@ const drawStandardCard = async (
); );
// Draw the cost // Draw the cost
context.font = "90pt DominionText"; context.font = "90pt DominionText";
await renderDominionText(context, parse(card.cost), 210, 1940, 200); const costMeasure = await measureDominionText(context, parse(card.cost));
await renderDominionText(
context,
parse(card.cost),
130 + costMeasure.width / 2,
1940
);
// Draw the preview // Draw the preview
if (card.preview) { if (card.preview) {
context.font = "90pt DominionText"; context.font = "90pt DominionText";
await renderDominionText(context, parse(card.preview), 200, 210, 200); await renderDominionText(context, parse(card.preview), 200, 210);
await renderDominionText( await renderDominionText(context, parse(card.preview), w - 200, 210);
context,
parse(card.preview),
w - 200,
210,
200
);
} }
// Draw the icon // Draw the icon
// Draw the author credit // Draw the author credit
@ -210,8 +226,7 @@ const drawStandardCard = async (
context, context,
parse(card.author), parse(card.author),
w - 150 - authorMeasure.width / 2, w - 150 - authorMeasure.width / 2,
2035, 2035
w / 2 - 150
); );
// Draw the artist credit // Draw the artist credit
const artistMeasure = await measureDominionText( const artistMeasure = await measureDominionText(
@ -222,8 +237,7 @@ const drawStandardCard = async (
context, context,
parse(card.artist), parse(card.artist),
155 + artistMeasure.width / 2, 155 + artistMeasure.width / 2,
2035, 2035
w / 2 - 150
); );
// Restore the context // Restore the context
context.restore(); context.restore();

View File

@ -15,7 +15,7 @@ export const sampleCard1: DominionCard = {
artist: "Dall-E", artist: "Dall-E",
author: "John Doe", author: "John Doe",
version: "", version: "",
cost: "$", cost: "@8",
preview: "", preview: "",
}; };
@ -35,12 +35,12 @@ export const sampleCard2: DominionCard = {
export const sampleCard3: DominionCard = { export const sampleCard3: DominionCard = {
orientation: "card", orientation: "card",
title: "Silver", title: "Silver",
description: "$2", description: "$2\n\n+@2",
types: [TYPE_TREASURE], types: [TYPE_TREASURE],
image: "", image: "",
artist: "", artist: "",
author: "", author: "",
version: "", version: "",
cost: "$3", cost: "$3^",
preview: "", preview: "",
}; };