Switch to deno
This commit is contained in:
parent
5ec05e3db7
commit
b81144153b
5
.gitignore
vendored
5
.gitignore
vendored
@ -1 +1,6 @@
|
||||
node_modules
|
||||
|
||||
# dotenv environment variable files
|
||||
.env
|
||||
|
||||
**/dist/**/*
|
||||
|
39
deno.json
Normal file
39
deno.json
Normal file
@ -0,0 +1,39 @@
|
||||
{
|
||||
"lock": false,
|
||||
"tasks": {
|
||||
"build": "deno run -A tools/build.ts",
|
||||
"serve": "deno run -A src/server/index.ts"
|
||||
},
|
||||
"lint": {
|
||||
"rules": {
|
||||
"tags": [
|
||||
"recommended"
|
||||
]
|
||||
}
|
||||
},
|
||||
"exclude": [
|
||||
"dist"
|
||||
],
|
||||
"imports": {
|
||||
"react/": "https://esm.sh/react@18.3.1/",
|
||||
"react-dom/": "https://esm.sh/react-dom@18.3.1/client/",
|
||||
"react": "https://esm.sh/react@18.3.1",
|
||||
"react-dom": "https://esm.sh/react-dom@18.3.1/client",
|
||||
"canvas": "https://esm.sh/canvas@3.0.0"
|
||||
},
|
||||
"compilerOptions": {
|
||||
"lib": ["deno.ns", "DOM"],
|
||||
"jsx": "react-jsx",
|
||||
"jsxImportSource": "react",
|
||||
"strict": true,
|
||||
"exactOptionalPropertyTypes": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"noImplicitOverride": true,
|
||||
"noImplicitReturns": true,
|
||||
"allowUnusedLabels": false
|
||||
},
|
||||
"fmt": {
|
||||
"useTabs": true
|
||||
}
|
||||
}
|
1048
package-lock.json
generated
1048
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,5 +0,0 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"canvas": "^2.11.2"
|
||||
}
|
||||
}
|
3
root.ts
Normal file
3
root.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { dirname, fromFileUrl } from "jsr:@std/path";
|
||||
|
||||
export const projectRootDir = dirname(fromFileUrl(import.meta.url));
|
6
src/client/App.tsx
Normal file
6
src/client/App.tsx
Normal file
@ -0,0 +1,6 @@
|
||||
import { sampleCard } from "../sampleData.ts";
|
||||
import { Card } from "./Card.tsx";
|
||||
|
||||
export const App = () => {
|
||||
return <div><Card card={sampleCard}/></div>;
|
||||
};
|
26
src/client/Card.tsx
Normal file
26
src/client/Card.tsx
Normal file
@ -0,0 +1,26 @@
|
||||
import { drawCard } from "../draw.ts";
|
||||
import { DominionCard } from "../types.ts";
|
||||
|
||||
const sizeMap = {
|
||||
card: {
|
||||
width: 1403,
|
||||
height: 2151,
|
||||
},
|
||||
landscape: {
|
||||
width: 2151,
|
||||
height: 1403,
|
||||
}
|
||||
}
|
||||
|
||||
export const Card = (props: {card: DominionCard}) => {
|
||||
const {card} = props;
|
||||
const {width, height} = sizeMap[card.orientation];
|
||||
return <canvas style={{width: "2.5in"}} width={width} height={height} ref={(canvasElement) => {
|
||||
if (canvasElement) {
|
||||
const context = canvasElement.getContext("2d");
|
||||
if (context) {
|
||||
drawCard(context, card);
|
||||
}
|
||||
}
|
||||
}}></canvas>
|
||||
}
|
14
src/client/index.tsx
Normal file
14
src/client/index.tsx
Normal file
@ -0,0 +1,14 @@
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom";
|
||||
import { App } from "./App.tsx";
|
||||
|
||||
const rootElement = document.getElementById("root");
|
||||
if (!rootElement) {
|
||||
throw Error("No root element to attach react to.");
|
||||
}
|
||||
|
||||
createRoot(rootElement).render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>,
|
||||
);
|
39
src/draw.ts
39
src/draw.ts
@ -1,22 +1,31 @@
|
||||
import { DominionCard } from "./types"
|
||||
import { createCanvas } from "canvas"
|
||||
import { DominionCard } from "./types.ts";
|
||||
|
||||
export const drawCard = (card: DominionCard): Promise<string> => {
|
||||
export const drawCard = (
|
||||
context: CanvasRenderingContext2D,
|
||||
card: DominionCard
|
||||
): Promise<void> => {
|
||||
if (card.orientation === "card") {
|
||||
return drawStandardCard(card);
|
||||
return drawStandardCard(context, card);
|
||||
} else {
|
||||
return drawLandscapeCard(card);
|
||||
return drawLandscapeCard(context, card);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const drawStandardCard = async (card: DominionCard): Promise<string> => {
|
||||
const canvas = createCanvas(1403, 2151);
|
||||
const context = canvas.getContext("2d");
|
||||
const drawStandardCard = async (
|
||||
context: CanvasRenderingContext2D,
|
||||
card: DominionCard
|
||||
): Promise<void> => {
|
||||
const w = context.canvas.width;
|
||||
const h = context.canvas.height;
|
||||
context.save();
|
||||
context.fillStyle = "brown";
|
||||
context.fillRect(0, 0, w, h);
|
||||
context.restore();
|
||||
};
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
const drawLandscapeCard = async (card: DominionCard): Promise<string> => {
|
||||
const drawLandscapeCard = async (
|
||||
context: CanvasRenderingContext2D,
|
||||
card: DominionCard
|
||||
): Promise<void> => {
|
||||
// TODO: everything
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
0
src/isocanvas.ts
Normal file
0
src/isocanvas.ts
Normal file
@ -1,4 +1,4 @@
|
||||
import { DominionCard, TYPE_ACTION } from "./types";
|
||||
import { DominionCard, TYPE_ACTION } from "./types.ts";
|
||||
|
||||
export const sampleCard: DominionCard = {
|
||||
orientation: "card",
|
||||
@ -11,4 +11,4 @@ export const sampleCard: DominionCard = {
|
||||
version: "",
|
||||
price: "",
|
||||
preview: "",
|
||||
}
|
||||
};
|
||||
|
14
src/server/index.ts
Normal file
14
src/server/index.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { serveDir, serveFile } from "jsr:@std/http/file-server";
|
||||
|
||||
Deno.serve((req: Request) => {
|
||||
const pathname = new URL(req.url).pathname;
|
||||
|
||||
if (pathname.startsWith("/static")) {
|
||||
return serveDir(req, {
|
||||
fsRoot: "src/static",
|
||||
urlRoot: "static",
|
||||
});
|
||||
} else {
|
||||
return serveFile(req, "src/static/index.html");
|
||||
}
|
||||
});
|
12
src/static/index.html
Normal file
12
src/static/index.html
Normal file
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Dominionator</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script src="/static/dist/bundle.js"></script>
|
||||
</body>
|
||||
</html>
|
67
src/types.ts
67
src/types.ts
@ -9,7 +9,16 @@ export type DominionColor = {
|
||||
|
||||
export type DominionBasicCardType = {
|
||||
typeType: "basic";
|
||||
name: "Action" | "Treasure" | "Victory" | "Reaction" | "Duration" | "Reserve" | "Night" | "Attack" | "Command";
|
||||
name:
|
||||
| "Action"
|
||||
| "Treasure"
|
||||
| "Victory"
|
||||
| "Reaction"
|
||||
| "Duration"
|
||||
| "Reserve"
|
||||
| "Night"
|
||||
| "Attack"
|
||||
| "Command";
|
||||
color: null | DominionColor;
|
||||
};
|
||||
export type DominionBasicLandscapeType = {
|
||||
@ -19,9 +28,12 @@ export type DominionBasicLandscapeType = {
|
||||
};
|
||||
|
||||
export type DominionCardType = DominionBasicCardType | DominionCustomCardType;
|
||||
export type DominionLandscapeType = DominionBasicLandscapeType | DominionCustomLandscapeType;
|
||||
export type DominionLandscapeType =
|
||||
| DominionBasicLandscapeType
|
||||
| DominionCustomLandscapeType;
|
||||
|
||||
export type DominionCard = {
|
||||
export type DominionCard =
|
||||
| {
|
||||
orientation: "card";
|
||||
title: string;
|
||||
description: DominionText;
|
||||
@ -32,7 +44,8 @@ export type DominionCard = {
|
||||
version: string;
|
||||
price: DominionText;
|
||||
preview?: DominionText;
|
||||
} | {
|
||||
}
|
||||
| {
|
||||
orientation: "landscape";
|
||||
title: string;
|
||||
description: DominionText;
|
||||
@ -42,7 +55,7 @@ export type DominionCard = {
|
||||
author: string;
|
||||
version: string;
|
||||
price: DominionText;
|
||||
};
|
||||
};
|
||||
|
||||
export type DominionCustomSymbol = {
|
||||
image: string;
|
||||
@ -51,12 +64,12 @@ export type DominionCustomSymbol = {
|
||||
export type DominionCustomCardType = {
|
||||
typeType: "custom";
|
||||
name: string;
|
||||
color: DominionColor
|
||||
color: DominionColor;
|
||||
};
|
||||
export type DominionCustomLandscapeType = {
|
||||
typeType: "custom";
|
||||
name: string;
|
||||
color: DominionColor
|
||||
color: DominionColor;
|
||||
};
|
||||
|
||||
export type DominionExpansion = {
|
||||
@ -65,7 +78,7 @@ export type DominionExpansion = {
|
||||
customSymbols: Array<DominionCustomSymbol>;
|
||||
customCardTypes: Array<DominionCustomCardType>;
|
||||
customLandscapeTypes: Array<DominionCustomLandscapeType>;
|
||||
}
|
||||
};
|
||||
|
||||
export const TYPE_ACTION: DominionBasicCardType = {
|
||||
typeType: "basic",
|
||||
@ -73,8 +86,8 @@ export const TYPE_ACTION: DominionBasicCardType = {
|
||||
color: {
|
||||
value: "white",
|
||||
priority: 6,
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export const TYPE_TREASURE: DominionBasicCardType = {
|
||||
typeType: "basic",
|
||||
@ -82,8 +95,8 @@ export const TYPE_TREASURE: DominionBasicCardType = {
|
||||
color: {
|
||||
value: "yellow",
|
||||
priority: 5,
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export const TYPE_VICTORY: DominionBasicCardType = {
|
||||
typeType: "basic",
|
||||
@ -91,8 +104,8 @@ export const TYPE_VICTORY: DominionBasicCardType = {
|
||||
color: {
|
||||
value: "green",
|
||||
priority: 4,
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export const TYPE_REACTION: DominionBasicCardType = {
|
||||
typeType: "basic",
|
||||
@ -101,8 +114,8 @@ export const TYPE_REACTION: DominionBasicCardType = {
|
||||
value: "blue",
|
||||
priority: 1,
|
||||
overridesAction: true,
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export const TYPE_DURATION: DominionBasicCardType = {
|
||||
typeType: "basic",
|
||||
@ -111,18 +124,18 @@ export const TYPE_DURATION: DominionBasicCardType = {
|
||||
value: "orange",
|
||||
priority: 3,
|
||||
overridesAction: true,
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export const TYPE_RESERVE: DominionBasicCardType = {
|
||||
typeType: "basic",
|
||||
name: "Duration",
|
||||
color: {
|
||||
value: "orange",
|
||||
value: "brown",
|
||||
priority: 2, // unknown whether this should be above or below reaction/duration?
|
||||
overridesAction: true,
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export const TYPE_NIGHT: DominionBasicCardType = {
|
||||
typeType: "basic",
|
||||
@ -131,17 +144,17 @@ export const TYPE_NIGHT: DominionBasicCardType = {
|
||||
value: "black",
|
||||
priority: 6,
|
||||
onConflictDescriptionOnly: true,
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export const TYPE_ATTACK: DominionBasicCardType = {
|
||||
typeType: "basic",
|
||||
name: "Attack",
|
||||
color: null
|
||||
}
|
||||
color: null,
|
||||
};
|
||||
|
||||
export const TYPE_COMMAND: DominionBasicCardType = {
|
||||
typeType: "basic",
|
||||
name: "Command",
|
||||
color: null
|
||||
}
|
||||
color: null,
|
||||
};
|
||||
|
28
tools/build.ts
Normal file
28
tools/build.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import * as esbuild from "npm:esbuild";
|
||||
import { denoPlugins } from "jsr:@luca/esbuild-deno-loader";
|
||||
import browserslist from "npm:browserslist";
|
||||
import { projectRootDir } from "../root.ts";
|
||||
|
||||
const browsers = browserslist([
|
||||
"last 4 Chrome versions",
|
||||
"last 4 Edge versions",
|
||||
"last 4 Opera versions",
|
||||
"last 4 Firefox versions",
|
||||
"last 4 Safari versions",
|
||||
]).map((browser: string) => browser.replace(" ", ""));
|
||||
|
||||
// esbuild target is fine-grained: https://esbuild.github.io/api/#target
|
||||
const target = [...browsers, "ios18", "ios17", "ios16", "ios14"];
|
||||
await esbuild.build({
|
||||
plugins: [...denoPlugins()],
|
||||
absWorkingDir: projectRootDir,
|
||||
entryPoints: ["src/client/index.tsx"],
|
||||
outfile: "src/static/dist/bundle.js",
|
||||
bundle: true,
|
||||
format: "esm",
|
||||
target,
|
||||
jsx: "automatic",
|
||||
jsxImportSource: "react",
|
||||
});
|
||||
|
||||
esbuild.stop();
|
Loading…
x
Reference in New Issue
Block a user