add vp symbols
This commit is contained in:
parent
6213eda240
commit
3adf3bf76d
@ -1,13 +1,13 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { sampleCard1, sampleCard2, sampleCard3 } from "../sampleData.ts";
|
import { sampleCards } from "../sampleData.ts";
|
||||||
import { Card } from "./Card.tsx";
|
import { Card } from "./Card.tsx";
|
||||||
|
|
||||||
export const App = () => {
|
export const App = () => {
|
||||||
const [count, setCount] = useState(0);
|
const [count, setCount] = useState(0);
|
||||||
return <div>
|
return <div>
|
||||||
<Card key={`1-${count}`} card={sampleCard1}/>
|
{sampleCards.map((sampleCard) => {
|
||||||
<Card key={`2-${count}`} card={sampleCard2}/>
|
return <Card key={`${sampleCard.title}-${count}`} card={sampleCard}/>
|
||||||
<Card key={`3-${count}`} card={sampleCard3}/>
|
})}
|
||||||
<button onClick={() => {setCount(c => c+1)}}>Rerender (for fonts)</button>
|
<button onClick={() => {setCount(c => c+1)}}>Rerender (for fonts)</button>
|
||||||
</div>;
|
</div>;
|
||||||
};
|
};
|
||||||
|
@ -5,9 +5,12 @@ 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: "debt"; text: string }
|
type: "symbol";
|
||||||
| { type: "potion"; text: string };
|
symbol: "coin" | "debt" | "potion" | "vp" | "vp-token";
|
||||||
|
text: string;
|
||||||
|
textColor: string;
|
||||||
|
};
|
||||||
|
|
||||||
type PromiseOr<T> = T | Promise<T>;
|
type PromiseOr<T> = T | Promise<T>;
|
||||||
|
|
||||||
@ -124,14 +127,14 @@ const breakPiece = pieceDef({
|
|||||||
render() {},
|
render() {},
|
||||||
});
|
});
|
||||||
|
|
||||||
const coinPiece = pieceDef({
|
const symbolPiece = pieceDef({
|
||||||
type: "coin",
|
type: "symbol",
|
||||||
measure(context, _piece) {
|
measure(context, piece) {
|
||||||
context.save();
|
context.save();
|
||||||
const metrics = context.measureText(" ");
|
const metrics = context.measureText(" ");
|
||||||
const height =
|
const height =
|
||||||
metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent;
|
metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent;
|
||||||
const coinImage = getImage("coin");
|
const coinImage = getImage(piece.symbol);
|
||||||
context.restore();
|
context.restore();
|
||||||
return {
|
return {
|
||||||
type: "content",
|
type: "content",
|
||||||
@ -146,7 +149,7 @@ const coinPiece = pieceDef({
|
|||||||
const height = measure.ascent + measure.descent;
|
const height = measure.ascent + measure.descent;
|
||||||
// context.fillRect(x, y - measure.ascent, measure.width, height);
|
// context.fillRect(x, y - measure.ascent, measure.width, height);
|
||||||
context.drawImage(
|
context.drawImage(
|
||||||
getImage("coin"),
|
getImage(piece.symbol),
|
||||||
x,
|
x,
|
||||||
y - measure.ascent,
|
y - measure.ascent,
|
||||||
measure.width,
|
measure.width,
|
||||||
@ -158,103 +161,14 @@ const coinPiece = pieceDef({
|
|||||||
fontInfo.size = parseInt(fontInfo.size.toString()) * 1.2;
|
fontInfo.size = parseInt(fontInfo.size.toString()) * 1.2;
|
||||||
const font = stringifyFont(fontInfo);
|
const font = stringifyFont(fontInfo);
|
||||||
context.font = font;
|
context.font = font;
|
||||||
context.fillStyle = "black";
|
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.width / 2, y);
|
||||||
context.restore();
|
context.restore();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const debtPiece = pieceDef({
|
const pieceDefs = [textPiece, spacePiece, breakPiece, symbolPiece];
|
||||||
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;
|
||||||
|
|
||||||
@ -406,23 +320,28 @@ export const renderDominionText = async (
|
|||||||
|
|
||||||
export const parse = (text: string): Piece[] => {
|
export const parse = (text: string): Piece[] => {
|
||||||
const pieces: Piece[] = [];
|
const pieces: Piece[] = [];
|
||||||
|
const symbolMap = {
|
||||||
|
"$": { symbol: "coin", textColor: "black" },
|
||||||
|
"@": { symbol: "debt", textColor: "white" },
|
||||||
|
"^": { symbol: "potion", textColor: "white" },
|
||||||
|
"%": { symbol: "vp", textColor: "white" },
|
||||||
|
"#": { symbol: "vp-token", textColor: "black" },
|
||||||
|
} 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 === "$") {
|
} else if (char && char in symbolMap) {
|
||||||
const end = text.slice(i).match(/\$\d*/)![0].length;
|
const c = char as keyof typeof symbolMap;
|
||||||
pieces.push({ type: "coin", text: text.slice(i + 1, i + end) });
|
const end = text.slice(i).match(new RegExp(`\\${c}\\w*`))![0]
|
||||||
i += end - 1;
|
.length;
|
||||||
} else if (char === "@") {
|
pieces.push({
|
||||||
const end = text.slice(i).match(/@\d*/)![0].length;
|
type: "symbol",
|
||||||
pieces.push({ type: "debt", text: text.slice(i + 1, i + end) });
|
...symbolMap[c],
|
||||||
i += end - 1;
|
text: text.slice(i + 1, i + end),
|
||||||
} 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;
|
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+/);
|
||||||
|
@ -59,6 +59,14 @@ const imageList = [
|
|||||||
key: "potion",
|
key: "potion",
|
||||||
src: "/static/assets/Potion.png",
|
src: "/static/assets/Potion.png",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: "vp",
|
||||||
|
src: "/static/assets/VP.png",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "vp-token",
|
||||||
|
src: "/static/assets/VP-Token.png",
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const loadImages = async () => {
|
export const loadImages = async () => {
|
||||||
|
@ -3,45 +3,58 @@ import {
|
|||||||
TYPE_ACTION,
|
TYPE_ACTION,
|
||||||
TYPE_REACTION,
|
TYPE_REACTION,
|
||||||
TYPE_TREASURE,
|
TYPE_TREASURE,
|
||||||
|
TYPE_VICTORY,
|
||||||
} from "./types.ts";
|
} from "./types.ts";
|
||||||
|
|
||||||
export const sampleCard1: DominionCard = {
|
export const sampleCards: DominionCard[] = [
|
||||||
orientation: "card",
|
{
|
||||||
title: "Title",
|
orientation: "card",
|
||||||
description:
|
title: "Title",
|
||||||
"+1 Action\n\nReveal the top card of your deck. If it's an Action card, +1 Action.",
|
description:
|
||||||
types: [TYPE_ACTION, TYPE_REACTION],
|
"+1 Action\n\nReveal the top card of your deck. If it's an Action card, +1 Action. If it has ^ in its cost, +1 Card.",
|
||||||
image: "https://wiki.dominionstrategy.com/images/7/76/AdventurerArt.jpg",
|
types: [TYPE_ACTION, TYPE_REACTION],
|
||||||
artist: "Dall-E",
|
image: "https://wiki.dominionstrategy.com/images/7/76/AdventurerArt.jpg",
|
||||||
author: "John Doe",
|
artist: "Dall-E",
|
||||||
version: "",
|
author: "John Doe",
|
||||||
cost: "@8",
|
version: "",
|
||||||
preview: "",
|
cost: "@8",
|
||||||
};
|
preview: "",
|
||||||
|
},
|
||||||
export const sampleCard2: DominionCard = {
|
{
|
||||||
orientation: "card",
|
orientation: "card",
|
||||||
title: "Market",
|
title: "Market",
|
||||||
description: "+1 Card\n+1 Action\n+1 Buy\n+$1",
|
description: "+1 Card\n+1 Action\n+1 Buy\n+$1",
|
||||||
types: [TYPE_ACTION],
|
types: [TYPE_ACTION],
|
||||||
image: "",
|
image: "",
|
||||||
artist: "Leonardo DaVinci",
|
artist: "Leonardo DaVinci",
|
||||||
author: "Jane Smith",
|
author: "Jane Smith",
|
||||||
version: "",
|
version: "",
|
||||||
cost: "$4",
|
cost: "$4",
|
||||||
preview: "",
|
preview: "",
|
||||||
};
|
},
|
||||||
|
{
|
||||||
export const sampleCard3: DominionCard = {
|
orientation: "card",
|
||||||
orientation: "card",
|
title: "Flask",
|
||||||
title: "Flask",
|
description:
|
||||||
description:
|
"+2 Cards\n\nAt the start of your Clean-up phase, you may put a card from your hand onto your deck.",
|
||||||
"+2 Cards\n\nAt the start of your Clean-up phase, you may put a card from your hand onto your deck.",
|
types: [TYPE_TREASURE],
|
||||||
types: [TYPE_TREASURE],
|
image: "",
|
||||||
image: "",
|
artist: "",
|
||||||
artist: "",
|
author: "",
|
||||||
author: "",
|
version: "",
|
||||||
version: "",
|
cost: "$6",
|
||||||
cost: "$6",
|
preview: "",
|
||||||
preview: "",
|
},
|
||||||
};
|
{
|
||||||
|
orientation: "card",
|
||||||
|
title: "Flask",
|
||||||
|
description: "+1 #\n\n-\n\n2 %",
|
||||||
|
types: [TYPE_VICTORY],
|
||||||
|
image: "",
|
||||||
|
artist: "",
|
||||||
|
author: "",
|
||||||
|
version: "",
|
||||||
|
cost: "$6",
|
||||||
|
preview: "",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user