🚀svg dark mode
This commit is contained in:
@@ -25,6 +25,10 @@ export const generateContributionSnake = async (
|
||||
colorEmpty: colorScheme[0],
|
||||
colorSnake: "purple",
|
||||
cells,
|
||||
dark: {
|
||||
colorEmpty: "#161b22",
|
||||
colorDots: { 1: "#01311f", 2: "#034525", 3: "#0f6d31", 4: "#00c647" },
|
||||
},
|
||||
};
|
||||
|
||||
const gifOptions = { frameDuration: 100, step: 1 };
|
||||
|
||||
@@ -12,10 +12,13 @@ export const drawOptions = {
|
||||
2: "#40c463",
|
||||
3: "#30a14e",
|
||||
4: "#216e39",
|
||||
5: "orange",
|
||||
},
|
||||
colorEmpty: "#ebedf0",
|
||||
colorSnake: "purple",
|
||||
dark: {
|
||||
colorEmpty: "#161b22",
|
||||
colorDots: { 1: "#01311f", 2: "#034525", 3: "#0f6d31", 4: "#00c647" },
|
||||
},
|
||||
};
|
||||
|
||||
const getPointedCell = (canvas: HTMLCanvasElement) => ({
|
||||
|
||||
@@ -13,6 +13,10 @@ const drawOptions = {
|
||||
colorDots: { 1: "#9be9a8", 2: "#40c463", 3: "#30a14e", 4: "#216e39" },
|
||||
colorEmpty: "#ebedf0",
|
||||
colorSnake: "purple",
|
||||
dark: {
|
||||
colorEmpty: "#161b22",
|
||||
colorDots: { 1: "#01311f", 2: "#034525", 3: "#0f6d31", 4: "#00c647" },
|
||||
},
|
||||
};
|
||||
|
||||
const gifOptions = { frameDuration: 100, step: 1 };
|
||||
|
||||
@@ -15,14 +15,7 @@ const percent = (x: number) => (x * 100).toFixed(2);
|
||||
|
||||
export const createGrid = (
|
||||
cells: (Point & { t: number | null; color: Color | Empty })[],
|
||||
{
|
||||
colorEmpty,
|
||||
colorBorder,
|
||||
sizeBorderRadius,
|
||||
colorDots,
|
||||
sizeDot,
|
||||
sizeCell,
|
||||
}: Options,
|
||||
{ sizeBorderRadius, sizeDot, sizeCell }: Options,
|
||||
duration: number
|
||||
) => {
|
||||
const svgElements: string[] = [];
|
||||
@@ -31,10 +24,10 @@ export const createGrid = (
|
||||
shape-rendering: geometricPrecision;
|
||||
rx: ${sizeBorderRadius};
|
||||
ry: ${sizeBorderRadius};
|
||||
fill:${colorEmpty};
|
||||
fill: var(--ce);
|
||||
stroke-width: 1px;
|
||||
stroke: ${colorBorder};
|
||||
animation: none ${duration}ms linear infinite;
|
||||
stroke: var(--cb);
|
||||
animation: none ${duration}ms linear infinite;
|
||||
}`,
|
||||
];
|
||||
|
||||
@@ -47,16 +40,14 @@ export const createGrid = (
|
||||
|
||||
if (t !== null) {
|
||||
const animationName = id;
|
||||
// @ts-ignore
|
||||
const fill = colorDots[color];
|
||||
|
||||
styles.push(
|
||||
`@keyframes ${animationName} {` +
|
||||
`${percent(t - 0.0001)}%{fill:${fill}}` +
|
||||
`${percent(t + 0.0001)}%,100%{fill:${colorEmpty}}` +
|
||||
`${percent(t - 0.0001)}%{fill:var(--c${color})}` +
|
||||
`${percent(t + 0.0001)}%,100%{fill:var(--ce)}` +
|
||||
"}",
|
||||
|
||||
`.c.${id}{fill: ${fill};animation-name: ${animationName}}`
|
||||
`.c.${id}{fill: var(--c${color}); animation-name: ${animationName}}`
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,12 @@ export type Options = {
|
||||
sizeDot: number;
|
||||
sizeBorderRadius: number;
|
||||
cells?: Point[];
|
||||
dark?: {
|
||||
colorDots: Record<Color, string>;
|
||||
colorEmpty: string;
|
||||
colorBorder?: string;
|
||||
colorSnake?: string;
|
||||
};
|
||||
};
|
||||
|
||||
const getCellsFromGrid = ({ width, height }: Grid) =>
|
||||
@@ -94,10 +100,12 @@ export const createSvg = (
|
||||
height,
|
||||
].join(" ");
|
||||
|
||||
const style = elements
|
||||
.map((e) => e.styles)
|
||||
.flat()
|
||||
.join("\n");
|
||||
const style =
|
||||
generateColorVar(drawOptions) +
|
||||
elements
|
||||
.map((e) => e.styles)
|
||||
.flat()
|
||||
.join("\n");
|
||||
|
||||
const svg = [
|
||||
h("svg", {
|
||||
@@ -121,3 +129,29 @@ export const createSvg = (
|
||||
|
||||
const optimizeCss = (css: string) => csso.minify(css).css;
|
||||
const optimizeSvg = (svg: string) => svg;
|
||||
|
||||
const generateColorVar = (drawOptions: Options) =>
|
||||
`
|
||||
:root {
|
||||
--cb: ${drawOptions.colorBorder};
|
||||
--cs: ${drawOptions.colorSnake};
|
||||
--ce: ${drawOptions.colorEmpty};
|
||||
${Object.entries(drawOptions.colorDots)
|
||||
.map(([i, color]) => `--c${i}:${color};`)
|
||||
.join("")}
|
||||
}
|
||||
` +
|
||||
(drawOptions.dark
|
||||
? `
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--cb: ${drawOptions.dark.colorBorder || drawOptions.colorBorder};
|
||||
--cs: ${drawOptions.dark.colorSnake || drawOptions.colorSnake};
|
||||
--ce: ${drawOptions.dark.colorEmpty};
|
||||
${Object.entries(drawOptions.dark.colorDots)
|
||||
.map(([i, color]) => `--c${i}:${color};`)
|
||||
.join("")}
|
||||
}
|
||||
}
|
||||
`
|
||||
: "");
|
||||
|
||||
@@ -20,7 +20,7 @@ const lerp = (k: number, a: number, b: number) => (1 - k) * a + k * b;
|
||||
|
||||
export const createSnake = (
|
||||
chain: Snake[],
|
||||
{ sizeCell, colorSnake, sizeDot }: Options,
|
||||
{ sizeCell, sizeDot }: Options,
|
||||
duration: number
|
||||
) => {
|
||||
const snakeN = chain[0] ? getSnakeLength(chain[0]) : 0;
|
||||
@@ -61,7 +61,7 @@ export const createSnake = (
|
||||
const styles = [
|
||||
`.s{
|
||||
shape-rendering:geometricPrecision;
|
||||
fill:${colorSnake};
|
||||
fill:var(--cs);
|
||||
animation: none linear ${duration}ms infinite
|
||||
}`,
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ import type { Color, Empty } from "@snk/types/grid";
|
||||
import { h } from "./utils";
|
||||
|
||||
export type Options = {
|
||||
colorDots: Record<Color, string>;
|
||||
sizeDot: number;
|
||||
};
|
||||
|
||||
@@ -10,7 +9,7 @@ const percent = (x: number) => (x * 100).toFixed(2);
|
||||
|
||||
export const createStack = (
|
||||
cells: { t: number | null; color: Color | Empty }[],
|
||||
{ colorDots, sizeDot }: Options,
|
||||
{ sizeDot }: Options,
|
||||
width: number,
|
||||
y: number,
|
||||
duration: number
|
||||
@@ -44,9 +43,6 @@ export const createStack = (
|
||||
const animationName = id;
|
||||
const x = (nx * m).toFixed(1);
|
||||
|
||||
// @ts-ignore
|
||||
const fill = colorDots[color];
|
||||
|
||||
nx += ts.length;
|
||||
|
||||
svgElements.push(
|
||||
@@ -76,7 +72,7 @@ export const createStack = (
|
||||
.join("\n") +
|
||||
"}",
|
||||
|
||||
`.u.${id}{fill:${fill};animation-name:${animationName};transform-origin:${x}px 0}`
|
||||
`.u.${id}{fill:var(--c${color});animation-name:${animationName};transform-origin:${x}px 0}`
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user