Allow big symbols
This commit is contained in:
parent
52db63d395
commit
ff5c543147
@ -9,6 +9,8 @@ export type Piece =
|
|||||||
| {
|
| {
|
||||||
type: "symbol";
|
type: "symbol";
|
||||||
symbol: "coin" | "debt" | "potion" | "vp" | "vp-token";
|
symbol: "coin" | "debt" | "potion" | "vp" | "vp-token";
|
||||||
|
isBig?: boolean;
|
||||||
|
prefix?: string;
|
||||||
text: string;
|
text: string;
|
||||||
textColor: string;
|
textColor: string;
|
||||||
};
|
};
|
||||||
@ -157,13 +159,21 @@ const symbolPiece = pieceDef({
|
|||||||
const metrics = context.measureText(" ");
|
const metrics = context.measureText(" ");
|
||||||
const height =
|
const height =
|
||||||
metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent;
|
metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent;
|
||||||
|
const prefixMetrics = context.measureText(piece.prefix ?? "");
|
||||||
const coinImage = getImage(piece.symbol);
|
const coinImage = getImage(piece.symbol);
|
||||||
context.restore();
|
context.restore();
|
||||||
|
const { isBig } = piece;
|
||||||
|
const scale = isBig ? 2.5 : 1;
|
||||||
return {
|
return {
|
||||||
type: "content",
|
type: "content",
|
||||||
width: coinImage.width * (height / coinImage.height),
|
width:
|
||||||
ascent: metrics.fontBoundingBoxAscent,
|
scale *
|
||||||
descent: metrics.fontBoundingBoxDescent,
|
(prefixMetrics.width +
|
||||||
|
coinImage.width * (height / coinImage.height)),
|
||||||
|
ascent: scale * metrics.fontBoundingBoxAscent,
|
||||||
|
descent: scale * metrics.fontBoundingBoxDescent,
|
||||||
|
prefixWidth: scale * prefixMetrics.width,
|
||||||
|
scale,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
render(context, piece, x, y, measure) {
|
render(context, piece, x, y, measure) {
|
||||||
@ -173,20 +183,34 @@ const symbolPiece = pieceDef({
|
|||||||
// context.fillRect(x, y - measure.ascent, measure.width, height);
|
// context.fillRect(x, y - measure.ascent, measure.width, height);
|
||||||
context.drawImage(
|
context.drawImage(
|
||||||
getImage(piece.symbol),
|
getImage(piece.symbol),
|
||||||
x,
|
x + measure.prefixWidth,
|
||||||
y - measure.ascent,
|
y - measure.ascent,
|
||||||
measure.width,
|
measure.width - measure.prefixWidth,
|
||||||
height
|
height
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const prefixFontInfo = parseFont(context.font);
|
||||||
|
prefixFontInfo.weight = "bold";
|
||||||
|
prefixFontInfo.size =
|
||||||
|
parseInt(prefixFontInfo.size.toString()) * measure.scale;
|
||||||
|
const prefixFont = stringifyFont(prefixFontInfo);
|
||||||
|
context.font = prefixFont;
|
||||||
|
context.fillText(piece.prefix ?? "", x, y);
|
||||||
|
|
||||||
const fontInfo = parseFont(context.font);
|
const fontInfo = parseFont(context.font);
|
||||||
fontInfo.family = ["DominionSpecial"];
|
fontInfo.family = ["DominionSpecial"];
|
||||||
fontInfo.weight = "bold";
|
fontInfo.weight = "bold";
|
||||||
fontInfo.size = parseInt(fontInfo.size.toString()) * 1.2;
|
fontInfo.size =
|
||||||
|
parseInt(fontInfo.size.toString()) * 1.2 * measure.scale;
|
||||||
const font = stringifyFont(fontInfo);
|
const font = stringifyFont(fontInfo);
|
||||||
context.font = font;
|
context.font = font;
|
||||||
context.fillStyle = piece.textColor;
|
context.fillStyle = piece.textColor;
|
||||||
context.textAlign = "center";
|
context.textAlign = "center";
|
||||||
context.fillText(piece.text, x + measure.width / 2, y);
|
context.fillText(
|
||||||
|
piece.text,
|
||||||
|
x + measure.prefixWidth + (measure.width - measure.prefixWidth) / 2,
|
||||||
|
y
|
||||||
|
);
|
||||||
context.restore();
|
context.restore();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -341,7 +365,11 @@ export const renderDominionText = async (
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const parse = (text: string): Piece[] => {
|
export const parse = (
|
||||||
|
text: string,
|
||||||
|
options?: { isDescription: boolean }
|
||||||
|
): Piece[] => {
|
||||||
|
const { isDescription = false } = options ?? {};
|
||||||
const pieces: Piece[] = [];
|
const pieces: Piece[] = [];
|
||||||
const symbolMap = {
|
const symbolMap = {
|
||||||
"$": { symbol: "coin", textColor: "black" },
|
"$": { symbol: "coin", textColor: "black" },
|
||||||
@ -351,23 +379,28 @@ export const parse = (text: string): Piece[] => {
|
|||||||
"#": { symbol: "vp-token", textColor: "black" },
|
"#": { symbol: "vp-token", textColor: "black" },
|
||||||
} as const;
|
} as const;
|
||||||
for (let i = 0; i < text.length; i++) {
|
for (let i = 0; i < text.length; i++) {
|
||||||
const char = text[i];
|
const char = text[i]!;
|
||||||
if (char === " ") {
|
if (char === " ") {
|
||||||
pieces.push({ type: "space" });
|
pieces.push({ type: "space" });
|
||||||
} else if (char === "\n") {
|
} else if (char === "\n") {
|
||||||
pieces.push({ type: "break" });
|
pieces.push({ type: "break" });
|
||||||
} else if (char && char in symbolMap) {
|
} else if (char in symbolMap) {
|
||||||
const c = char as keyof typeof symbolMap;
|
const c = char as keyof typeof symbolMap;
|
||||||
const end = text.slice(i).match(new RegExp(`\\${c}\\w*`))![0]
|
const end = text.slice(i).match(new RegExp(`\\${c}\\w*`))![0]
|
||||||
.length;
|
.length;
|
||||||
|
const isBig =
|
||||||
|
isDescription &&
|
||||||
|
["\n", undefined].includes(text[i - 1]) &&
|
||||||
|
["\n", undefined].includes(text[i + end]);
|
||||||
pieces.push({
|
pieces.push({
|
||||||
type: "symbol",
|
type: "symbol",
|
||||||
...symbolMap[c],
|
...symbolMap[c],
|
||||||
text: text.slice(i + 1, i + end),
|
text: text.slice(i + 1, i + end),
|
||||||
|
isBig,
|
||||||
});
|
});
|
||||||
i += end - 1;
|
i += end - 1;
|
||||||
} else if (char === "+") {
|
} else if (char === "+") {
|
||||||
const match = text.slice(i).match(/\+\d* \w+/);
|
const match = text.slice(i).match(/\+\d*( \w+)?/);
|
||||||
if (match) {
|
if (match) {
|
||||||
const end = match[0].length;
|
const end = match[0].length;
|
||||||
pieces.push({
|
pieces.push({
|
||||||
@ -389,8 +422,42 @@ export const parse = (text: string): Piece[] => {
|
|||||||
text[i + 1] === "\n"
|
text[i + 1] === "\n"
|
||||||
) {
|
) {
|
||||||
pieces.push({ type: "hr" });
|
pieces.push({ type: "hr" });
|
||||||
|
} else if (/\d/.test(char)) {
|
||||||
|
const match = text.slice(i).match(
|
||||||
|
new RegExp(
|
||||||
|
`\\d+(${Object.keys(symbolMap)
|
||||||
|
.map((s) => `\\${s}`)
|
||||||
|
.join("|")})`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
if (match) {
|
||||||
|
const end = match[0].length;
|
||||||
|
const symbolChar = match[1] as keyof typeof symbolMap;
|
||||||
|
const isBig =
|
||||||
|
isDescription &&
|
||||||
|
["\n", undefined].includes(text[i - 1]) &&
|
||||||
|
["\n", undefined].includes(text[i + end]);
|
||||||
|
pieces.push({
|
||||||
|
type: "symbol",
|
||||||
|
...symbolMap[symbolChar],
|
||||||
|
prefix: text.slice(i, i + end - 1),
|
||||||
|
text: "",
|
||||||
|
isBig,
|
||||||
|
});
|
||||||
|
i += end - 1;
|
||||||
|
} else {
|
||||||
|
const end = text.slice(i).match(/\d+/)![0].length;
|
||||||
|
pieces.push({ type: "text", text: text.slice(i, i + end) });
|
||||||
|
i += end - 1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const end = text.slice(i).match(/[^$ \n]+/)![0].length;
|
const end = text.slice(i).match(
|
||||||
|
new RegExp(
|
||||||
|
`[^${Object.keys(symbolMap)
|
||||||
|
.map((s) => `\\${s}`)
|
||||||
|
.join("")} \n]+`
|
||||||
|
)
|
||||||
|
)![0].length;
|
||||||
pieces.push({ type: "text", text: text.slice(i, i + end) });
|
pieces.push({ type: "text", text: text.slice(i, i + end) });
|
||||||
i += end - 1;
|
i += end - 1;
|
||||||
}
|
}
|
||||||
|
@ -181,11 +181,12 @@ const drawStandardCard = async (
|
|||||||
context.font = "60pt DominionText";
|
context.font = "60pt DominionText";
|
||||||
await renderDominionText(
|
await renderDominionText(
|
||||||
context,
|
context,
|
||||||
parse(card.description),
|
parse(card.description, { isDescription: true }),
|
||||||
w / 2,
|
w / 2,
|
||||||
1490,
|
1490,
|
||||||
1000
|
1000
|
||||||
);
|
);
|
||||||
|
console.log(card.title, parse(card.description));
|
||||||
// Draw the types
|
// Draw the types
|
||||||
size = 65;
|
size = 65;
|
||||||
context.font = `${size}pt DominionTitle`;
|
context.font = `${size}pt DominionTitle`;
|
||||||
|
@ -48,7 +48,7 @@ export const sampleCards: DominionCard[] = [
|
|||||||
{
|
{
|
||||||
orientation: "card",
|
orientation: "card",
|
||||||
title: "VP Card",
|
title: "VP Card",
|
||||||
description: "+1 #\n\n-\n\n2 %",
|
description: "+1#\n\n\n-\n\n\n2%",
|
||||||
types: [TYPE_VICTORY],
|
types: [TYPE_VICTORY],
|
||||||
image: "",
|
image: "",
|
||||||
artist: "",
|
artist: "",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user