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