change options, drop svg_out_path in favor of outputs list
This commit is contained in:
@@ -1,2 +1,3 @@
|
||||
*
|
||||
!.gitignore
|
||||
!.gitignore
|
||||
!*.snap
|
||||
@@ -0,0 +1,66 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`should parse /out.svg?color_snake=orange&color_dots=#bfd6f6,#8dbdff,#64a1f4,#4b91f1,#3c7dd9 1`] = `
|
||||
Object {
|
||||
"drawOptions": Object {
|
||||
"colorDotBorder": "#1b1f230a",
|
||||
"colorDots": Array [
|
||||
"#bfd6f6",
|
||||
"#8dbdff",
|
||||
"#64a1f4",
|
||||
"#4b91f1",
|
||||
"#3c7dd9",
|
||||
],
|
||||
"colorEmpty": "#bfd6f6",
|
||||
"colorSnake": "orange",
|
||||
"dark": undefined,
|
||||
"sizeCell": 16,
|
||||
"sizeDot": 12,
|
||||
"sizeDotBorderRadius": 2,
|
||||
},
|
||||
"filename": "/out.svg",
|
||||
"format": "svg",
|
||||
"gifOptions": Object {
|
||||
"frameDuration": 100,
|
||||
"step": 1,
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`should parse path/to/out.gif 1`] = `
|
||||
Object {
|
||||
"drawOptions": Object {
|
||||
"colorDotBorder": "#1b1f230a",
|
||||
"colorDots": Array [
|
||||
"#ebedf0",
|
||||
"#9be9a8",
|
||||
"#40c463",
|
||||
"#30a14e",
|
||||
"#216e39",
|
||||
],
|
||||
"colorEmpty": "#ebedf0",
|
||||
"colorSnake": "purple",
|
||||
"dark": Object {
|
||||
"colorDotBorder": "#1b1f230a",
|
||||
"colorDots": Array [
|
||||
"#161b22",
|
||||
"#01311f",
|
||||
"#034525",
|
||||
"#0f6d31",
|
||||
"#00c647",
|
||||
],
|
||||
"colorEmpty": "#161b22",
|
||||
"colorSnake": "purple",
|
||||
},
|
||||
"sizeCell": 16,
|
||||
"sizeDot": 12,
|
||||
"sizeDotBorderRadius": 2,
|
||||
},
|
||||
"filename": "path/to/out.gif",
|
||||
"format": "gif",
|
||||
"gifOptions": Object {
|
||||
"frameDuration": 100,
|
||||
"step": 1,
|
||||
},
|
||||
}
|
||||
`;
|
||||
@@ -1,19 +0,0 @@
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import { generateContributionSnake } from "../generateContributionSnake";
|
||||
|
||||
(async () => {
|
||||
const outputSvg = path.join(__dirname, "__snapshots__/out.svg");
|
||||
const outputGif = path.join(__dirname, "__snapshots__/out.gif");
|
||||
|
||||
const buffer = await generateContributionSnake("platane", {
|
||||
svg: true,
|
||||
gif: true,
|
||||
});
|
||||
|
||||
console.log("💾 writing to", outputSvg);
|
||||
fs.writeFileSync(outputSvg, buffer.svg);
|
||||
|
||||
console.log("💾 writing to", outputGif);
|
||||
fs.writeFileSync(outputGif, buffer.gif);
|
||||
})();
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import { generateContributionSnake } from "../generateContributionSnake";
|
||||
import { parseOutputsOption } from "../outputsOptions";
|
||||
|
||||
jest.setTimeout(2 * 60 * 1000);
|
||||
|
||||
@@ -17,22 +18,26 @@ const silent = (handler: () => void | Promise<void>) => async () => {
|
||||
it(
|
||||
"should generate contribution snake",
|
||||
silent(async () => {
|
||||
const outputSvg = path.join(__dirname, "__snapshots__/out.svg");
|
||||
const outputGif = path.join(__dirname, "__snapshots__/out.gif");
|
||||
const entries = [
|
||||
path.join(__dirname, "__snapshots__/out.svg"),
|
||||
|
||||
console.log = () => undefined;
|
||||
const buffer = await generateContributionSnake("platane", {
|
||||
svg: true,
|
||||
gif: true,
|
||||
});
|
||||
path.join(__dirname, "__snapshots__/out-dark.svg") +
|
||||
"?palette=github-dark&color_snake=orange",
|
||||
|
||||
expect(buffer.svg).toBeDefined();
|
||||
expect(buffer.gif).toBeDefined();
|
||||
path.join(__dirname, "__snapshots__/out.gif") +
|
||||
"?color_snake=orange&color_dots=#d4e0f0,#8dbdff,#64a1f4,#4b91f1,#3c7dd9",
|
||||
];
|
||||
|
||||
console.log("💾 writing to", outputSvg);
|
||||
fs.writeFileSync(outputSvg, buffer.svg);
|
||||
const outputs = parseOutputsOption(entries);
|
||||
|
||||
console.log("💾 writing to", outputGif);
|
||||
fs.writeFileSync(outputGif, buffer.gif);
|
||||
const results = await generateContributionSnake("platane", outputs);
|
||||
|
||||
expect(results[0]).toBeDefined();
|
||||
expect(results[1]).toBeDefined();
|
||||
expect(results[2]).toBeDefined();
|
||||
|
||||
fs.writeFileSync(outputs[0]!.filename, results[0]!);
|
||||
fs.writeFileSync(outputs[1]!.filename, results[1]!);
|
||||
fs.writeFileSync(outputs[2]!.filename, results[2]!);
|
||||
})
|
||||
);
|
||||
|
||||
11
packages/action/__tests__/outputsOptions.spec.ts
Normal file
11
packages/action/__tests__/outputsOptions.spec.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { parseEntry } from "../outputsOptions";
|
||||
|
||||
[
|
||||
"path/to/out.gif",
|
||||
|
||||
"/out.svg?color_snake=orange&color_dots=#bfd6f6,#8dbdff,#64a1f4,#4b91f1,#3c7dd9",
|
||||
].forEach((entry) =>
|
||||
it(`should parse ${entry}`, () => {
|
||||
expect(parseEntry(entry)).toMatchSnapshot();
|
||||
})
|
||||
);
|
||||
@@ -3,10 +3,18 @@ import { userContributionToGrid } from "./userContributionToGrid";
|
||||
import { getBestRoute } from "@snk/solver/getBestRoute";
|
||||
import { snake4 } from "@snk/types/__fixtures__/snake";
|
||||
import { getPathToPose } from "@snk/solver/getPathToPose";
|
||||
import { Options as DrawOptions } from "@snk/svg-creator";
|
||||
|
||||
export const generateContributionSnake = async (
|
||||
userName: string,
|
||||
format: { svg?: boolean; gif?: boolean }
|
||||
outputs: ({
|
||||
format: "svg" | "gif";
|
||||
drawOptions: DrawOptions;
|
||||
gifOptions: {
|
||||
frameDuration: number;
|
||||
step: number;
|
||||
};
|
||||
} | null)[]
|
||||
) => {
|
||||
console.log("🎣 fetching github user contribution");
|
||||
const { cells, colorScheme } = await getGithubUserContribution(userName);
|
||||
@@ -14,40 +22,26 @@ export const generateContributionSnake = async (
|
||||
const grid = userContributionToGrid(cells, colorScheme);
|
||||
const snake = snake4;
|
||||
|
||||
const drawOptions = {
|
||||
sizeBorderRadius: 2,
|
||||
sizeCell: 16,
|
||||
sizeDot: 12,
|
||||
colorBorder: "#1b1f230a",
|
||||
colorDots: colorScheme as any,
|
||||
colorEmpty: colorScheme[0],
|
||||
colorSnake: "purple",
|
||||
cells,
|
||||
dark: {
|
||||
colorEmpty: "#161b22",
|
||||
colorDots: { 1: "#01311f", 2: "#034525", 3: "#0f6d31", 4: "#00c647" },
|
||||
},
|
||||
};
|
||||
|
||||
const gifOptions = { frameDuration: 100, step: 1 };
|
||||
|
||||
console.log("📡 computing best route");
|
||||
const chain = getBestRoute(grid, snake)!;
|
||||
chain.push(...getPathToPose(chain.slice(-1)[0], snake)!);
|
||||
|
||||
const output: Record<string, Buffer | string> = {};
|
||||
|
||||
if (format.gif) {
|
||||
console.log("📹 creating gif");
|
||||
const { createGif } = await import("@snk/gif-creator");
|
||||
output.gif = await createGif(grid, chain, drawOptions, gifOptions);
|
||||
}
|
||||
|
||||
if (format.svg) {
|
||||
console.log("🖌 creating svg");
|
||||
const { createSvg } = await import("@snk/svg-creator");
|
||||
output.svg = createSvg(grid, chain, drawOptions, gifOptions);
|
||||
}
|
||||
|
||||
return output;
|
||||
return Promise.all(
|
||||
outputs.map(async (out, i) => {
|
||||
if (!out) return;
|
||||
const { format, drawOptions, gifOptions } = out;
|
||||
switch (format) {
|
||||
case "svg": {
|
||||
console.log(`🖌 creating svg (outputs[${i}])`);
|
||||
const { createSvg } = await import("@snk/svg-creator");
|
||||
return createSvg(grid, chain, drawOptions, gifOptions);
|
||||
}
|
||||
case "gif": {
|
||||
console.log(`📹 creating gif (outputs[${i}])`);
|
||||
const { createGif } = await import("@snk/gif-creator");
|
||||
return await createGif(grid, chain, drawOptions, gifOptions);
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2,30 +2,28 @@ import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import * as core from "@actions/core";
|
||||
import { generateContributionSnake } from "./generateContributionSnake";
|
||||
import { parseOutputsOption } from "./outputsOptions";
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
const userName = core.getInput("github_user_name");
|
||||
const format = {
|
||||
svg: core.getInput("svg_out_path"),
|
||||
gif: core.getInput("gif_out_path"),
|
||||
};
|
||||
|
||||
const { svg, gif } = await generateContributionSnake(
|
||||
userName,
|
||||
format as any
|
||||
const outputs = parseOutputsOption(
|
||||
core.getMultilineInput("outputs") ?? [
|
||||
core.getInput("gif_out_path"),
|
||||
core.getInput("svg_out_path"),
|
||||
]
|
||||
);
|
||||
|
||||
if (svg) {
|
||||
fs.mkdirSync(path.dirname(format.svg), { recursive: true });
|
||||
fs.writeFileSync(format.svg, svg);
|
||||
core.setOutput("svg_out_path", format.svg);
|
||||
}
|
||||
if (gif) {
|
||||
fs.mkdirSync(path.dirname(format.gif), { recursive: true });
|
||||
fs.writeFileSync(format.gif, gif);
|
||||
core.setOutput("gif_out_path", format.gif);
|
||||
}
|
||||
const results = await generateContributionSnake(userName, outputs);
|
||||
|
||||
outputs.forEach((out, i) => {
|
||||
const result = results[i];
|
||||
if (out?.filename && result) {
|
||||
console.log(`💾 writing to ${out?.filename}`);
|
||||
fs.mkdirSync(path.dirname(out?.filename), { recursive: true });
|
||||
fs.writeFileSync(out?.filename, result);
|
||||
}
|
||||
});
|
||||
} catch (e: any) {
|
||||
core.setFailed(`Action failed with "${e.message}"`);
|
||||
}
|
||||
|
||||
54
packages/action/outputsOptions.ts
Normal file
54
packages/action/outputsOptions.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { Options as DrawOptions } from "@snk/svg-creator";
|
||||
import { palettes } from "./palettes";
|
||||
|
||||
export const parseOutputsOption = (lines: string[]) => lines.map(parseEntry);
|
||||
|
||||
export const parseEntry = (entry: string) => {
|
||||
const m = entry.trim().match(/^(.+\.(svg|gif))(\?.*)?$/);
|
||||
if (!m) return null;
|
||||
|
||||
const [_, filename, format, query] = m;
|
||||
|
||||
const sp = new URLSearchParams(query || "");
|
||||
|
||||
const drawOptions: DrawOptions = {
|
||||
sizeDotBorderRadius: 2,
|
||||
sizeCell: 16,
|
||||
sizeDot: 12,
|
||||
...palettes["default"],
|
||||
};
|
||||
const gifOptions = { step: 1, frameDuration: 100 };
|
||||
|
||||
{
|
||||
const palette = palettes[sp.get("palette")!];
|
||||
if (palette) {
|
||||
Object.assign(drawOptions, palette);
|
||||
drawOptions.dark = palette.dark && { ...palette.dark };
|
||||
}
|
||||
}
|
||||
|
||||
if (sp.has("color_snake")) drawOptions.colorSnake = sp.get("color_snake")!;
|
||||
if (sp.has("color_dots")) {
|
||||
const colors = sp.get("color_dots")!.split(/[,;]/);
|
||||
drawOptions.colorDots = colors;
|
||||
drawOptions.colorEmpty = colors[0];
|
||||
drawOptions.dark = undefined;
|
||||
}
|
||||
if (sp.has("color_dot_border"))
|
||||
drawOptions.colorDotBorder = sp.get("color_dot_border")!;
|
||||
|
||||
if (sp.has("dark_color_dots")) {
|
||||
const colors = sp.get("dark_color_dots")!.split(/[,;]/);
|
||||
drawOptions.dark = {
|
||||
...drawOptions.dark,
|
||||
colorDots: colors,
|
||||
colorEmpty: colors[0],
|
||||
};
|
||||
}
|
||||
if (sp.has("dark_color_dot_border") && drawOptions.dark)
|
||||
drawOptions.dark.colorDotBorder = sp.get("color_dot_border")!;
|
||||
if (sp.has("dark_color_snake") && drawOptions.dark)
|
||||
drawOptions.dark.colorSnake = sp.get("color_snake")!;
|
||||
|
||||
return { filename, format: format as "svg" | "gif", drawOptions, gifOptions };
|
||||
};
|
||||
@@ -10,11 +10,9 @@
|
||||
"@snk/types": "1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vercel/ncc": "0.24.1",
|
||||
"ts-node": "10.7.0"
|
||||
"@vercel/ncc": "0.24.1"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "ncc build --external canvas --external gifsicle --out dist ./index.ts",
|
||||
"dev": "ts-node __tests__/dev.ts"
|
||||
"build": "ncc build --external canvas --external gifsicle --out dist ./index.ts"
|
||||
}
|
||||
}
|
||||
|
||||
29
packages/action/palettes.ts
Normal file
29
packages/action/palettes.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { Options as DrawOptions } from "@snk/svg-creator";
|
||||
|
||||
export const palettes: Record<
|
||||
string,
|
||||
Pick<
|
||||
DrawOptions,
|
||||
"colorDotBorder" | "colorEmpty" | "colorSnake" | "colorDots" | "dark"
|
||||
>
|
||||
> = {
|
||||
"github-light": {
|
||||
colorDotBorder: "#1b1f230a",
|
||||
colorDots: ["#ebedf0", "#9be9a8", "#40c463", "#30a14e", "#216e39"],
|
||||
colorEmpty: "#ebedf0",
|
||||
colorSnake: "purple",
|
||||
},
|
||||
"github-dark": {
|
||||
colorDotBorder: "#1b1f230a",
|
||||
colorEmpty: "#161b22",
|
||||
colorDots: ["#161b22", "#01311f", "#034525", "#0f6d31", "#00c647"],
|
||||
colorSnake: "purple",
|
||||
},
|
||||
};
|
||||
|
||||
// aliases
|
||||
palettes["github"] = {
|
||||
...palettes["github-light"],
|
||||
dark: { ...palettes["github-dark"] },
|
||||
};
|
||||
palettes["default"] = palettes["github"];
|
||||
@@ -1,12 +1,13 @@
|
||||
import { Color, Grid } from "@snk/types/grid";
|
||||
import { drawLerpWorld, drawWorld } from "@snk/draw/drawWorld";
|
||||
import { Snake } from "@snk/types/snake";
|
||||
import type { Options as DrawOptions } from "@snk/svg-creator";
|
||||
|
||||
export const drawOptions = {
|
||||
sizeBorderRadius: 2,
|
||||
export const drawOptions: DrawOptions = {
|
||||
sizeDotBorderRadius: 2,
|
||||
sizeCell: 16,
|
||||
sizeDot: 12,
|
||||
colorBorder: "#1b1f230a",
|
||||
colorDotBorder: "#1b1f230a",
|
||||
colorDots: {
|
||||
1: "#9be9a8",
|
||||
2: "#40c463",
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { Snake } from "@snk/types/snake";
|
||||
import {
|
||||
drawLerpWorld,
|
||||
getCanvasWorldSize,
|
||||
Options,
|
||||
Options as DrawOptions,
|
||||
} from "@snk/draw/drawWorld";
|
||||
import { userContributionToGrid } from "@snk/action/userContributionToGrid";
|
||||
import { createSvg } from "@snk/svg-creator";
|
||||
@@ -120,7 +120,7 @@ const createViewer = ({
|
||||
}: {
|
||||
grid0: Grid;
|
||||
chain: Snake[];
|
||||
drawOptions: Options;
|
||||
drawOptions: DrawOptions;
|
||||
}) => {
|
||||
//
|
||||
// canvas
|
||||
@@ -229,11 +229,11 @@ const onSubmit = async (userName: string) => {
|
||||
);
|
||||
const { cells, colorScheme } = (await res.json()) as Res;
|
||||
|
||||
const drawOptions = {
|
||||
sizeBorderRadius: 2,
|
||||
const drawOptions: DrawOptions = {
|
||||
sizeDotBorderRadius: 2,
|
||||
sizeCell: 16,
|
||||
sizeDot: 12,
|
||||
colorBorder: "#1b1f230a",
|
||||
colorDotBorder: "#1b1f230a",
|
||||
colorDots: colorScheme as any,
|
||||
colorEmpty: colorScheme[0],
|
||||
colorSnake: "purple",
|
||||
|
||||
@@ -6,10 +6,10 @@ import type { Point } from "@snk/types/point";
|
||||
type Options = {
|
||||
colorDots: Record<Color, string>;
|
||||
colorEmpty: string;
|
||||
colorBorder: string;
|
||||
colorDotBorder: string;
|
||||
sizeCell: number;
|
||||
sizeDot: number;
|
||||
sizeBorderRadius: number;
|
||||
sizeDotBorderRadius: number;
|
||||
cells?: Point[];
|
||||
};
|
||||
|
||||
@@ -31,11 +31,11 @@ export const drawGrid = (
|
||||
);
|
||||
|
||||
ctx.fillStyle = color;
|
||||
ctx.strokeStyle = o.colorBorder;
|
||||
ctx.strokeStyle = o.colorDotBorder;
|
||||
ctx.lineWidth = 1;
|
||||
ctx.beginPath();
|
||||
|
||||
pathRoundedRect(ctx, o.sizeDot, o.sizeDot, o.sizeBorderRadius);
|
||||
pathRoundedRect(ctx, o.sizeDot, o.sizeDot, o.sizeDotBorderRadius);
|
||||
|
||||
ctx.fill();
|
||||
ctx.stroke();
|
||||
|
||||
@@ -7,11 +7,11 @@ import type { Snake } from "@snk/types/snake";
|
||||
export type Options = {
|
||||
colorDots: Record<Color, string>;
|
||||
colorEmpty: string;
|
||||
colorBorder: string;
|
||||
colorDotBorder: string;
|
||||
colorSnake: string;
|
||||
sizeCell: number;
|
||||
sizeDot: number;
|
||||
sizeBorderRadius: number;
|
||||
sizeDotBorderRadius: number;
|
||||
cells?: Point[];
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { realistic as grid } from "@snk/types/__fixtures__/grid";
|
||||
import { createGif } from "..";
|
||||
import { getBestRoute } from "@snk/solver/getBestRoute";
|
||||
import { getPathToPose } from "@snk/solver/getPathToPose";
|
||||
import type { Options as DrawOptions } from "@snk/draw/drawWorld";
|
||||
|
||||
let snake = createSnakeFromCells(
|
||||
Array.from({ length: 4 }, (_, i) => ({ x: i, y: -1 }))
|
||||
@@ -24,11 +25,11 @@ let snake = createSnakeFromCells(
|
||||
const chain = getBestRoute(grid, snake)!;
|
||||
chain.push(...getPathToPose(chain.slice(-1)[0], snake)!);
|
||||
|
||||
const drawOptions = {
|
||||
sizeBorderRadius: 2,
|
||||
const drawOptions: DrawOptions = {
|
||||
sizeDotBorderRadius: 2,
|
||||
sizeCell: 16,
|
||||
sizeDot: 12,
|
||||
colorBorder: "#1b1f230a",
|
||||
colorDotBorder: "#1b1f230a",
|
||||
colorDots: { 1: "#9be9a8", 2: "#40c463", 3: "#30a14e", 4: "#216e39" },
|
||||
colorEmpty: "#ebedf0",
|
||||
colorSnake: "purple",
|
||||
|
||||
@@ -5,15 +5,16 @@ import * as grids from "@snk/types/__fixtures__/grid";
|
||||
import { snake3 as snake } from "@snk/types/__fixtures__/snake";
|
||||
import { createSnakeFromCells, nextSnake } from "@snk/types/snake";
|
||||
import { getBestRoute } from "@snk/solver/getBestRoute";
|
||||
import type { Options as DrawOptions } from "@snk/draw/drawWorld";
|
||||
|
||||
jest.setTimeout(20 * 1000);
|
||||
|
||||
const upscale = 1;
|
||||
const drawOptions = {
|
||||
sizeBorderRadius: 2 * upscale,
|
||||
const drawOptions: DrawOptions = {
|
||||
sizeDotBorderRadius: 2 * upscale,
|
||||
sizeCell: 16 * upscale,
|
||||
sizeDot: 12 * upscale,
|
||||
colorBorder: "#1b1f230a",
|
||||
colorDotBorder: "#1b1f230a",
|
||||
colorDots: { 1: "#9be9a8", 2: "#40c463", 3: "#30a14e", 4: "#216e39" },
|
||||
colorEmpty: "#ebedf0",
|
||||
colorSnake: "purple",
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import { createSvg } from "..";
|
||||
import { createSvg, Options } from "..";
|
||||
import * as grids from "@snk/types/__fixtures__/grid";
|
||||
import { snake3 as snake } from "@snk/types/__fixtures__/snake";
|
||||
import { getBestRoute } from "@snk/solver/getBestRoute";
|
||||
|
||||
const drawOptions = {
|
||||
sizeBorderRadius: 2,
|
||||
const drawOptions: Options = {
|
||||
sizeDotBorderRadius: 2,
|
||||
sizeCell: 16,
|
||||
sizeDot: 12,
|
||||
colorBorder: "#1b1f230a",
|
||||
colorDotBorder: "#1b1f230a",
|
||||
colorDots: { 1: "#9be9a8", 2: "#40c463", 3: "#30a14e", 4: "#216e39" },
|
||||
colorEmpty: "#ebedf0",
|
||||
colorSnake: "purple",
|
||||
|
||||
@@ -5,17 +5,17 @@ import { h } from "./utils";
|
||||
export type Options = {
|
||||
colorDots: Record<Color, string>;
|
||||
colorEmpty: string;
|
||||
colorBorder: string;
|
||||
colorDotBorder: string;
|
||||
sizeCell: number;
|
||||
sizeDot: number;
|
||||
sizeBorderRadius: number;
|
||||
sizeDotBorderRadius: number;
|
||||
};
|
||||
|
||||
const percent = (x: number) => (x * 100).toFixed(2);
|
||||
|
||||
export const createGrid = (
|
||||
cells: (Point & { t: number | null; color: Color | Empty })[],
|
||||
{ sizeBorderRadius, sizeDot, sizeCell }: Options,
|
||||
{ sizeDotBorderRadius, sizeDot, sizeCell }: Options,
|
||||
duration: number
|
||||
) => {
|
||||
const svgElements: string[] = [];
|
||||
@@ -54,8 +54,8 @@ export const createGrid = (
|
||||
class: ["c", id].filter(Boolean).join(" "),
|
||||
x: x * s + m,
|
||||
y: y * s + m,
|
||||
rx: sizeBorderRadius,
|
||||
ry: sizeBorderRadius,
|
||||
rx: sizeDotBorderRadius,
|
||||
ry: sizeDotBorderRadius,
|
||||
width: d,
|
||||
height: d,
|
||||
})
|
||||
|
||||
@@ -18,16 +18,16 @@ import * as csso from "csso";
|
||||
export type Options = {
|
||||
colorDots: Record<Color, string>;
|
||||
colorEmpty: string;
|
||||
colorBorder: string;
|
||||
colorDotBorder: string;
|
||||
colorSnake: string;
|
||||
sizeCell: number;
|
||||
sizeDot: number;
|
||||
sizeBorderRadius: number;
|
||||
sizeDotBorderRadius: number;
|
||||
cells?: Point[];
|
||||
dark?: {
|
||||
colorDots: Record<Color, string>;
|
||||
colorEmpty: string;
|
||||
colorBorder?: string;
|
||||
colorDotBorder?: string;
|
||||
colorSnake?: string;
|
||||
};
|
||||
};
|
||||
@@ -137,7 +137,7 @@ const optimizeSvg = (svg: string) => svg;
|
||||
const generateColorVar = (drawOptions: Options) =>
|
||||
`
|
||||
:root {
|
||||
--cb: ${drawOptions.colorBorder};
|
||||
--cb: ${drawOptions.colorDotBorder};
|
||||
--cs: ${drawOptions.colorSnake};
|
||||
--ce: ${drawOptions.colorEmpty};
|
||||
${Object.entries(drawOptions.colorDots)
|
||||
@@ -149,7 +149,7 @@ const generateColorVar = (drawOptions: Options) =>
|
||||
? `
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--cb: ${drawOptions.dark.colorBorder || drawOptions.colorBorder};
|
||||
--cb: ${drawOptions.dark.colorDotBorder || drawOptions.colorDotBorder};
|
||||
--cs: ${drawOptions.dark.colorSnake || drawOptions.colorSnake};
|
||||
--ce: ${drawOptions.dark.colorEmpty};
|
||||
${Object.entries(drawOptions.dark.colorDots)
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
import { getSnakeLength, snakeToCells } from "@snk/types/snake";
|
||||
import type { Snake } from "@snk/types/snake";
|
||||
import type { Color } from "@snk/types/grid";
|
||||
import type { Point } from "@snk/types/point";
|
||||
import { h } from "./utils";
|
||||
|
||||
export type Options = {
|
||||
colorDots: Record<Color, string>;
|
||||
colorEmpty: string;
|
||||
colorBorder: string;
|
||||
colorSnake: string;
|
||||
sizeCell: number;
|
||||
sizeDot: number;
|
||||
sizeBorderRadius: number;
|
||||
};
|
||||
|
||||
const percent = (x: number) => (x * 100).toFixed(2);
|
||||
|
||||
Reference in New Issue
Block a user