🚀 improve demos
This commit is contained in:
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@@ -71,8 +71,6 @@ jobs:
|
||||
- uses: bahmutov/npm-install@v1.4.3
|
||||
|
||||
- run: yarn build:demo
|
||||
env:
|
||||
BASE_PATHNAME: "snk"
|
||||
|
||||
- uses: crazy-max/ghaction-github-pages@v2.1.3
|
||||
if: success() && github.ref == 'refs/heads/master'
|
||||
|
||||
@@ -55,5 +55,11 @@ export const createCanvas = ({
|
||||
drawLerpWorld(ctx, grid, snake0, snake1, stack, k, drawOptions);
|
||||
};
|
||||
|
||||
return { draw, drawLerp, canvas, ctx };
|
||||
const highlightCell = (x: number, y: number, color = "orange") => {
|
||||
ctx.fillStyle = color;
|
||||
ctx.beginPath();
|
||||
ctx.fillRect((1 + x + 0.5) * 16 - 2, (2 + y + 0.5) * 16 - 2, 4, 4);
|
||||
};
|
||||
|
||||
return { draw, drawLerp, highlightCell, canvas, ctx };
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import "./menu";
|
||||
import { createCanvas } from "./canvas";
|
||||
import { getHeadX, getHeadY, snakeToCells } from "@snk/types/snake";
|
||||
import { grid, snake } from "./sample";
|
||||
@@ -31,7 +32,7 @@ getAvailableRoutes(grid, snake, (chain) => {
|
||||
});
|
||||
solutions.sort((a, b) => a.color - b.color);
|
||||
|
||||
const { canvas, ctx, draw } = createCanvas(grid);
|
||||
const { canvas, ctx, draw, highlightCell } = createCanvas(grid);
|
||||
document.body.appendChild(canvas);
|
||||
|
||||
let k = 0;
|
||||
@@ -44,14 +45,12 @@ const onChange = () => {
|
||||
|
||||
draw(grid, chain[i], []);
|
||||
|
||||
ctx.fillStyle = "orange";
|
||||
chain
|
||||
.map(snakeToCells)
|
||||
.flat()
|
||||
.forEach(({ x, y }) => {
|
||||
ctx.beginPath();
|
||||
ctx.fillRect((1 + x + 0.5) * 16 - 2, (2 + y + 0.5) * 16 - 2, 4, 4);
|
||||
});
|
||||
.forEach(({ x, y }) => highlightCell(x, y));
|
||||
|
||||
highlightCell(2, 4);
|
||||
};
|
||||
|
||||
onChange();
|
||||
@@ -83,3 +82,8 @@ inputI.addEventListener("input", () => {
|
||||
onChange();
|
||||
});
|
||||
document.body.append(inputI);
|
||||
|
||||
window.addEventListener("click", (e) => {
|
||||
if (e.target === document.body || e.target === document.body.parentElement)
|
||||
inputK.focus();
|
||||
});
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import "./menu";
|
||||
import { createCanvas } from "./canvas";
|
||||
import { getBestRoute } from "@snk/compute/getBestRoute";
|
||||
import { Color, copyGrid } from "@snk/types/grid";
|
||||
@@ -14,7 +15,7 @@ const spring = { x: 0, v: 0, target: 0 };
|
||||
const springParams = { tension: 120, friction: 20, maxVelocity: 50 };
|
||||
let animationFrame: number;
|
||||
|
||||
const { canvas, drawLerp } = createCanvas(grid);
|
||||
const { canvas, highlightCell, drawLerp } = createCanvas(grid);
|
||||
document.body.appendChild(canvas);
|
||||
|
||||
const clamp = (x: number, a: number, b: number) => Math.max(a, Math.min(b, x));
|
||||
@@ -54,4 +55,7 @@ input.addEventListener("input", () => {
|
||||
animationFrame = requestAnimationFrame(loop);
|
||||
});
|
||||
document.body.append(input);
|
||||
document.body.addEventListener("click", () => input.focus());
|
||||
window.addEventListener("click", (e) => {
|
||||
if (e.target === document.body || e.target === document.body.parentElement)
|
||||
input.focus();
|
||||
});
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
import * as grid from "@snk/types/__fixtures__/grid";
|
||||
|
||||
const container = document.createElement("div");
|
||||
container.style.fontFamily = "helvetica";
|
||||
document.body.appendChild(container);
|
||||
|
||||
for (const demo of require("./demo.json").filter(
|
||||
(x: any) => !["index"].includes(x)
|
||||
)) {
|
||||
const title = document.createElement("h1");
|
||||
title.innerText = demo;
|
||||
|
||||
container.appendChild(title);
|
||||
|
||||
if (["interactive"].includes(demo)) {
|
||||
const a = document.createElement("a");
|
||||
a.style.display = "block";
|
||||
a.innerText = demo;
|
||||
a.href = `./${demo}.html`;
|
||||
|
||||
container.appendChild(a);
|
||||
} else
|
||||
for (const g of Object.keys(grid)) {
|
||||
const a = document.createElement("a");
|
||||
a.style.display = "block";
|
||||
a.innerText = `${demo} - ${g}`;
|
||||
a.href = `./${demo}.html?grid=${g}`;
|
||||
|
||||
container.appendChild(a);
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
["index", "getAvailableRoutes", "pruneLayer", "getBestRoute", "interactive"]
|
||||
["getAvailableRoutes", "pruneLayer", "getBestRoute", "interactive"]
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import "./menu";
|
||||
import { createCanvas } from "./canvas";
|
||||
import { Color, copyGrid } from "@snk/types/grid";
|
||||
import { grid, snake } from "./sample";
|
||||
@@ -14,7 +15,7 @@ for (const color of colors) {
|
||||
layers.push({ chunk, grid: copyGrid(grid0) });
|
||||
}
|
||||
|
||||
const { canvas, ctx, draw } = createCanvas(grid);
|
||||
const { canvas, ctx, highlightCell, draw } = createCanvas(grid);
|
||||
document.body.appendChild(canvas);
|
||||
|
||||
let k = 0;
|
||||
@@ -25,10 +26,7 @@ const loop = () => {
|
||||
draw(grid, snake, []);
|
||||
|
||||
ctx.fillStyle = "orange";
|
||||
chunk.forEach(({ x, y }) => {
|
||||
ctx.beginPath();
|
||||
ctx.fillRect((1 + x + 0.5) * 16 - 2, (2 + y + 0.5) * 16 - 2, 4, 4);
|
||||
});
|
||||
chunk.forEach(({ x, y }) => highlightCell(x, y));
|
||||
};
|
||||
|
||||
loop();
|
||||
@@ -45,4 +43,8 @@ input.addEventListener("input", () => {
|
||||
loop();
|
||||
});
|
||||
document.body.append(input);
|
||||
document.body.addEventListener("click", () => input.focus());
|
||||
|
||||
window.addEventListener("click", (e) => {
|
||||
if (e.target === document.body || e.target === document.body.parentElement)
|
||||
input.focus();
|
||||
});
|
||||
|
||||
38
packages/demo/menu.ts
Normal file
38
packages/demo/menu.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { GUI } from "dat.gui";
|
||||
import * as grids from "@snk/types/__fixtures__/grid";
|
||||
import * as snakes from "@snk/types/__fixtures__/snake";
|
||||
import { grid, snake } from "./sample";
|
||||
|
||||
const demos: string[] = require("./demo.json").filter(
|
||||
(x: any) => x !== "interactive"
|
||||
);
|
||||
|
||||
export const gui = new GUI();
|
||||
|
||||
const config = {
|
||||
snake: Object.entries(snakes).find(([_, s]) => s === snake)![0],
|
||||
grid: Object.entries(grids).find(([_, s]) => s === grid)![0],
|
||||
demo: demos[0],
|
||||
};
|
||||
{
|
||||
const d = window.location.pathname.match(/(\w+)\.html/)?.[1];
|
||||
if (d && demos.includes(d)) config.demo = d;
|
||||
}
|
||||
|
||||
const onChange = () => {
|
||||
const search = new URLSearchParams({
|
||||
snake: config.snake,
|
||||
grid: config.grid,
|
||||
}).toString();
|
||||
|
||||
const url = new URL(
|
||||
config.demo + ".html?" + search,
|
||||
window.location.href
|
||||
).toString();
|
||||
|
||||
window.location.href = url;
|
||||
};
|
||||
|
||||
gui.add(config, "demo", demos).onChange(onChange);
|
||||
gui.add(config, "grid", Object.keys(grids)).onChange(onChange);
|
||||
gui.add(config, "snake", Object.keys(snakes)).onChange(onChange);
|
||||
@@ -3,10 +3,6 @@ import HtmlWebpackPlugin from "html-webpack-plugin";
|
||||
|
||||
import type { Configuration } from "webpack";
|
||||
|
||||
const basePathname = (process.env.BASE_PATHNAME || "")
|
||||
.split("/")
|
||||
.filter(Boolean);
|
||||
|
||||
const demos: string[] = require("./demo.json");
|
||||
|
||||
const config: Configuration = {
|
||||
@@ -18,7 +14,6 @@ const config: Configuration = {
|
||||
output: {
|
||||
path: path.join(__dirname, "dist"),
|
||||
filename: "[contenthash].js",
|
||||
publicPath: "/" + basePathname.map((x) => x + "/").join(""),
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
@@ -40,6 +35,7 @@ const config: Configuration = {
|
||||
...demos.map(
|
||||
(demo) =>
|
||||
new HtmlWebpackPlugin({
|
||||
title: "snk - " + demo,
|
||||
filename: `${demo}.html`,
|
||||
chunks: [demo],
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user