From bc118dfb1bbc8b5b6d6b89d62f03c54d5a717217 Mon Sep 17 00:00:00 2001 From: jacobk999 Date: Sun, 5 Jan 2025 23:29:48 -0500 Subject: [PATCH 1/5] feat: add winter theme --- .../src/commands/quests/quests.profile.tsx | 6 +- apps/discord-bot/src/index.ts | 3 +- .../src/lib/convert-color-codes.ts | 14 +- apps/discord-bot/src/themes/boxes/hd.box.ts | 153 +----------- apps/discord-bot/src/themes/boxes/uhd.box.ts | 35 +-- apps/discord-bot/src/themes/index.ts | 7 +- apps/support-bot/src/index.ts | 3 +- packages/assets/package.json | 1 - packages/assets/src/index.ts | 5 +- packages/rendering/package.json | 1 + packages/rendering/src/font/tokens.ts | 4 +- packages/rendering/src/index.ts | 1 + packages/rendering/src/intrinsics/Box.ts | 232 ++++++++---------- packages/rendering/src/jsx/render.ts | 2 + packages/rendering/src/jsx/types.ts | 2 + .../rendering/src/winter-theme.service.ts | 39 +++ packages/util/src/minecraft-colors.ts | 19 ++ pnpm-lock.yaml | 6 +- 18 files changed, 214 insertions(+), 319 deletions(-) create mode 100644 packages/rendering/src/winter-theme.service.ts diff --git a/apps/discord-bot/src/commands/quests/quests.profile.tsx b/apps/discord-bot/src/commands/quests/quests.profile.tsx index 2e33dfd09..7ef4a53f4 100644 --- a/apps/discord-bot/src/commands/quests/quests.profile.tsx +++ b/apps/discord-bot/src/commands/quests/quests.profile.tsx @@ -103,21 +103,21 @@ const NormalTable = ({ quests, t, gameIcons, colorPalette, time }: NormalTablePr boxColor = useGradient( "horizontal", [GRADIENT_OFFSET, BOX_COLOR], - [1, "hsla(120, 100%, 30%, 0.5)"] + [1, "hsla(145, 45%, 44%, 0.5)"] ); } else if (completed >= 1) { textColor = "§6"; boxColor = useGradient( "horizontal", [GRADIENT_OFFSET, BOX_COLOR], - [1, "hsla(40, 100%, 30%, 0.5)"] + [1, "hsla(42, 17%, 48%, 0.5)"] ); } else { textColor = "§c"; boxColor = useGradient( "horizontal", [GRADIENT_OFFSET, BOX_COLOR], - [1, "hsla(0, 100%, 30%, 0.5)"] + [1, "hsla(337, 31%, 43%, 0.5)"] ); } diff --git a/apps/discord-bot/src/index.ts b/apps/discord-bot/src/index.ts index fd80e2349..7046a9d79 100644 --- a/apps/discord-bot/src/index.ts +++ b/apps/discord-bot/src/index.ts @@ -14,6 +14,7 @@ import { FontLoaderService } from "#services"; import { InteractionServer, RestClient, WebsocketShard } from "tiny-discord"; import { Logger } from "@statsify/logger"; import { VerifyCommand } from "#commands/verify.command"; +import { WinterThemeService } from "@statsify/rendering"; import { config } from "@statsify/util"; import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; @@ -39,7 +40,7 @@ if (sentryDsn) { } await Promise.all( - [I18nLoaderService, FontLoaderService].map((service) => Container.get(service).init()) + [I18nLoaderService, FontLoaderService, WinterThemeService].map((service) => Container.get(service).init()) ); const rest = new RestClient({ token: config("discordBot.token"), timeout: 60 * 1000 }); diff --git a/apps/discord-bot/src/lib/convert-color-codes.ts b/apps/discord-bot/src/lib/convert-color-codes.ts index 03988e22e..4fd78bf74 100644 --- a/apps/discord-bot/src/lib/convert-color-codes.ts +++ b/apps/discord-bot/src/lib/convert-color-codes.ts @@ -6,8 +6,18 @@ * https://github.com/Statsify/statsify/blob/main/LICENSE */ -export const convertColorCodes = (content: string) => - content +import { minecraftColors } from "@statsify/util"; + +export const convertColorCodes = (content: string) => { + content = content .replaceAll(String.raw`\&`, "󰀀") .replace(/&\S/g, (m) => m.replace("&", "§")) .replaceAll("󰀀", "&"); + + for (const color of minecraftColors) { + content = content.replaceAll(color.code, `§${color.hex}`); + } + + return `§#FFFFFF${content}`; +}; + diff --git a/apps/discord-bot/src/themes/boxes/hd.box.ts b/apps/discord-bot/src/themes/boxes/hd.box.ts index 459eae417..68913faf9 100644 --- a/apps/discord-bot/src/themes/boxes/hd.box.ts +++ b/apps/discord-bot/src/themes/boxes/hd.box.ts @@ -7,13 +7,6 @@ */ import { Box, Render } from "@statsify/rendering"; -import { CanvasRenderingContext2D } from "skia-canvas"; - -const WHITE = "rgb(245, 248, 255)"; -const RED = "rgb(255, 53, 53)"; -const RED_HIGHLIGHT = "rgb(255, 98, 98)"; -const GREEN = "rgb(34, 175, 31)"; -const GREEN_HIGHLIGHT = "rgb(47, 209, 44)"; export const render: Render = ( ctx, @@ -25,10 +18,11 @@ export const render: Render = ( outline, outlineSize, }, - { x, y, width, height, padding } + { x, y, width, height, padding }, + { winterTheme } ) => { const fill = Box.resolveFill(color, ctx, x, y, width, height); - ctx.fillStyle = fill; + ctx.fillStyle = winterTheme.getIce(ctx); width = width + padding.left + padding.right; height = height + padding.top + padding.bottom; @@ -78,13 +72,18 @@ export const render: Render = ( ctx.closePath(); ctx.fill(); + if (fill !== Box.DEFAULT_COLOR) { + ctx.fillStyle = fill; + ctx.fill(); + } + ctx.globalCompositeOperation = "overlay"; const overlay = ctx.createLinearGradient(x, y, x, y + height); overlay.addColorStop(0, "rgba(255, 255, 255, 0.15)"); overlay.addColorStop(1, "rgba(0, 0, 0, 0.15)"); - ctx.fillStyle = overlay; + ctx.fillStyle = overlay; ctx.fill(); ctx.globalCompositeOperation = "source-over"; @@ -96,78 +95,6 @@ export const render: Render = ( ctx.stroke(); } - drawPattern(ctx, "horizontal", x + (2 * border.topLeft), y, width - (2 * border.topRight) - (2 * border.topLeft)); - drawPattern(ctx, "horizontal", x + (2 * border.bottomLeft), y + height - 4, width - (2 * border.bottomRight) - (2 * border.bottomLeft)); - - drawPattern(ctx, "vertical", x, y + (2 * border.topLeft), height - (2 * border.topLeft) - (2 * border.bottomLeft)); - drawPattern(ctx, "vertical", x + width - 4, y + (2 * border.topRight), height - (2 * border.topRight) - (2 * border.bottomRight)); - - ctx.fillStyle = WHITE; - - if (border.topLeft !== 0) { - ctx.fillRect( - x + border.topLeft, - y + border.topLeft, - border.topLeft, - border.topLeft - ); - - ctx.fillRect( - x + (2 * border.topLeft), - y + (2 * border.topLeft), - border.topLeft, - border.topLeft - ); - } - - if (border.topRight !== 0) { - ctx.fillRect( - x + width - (2 * border.topRight), - y + border.topRight, - border.topRight, - border.topRight - ); - - ctx.fillRect( - x + width - (3 * border.topRight), - y + (2 * border.topRight), - border.topRight, - border.topRight - ); - } - - if (border.bottomLeft !== 0) { - ctx.fillRect( - x + border.bottomLeft, - y + height - (2 * border.bottomLeft), - border.bottomLeft, - border.bottomLeft - ); - - ctx.fillRect( - x + (2 * border.bottomLeft), - y + height - (3 * border.bottomLeft), - border.bottomLeft, - border.bottomLeft - ); - } - - if (border.bottomRight !== 0) { - ctx.fillRect( - x + width - (2 * border.bottomRight), - y + height - (2 * border.bottomRight), - border.bottomRight, - border.bottomRight - ); - - ctx.fillRect( - x + width - (3 * border.bottomRight), - y + height - (3 * border.bottomRight), - border.bottomRight, - border.bottomRight - ); - } - if (!shadowDistance) return; shadowDistance /= 2; @@ -219,64 +146,6 @@ export const render: Render = ( } ctx.globalAlpha = 1; -}; -function drawPattern(ctx: CanvasRenderingContext2D, direction: "horizontal" | "vertical", x: number, y: number, length: number) { - if (direction === "horizontal") { - const patternWidth = 60; - const patternHeight = 4; - - for (let i = 0; i < length; i += patternWidth) { - const width = Math.min(patternWidth, length - i); - ctx.fillStyle = WHITE; - ctx.fillRect(x + i, y, width, patternHeight); - - if (width >= 30) horizontalSquiggle(ctx, x + i + 6, y, RED, RED_HIGHLIGHT); - if (width >= 60) horizontalSquiggle(ctx, x + i + 36, y, GREEN, GREEN_HIGHLIGHT); - } - } else { - const patternWidth = 4; - const patternHeight = 60; - for (let i = 0; i < length; i += patternHeight) { - const height = Math.min(patternHeight, length - i); - ctx.fillStyle = WHITE; - ctx.fillRect(x, y + i, patternWidth, height); - - if (height >= 30) verticalSquiggle(ctx, x, y + i + 6, RED, RED_HIGHLIGHT); - if (height >= 60) verticalSquiggle(ctx, x, y + i + 36, GREEN, GREEN_HIGHLIGHT); - } - } -} - -function horizontalSquiggle(ctx: CanvasRenderingContext2D, x: number, y: number, color: string, highlight: string) { - ctx.fillStyle = color; - ctx.fillRect(x + 3, y + 2, 12, 2); - ctx.fillRect(x + 9, y, 12, 2); - - ctx.fillRect(x + 15, y + 2, 3, 1); - - ctx.fillStyle = highlight; - ctx.fillRect(x + 3, y + 2, 1, 2); - ctx.fillRect(x + 3, y + 2, 4, 1); - ctx.fillRect(x + 9, y, 12, 1); - - ctx.fillRect(x + 6, y + 1, 4, 1); - ctx.fillRect(x + 21, y, 3, 1); - ctx.fillRect(x, y + 3, 3, 1); -} - -function verticalSquiggle(ctx: CanvasRenderingContext2D, x: number, y: number, color: string, highlight: string) { - ctx.fillStyle = color; - ctx.fillRect(x, y + 3, 2, 12); - ctx.fillRect(x + 2, y + 9, 2, 12); - ctx.fillRect(x + 2, y + 6, 1, 3); - - ctx.fillStyle = highlight; - ctx.fillRect(x, y + 3, 1, 12); - ctx.fillRect(x + 2, y + 17, 1, 4); - ctx.fillRect(x + 2, y + 20, 2, 1); - - ctx.fillRect(x, y, 1, 3); - ctx.fillRect(x + 1, y + 14, 1, 4); - ctx.fillRect(x + 3, y + 21, 1, 3); -} + Box.renderSnow(ctx, winterTheme, x, y, width); +}; diff --git a/apps/discord-bot/src/themes/boxes/uhd.box.ts b/apps/discord-bot/src/themes/boxes/uhd.box.ts index ea5bc752e..7504b3693 100644 --- a/apps/discord-bot/src/themes/boxes/uhd.box.ts +++ b/apps/discord-bot/src/themes/boxes/uhd.box.ts @@ -23,10 +23,11 @@ export const render: Render = ( outline, outlineSize, }, - { x, y, width, height, padding } + { x, y, width, height, padding }, + { winterTheme } ) => { const fill = Box.resolveFill(color, ctx, x, y, width, height); - ctx.fillStyle = fill; + ctx.fillStyle = winterTheme.getIce(ctx); width = width + padding.left + padding.right; height = height + padding.top + padding.bottom; @@ -49,6 +50,11 @@ export const render: Render = ( boxPath(ctx, x, y, width, height, border, 0); ctx.fill(); + if (fill !== Box.DEFAULT_COLOR) { + ctx.fillStyle = fill; + ctx.fill(); + } + ctx.globalCompositeOperation = "overlay"; const overlay = ctx.createLinearGradient(x, y, x, y + height); @@ -113,30 +119,7 @@ export const render: Render = ( ctx.globalAlpha = 1; - boxPath(ctx, x, y, width, height, border, 2); - const gradient = ctx.createLinearGradient(x, y, x + width, (width / 1.25) + y); - - const COLORS = [WHITE, RED, WHITE, GREEN]; - let index = 0; - const delta = (3 * COLORS.length) / width; - - for (let i = 0; i <= (1 - delta); i += delta) { - const color = COLORS[index]; - - gradient.addColorStop(i, color); - gradient.addColorStop(i + delta, color); - - index = (index + 1) % COLORS.length; - } - - ctx.strokeStyle = gradient; - ctx.lineWidth = 4; - ctx.stroke(); - - boxPath(ctx, x, y, width, height, border, 1); - ctx.lineWidth = 2; - ctx.strokeStyle = "rgba(255, 255, 255, 0.3)"; - ctx.stroke(); + Box.renderSnow(ctx, winterTheme, x, y, width); }; function boxPath( diff --git a/apps/discord-bot/src/themes/index.ts b/apps/discord-bot/src/themes/index.ts index f7d5d3c5c..866153f1f 100644 --- a/apps/discord-bot/src/themes/index.ts +++ b/apps/discord-bot/src/themes/index.ts @@ -12,6 +12,7 @@ import { User, UserBoxes, UserFont, UserPalette } from "@statsify/schemas"; import { getBoxRenderer } from "./boxes/index.js"; import { getColorPalette } from "./palette.js"; import { getFontRenderer } from "./renderer.js"; +import { noop } from "@statsify/util"; export const getTheme = (user: User | null): Theme | undefined => { if (!user) return undefined; @@ -29,7 +30,11 @@ export const getTheme = (user: User | null): Theme | undefined => { const colorPalette = User.isDiamond(user) ? getColorPalette(palette) : undefined; return { - context: { renderer }, + context: { + renderer, + // This can be null since @statsify/rendering's render function will override this + winterTheme: noop(), + }, elements: { box(ctx, props, location, theme) { if (colorPalette?.boxes?.color) props.color ??= colorPalette.boxes.color; diff --git a/apps/support-bot/src/index.ts b/apps/support-bot/src/index.ts index 2be233be4..9de3d6539 100644 --- a/apps/support-bot/src/index.ts +++ b/apps/support-bot/src/index.ts @@ -24,6 +24,7 @@ import { import { GatewayIntentBits } from "discord-api-types/v10"; import { Logger } from "@statsify/logger"; import { RestClient, WebsocketShard } from "tiny-discord"; +import { WinterThemeService } from "@statsify/rendering"; import { config } from "@statsify/util"; import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; @@ -56,7 +57,7 @@ const rest = new RestClient({ token: config("supportBot.token") }); Container.set(RestClient, rest); await Promise.all( - [I18nLoaderService, FontLoaderService, MongoLoaderService].map((service) => + [I18nLoaderService, FontLoaderService, MongoLoaderService, WinterThemeService].map((service) => Container.get(service).init() ) ); diff --git a/packages/assets/package.json b/packages/assets/package.json index 34c7c5644..24bf62129 100644 --- a/packages/assets/package.json +++ b/packages/assets/package.json @@ -11,7 +11,6 @@ }, "dependencies": { "@statsify/logger": "workspace:^", - "@statsify/rendering": "workspace:^", "@statsify/schemas": "workspace:^", "@swc/helpers": "^0.5.12", "axios": "1.7.3", diff --git a/packages/assets/src/index.ts b/packages/assets/src/index.ts index 169ed98c9..dae04fd37 100644 --- a/packages/assets/src/index.ts +++ b/packages/assets/src/index.ts @@ -6,11 +6,10 @@ * https://github.com/Statsify/statsify/blob/main/LICENSE */ +import { type Image, loadImage } from "skia-canvas"; import { User, UserLogo } from "@statsify/schemas"; import { existsSync, readdirSync } from "node:fs"; import { join } from "node:path"; -import { loadImage } from "@statsify/rendering"; -import type { Image } from "skia-canvas"; const PATH = "../../assets"; const PRIVATE_PATH = join(PATH, "private"); @@ -22,7 +21,7 @@ const checkAsset = (file: string) => export const getAssetPath = (path: string) => join(PATH, checkAsset(path), path); -export const getImage = (path: string) => loadImage(getAssetPath(path)); +const getImage = (path: string) => loadImage(getAssetPath(path)); /** * diff --git a/packages/rendering/package.json b/packages/rendering/package.json index d6fd8fde2..495a5cedd 100644 --- a/packages/rendering/package.json +++ b/packages/rendering/package.json @@ -20,6 +20,7 @@ }, "dependencies": { "@sentry/node": "^7.118.0", + "@statsify/assets": "workspace:^", "@statsify/util": "workspace:^", "@swc/helpers": "^0.5.12", "axios": "1.7.3", diff --git a/packages/rendering/src/font/tokens.ts b/packages/rendering/src/font/tokens.ts index 625b99852..79d888c12 100644 --- a/packages/rendering/src/font/tokens.ts +++ b/packages/rendering/src/font/tokens.ts @@ -6,7 +6,7 @@ * https://github.com/Statsify/statsify/blob/main/LICENSE */ -import { minecraftColors } from "@statsify/util"; +import { winterMinecraftColors } from "@statsify/util"; import type { Fill } from "#jsx"; export interface TextNode { @@ -55,7 +55,7 @@ const reset: Token = { effect: (_, __, defaultState) => defaultState, }; -const minecraftColorList = minecraftColors.map((color) => [ +const minecraftColorList = winterMinecraftColors.map((color) => [ color.code.replace("§", ""), color.hex, ]); diff --git a/packages/rendering/src/index.ts b/packages/rendering/src/index.ts index 5b519fef7..73b446958 100644 --- a/packages/rendering/src/index.ts +++ b/packages/rendering/src/index.ts @@ -12,6 +12,7 @@ export * from "./font/index.js"; export * from "./hooks/index.js"; export * from "./jsx/index.js"; export * from "./intrinsics/index.js"; +export { WinterThemeService } from "./winter-theme.service.js"; import type * as JSXInternal from "./jsx/index.js"; diff --git a/packages/rendering/src/intrinsics/Box.ts b/packages/rendering/src/intrinsics/Box.ts index 39414d55b..c8af25840 100644 --- a/packages/rendering/src/intrinsics/Box.ts +++ b/packages/rendering/src/intrinsics/Box.ts @@ -7,6 +7,7 @@ */ import { type CanvasRenderingContext2D } from "skia-canvas"; +import { WinterThemeService } from "../winter-theme.service.js"; import type * as JSX from "#jsx"; import type { DeferredGradient } from "#hooks"; @@ -50,9 +51,29 @@ export const resolveFill = ( return fill(ctx, x, y, width, height); }; -export const DEFAULT_COLOR = "rgba(0, 10, 5, 0.5)"; +export const DEFAULT_COLOR = "rgba(117, 146, 197, 0.5)"; export const SHADOW_OPACITY = 0.84; +function increaseSpacing( + spacing: JSX.Spacing, + side: keyof JSX.CompleteSpacing, + amount: number +) { + if (typeof spacing === "number") + return { + top: spacing, + right: spacing, + bottom: spacing, + left: spacing, + [side]: spacing + amount, + }; + + return { + ...spacing, + [side]: (spacing?.[side] ?? 0) + amount, + }; +} + export const component: JSX.RawFC = ({ children, width, @@ -68,38 +89,65 @@ export const component: JSX.RawFC = ({ shadowOpacity, outlineSize = 4, outline, -}) => { - const completePadding = toCompleteSpacing(padding); - completePadding.top += 4; - completePadding.bottom += 4; - completePadding.left += 4; - completePadding.right += 4; - - return ({ - dimension: { - padding: completePadding, - margin, - width, - height, - }, - style: { location, direction, align }, - props: { - border, - color, - shadowDistance, - shadowOpacity, - outlineSize, - outline, - }, - children, - }); -}; +}) => ({ + dimension: { + padding: increaseSpacing(padding, "top", 2), + margin: increaseSpacing(margin, "top", 4), + width, + height, + }, + style: { location, direction, align }, + props: { + border, + color, + shadowDistance, + shadowOpacity, + outlineSize, + outline, + }, + children, +}); -const WHITE = "rgb(245, 248, 255)"; -const RED = "rgb(255, 53, 53)"; -const RED_HIGHLIGHT = "rgb(255, 98, 98)"; -const GREEN = "rgb(34, 175, 31)"; -const GREEN_HIGHLIGHT = "rgb(47, 209, 44)"; +const SNOW_OFFSET = 6; + +export const renderSnow = ( + ctx: CanvasRenderingContext2D, + winterTheme: WinterThemeService, + x: number, + y: number, + width: number +) => { + const centerSnow = winterTheme.getAsset("box-snow-center"); + const leftSnow = winterTheme.getAsset("box-snow-left"); + const rightSnow = winterTheme.getAsset("box-snow-right"); + + const snowWidth = width - leftSnow.width - rightSnow.width; + + let drawnSnow = 0; + let snowLeft = snowWidth - drawnSnow; + + while (drawnSnow < snowWidth) { + const drawn = snowLeft < centerSnow.width ? snowLeft : centerSnow.width; + + ctx.drawImage( + centerSnow, + 0, + 0, + drawn, + centerSnow.height, + x + drawnSnow + leftSnow.width, + y - SNOW_OFFSET, + drawn, + centerSnow.height + ); + + drawnSnow += drawn; + snowLeft -= drawn; + } + + ctx.drawImage(leftSnow, x, y - SNOW_OFFSET + 4); + ctx.drawImage(rightSnow, x + leftSnow.width + snowWidth, y - SNOW_OFFSET + 4); +}; export const render: JSX.Render = ( ctx, @@ -111,10 +159,12 @@ export const render: JSX.Render = ( outline, outlineSize, }, - { x, y, width, height, padding } + { x, y, width, height, padding }, + { winterTheme } ) => { + ctx.filter = "brightness(70%)"; const fill = resolveFill(color, ctx, x, y, width, height); - ctx.fillStyle = fill; + ctx.fillStyle = winterTheme.getIce(ctx); width = width + padding.left + padding.right; height = height + padding.top + padding.bottom; @@ -143,11 +193,20 @@ export const render: JSX.Render = ( ctx.closePath(); ctx.fill(); + ctx.filter = "none"; + + if (fill !== DEFAULT_COLOR) { + ctx.fillStyle = fill; + ctx.fill(); + } + + ctx.filter = "brightness(70%)"; + ctx.globalCompositeOperation = "overlay"; const overlay = ctx.createLinearGradient(x, y, x, y + height); - overlay.addColorStop(0, "rgba(255, 255, 255, 0.15)"); - overlay.addColorStop(1, "rgba(0, 0, 0, 0.15)"); + overlay.addColorStop(0, "rgba(255, 255, 255, 0.30)"); + overlay.addColorStop(1, "rgba(0, 0, 0, 0.30)"); ctx.fillStyle = overlay; ctx.fill(); @@ -161,42 +220,6 @@ export const render: JSX.Render = ( ctx.stroke(); } - drawPattern(ctx, "horizontal", x + border.topLeft, y, width - border.topRight - border.topLeft); - drawPattern(ctx, "horizontal", x + border.bottomLeft, y + height - 4, width - border.bottomRight - border.bottomLeft); - - drawPattern(ctx, "vertical", x, y + border.topLeft, height - border.topLeft - border.bottomLeft); - drawPattern(ctx, "vertical", x + width - 4, y + border.topRight, height - border.topRight - border.bottomRight); - - ctx.fillStyle = WHITE; - - if (border.topLeft !== 0) ctx.fillRect( - x + border.topLeft, - y + border.topLeft, - border.topLeft, - border.topLeft - ); - - if (border.topRight !== 0) ctx.fillRect( - x + width - (2 * border.topRight), - y + border.topRight, - border.topRight, - border.topRight - ); - - if (border.bottomLeft !== 0) ctx.fillRect( - x + border.bottomLeft, - y + height - (2 * border.bottomLeft), - border.bottomLeft, - border.bottomLeft - ); - - if (border.bottomRight !== 0) ctx.fillRect( - x + width - (2 * border.bottomRight), - y + height - (2 * border.bottomRight), - border.bottomRight, - border.bottomRight - ); - if (!shadowDistance) return; ctx.globalAlpha = shadowOpacity; @@ -236,66 +259,7 @@ export const render: JSX.Render = ( ); ctx.globalAlpha = 1; -}; + ctx.filter = "none"; -function drawPattern(ctx: CanvasRenderingContext2D, direction: "horizontal" | "vertical", x: number, y: number, length: number) { - if (direction === "horizontal") { - const patternWidth = 48; - const patternHeight = 4; - - for (let i = 0; i < length; i += patternWidth) { - const width = Math.min(patternWidth, length - i); - ctx.fillStyle = WHITE; - ctx.fillRect(x + i, y, width, patternHeight); - - if (width >= 24) horizontalSquiggle(ctx, x + i + 6, y, RED, RED_HIGHLIGHT); - if (width >= 48) horizontalSquiggle(ctx, x + i + 30, y, GREEN, GREEN_HIGHLIGHT); - } - } else { - const patternWidth = 4; - const patternHeight = 48; - for (let i = 0; i < length; i += patternHeight) { - const height = Math.min(patternHeight, length - i); - ctx.fillStyle = WHITE; - ctx.fillRect(x, y + i, patternWidth, height); - - if (height >= 24) verticalSquiggle(ctx, x, y + i + 6, RED, RED_HIGHLIGHT); - if (height >= 48) verticalSquiggle(ctx, x, y + i + 30, GREEN, GREEN_HIGHLIGHT); - } - } -} - -function horizontalSquiggle(ctx: CanvasRenderingContext2D, x: number, y: number, color: string, highlight: string) { - ctx.fillStyle = color; - ctx.fillRect(x, y + 2, 12, 2); - ctx.fillRect(x + 6, y, 12, 2); - - ctx.fillStyle = highlight; - ctx.fillRect(x, y + 2, 1, 2); - ctx.fillRect(x, y + 2, 6, 1); - ctx.fillRect(x + 6, y, 1, 3); - ctx.fillRect(x + 6, y, 12, 1); -} - -function verticalSquiggle(ctx: CanvasRenderingContext2D, x: number, y: number, color: string, highlight: string) { - ctx.fillStyle = color; - ctx.fillRect(x + 2, y + 6, 2, 12); - ctx.fillRect(x, y, 2, 12); - - ctx.fillStyle = highlight; - ctx.fillRect(x, y, 1, 12); - ctx.fillRect(x, y + 11, 3, 1); - ctx.fillRect(x + 2, y + 12, 1, 6); - ctx.fillRect(x + 2, y + 17, 2, 1); -} - -function toCompleteSpacing(spacing: JSX.Spacing): JSX.CompleteSpacing { - if (typeof spacing === "number") return { top: spacing, right: spacing, bottom: spacing, left: spacing }; - - return { - top: spacing.top ?? 0, - right: spacing.right ?? 0, - bottom: spacing.bottom ?? 0, - left: spacing.left ?? 0, - }; -} + renderSnow(ctx, winterTheme, x, y, width); +}; diff --git a/packages/rendering/src/jsx/render.ts b/packages/rendering/src/jsx/render.ts index 8b95dc096..e1f0236a2 100644 --- a/packages/rendering/src/jsx/render.ts +++ b/packages/rendering/src/jsx/render.ts @@ -11,6 +11,7 @@ import { Canvas, type CanvasRenderingContext2D } from "skia-canvas"; import { Container } from "typedi"; import { FontRenderer } from "#font"; import { IntrinsicRenders, intrinsicRenders } from "./instrinsics.js"; +import { WinterThemeService } from "../winter-theme.service.js"; import { createInstructions } from "./create-instructions.js"; import { getPositionalDelta, getTotalSize } from "./util.js"; import { noop } from "@statsify/util"; @@ -139,6 +140,7 @@ export function render(node: ElementNode, theme?: Theme): Canvas { ...theme?.context, canvasWidth: width, canvasHeight: height, + winterTheme: Container.get(WinterThemeService), }; if (!context.renderer) context.renderer = Container.get(FontRenderer); diff --git a/packages/rendering/src/jsx/types.ts b/packages/rendering/src/jsx/types.ts index 588ff10d4..f30b78e7e 100644 --- a/packages/rendering/src/jsx/types.ts +++ b/packages/rendering/src/jsx/types.ts @@ -14,9 +14,11 @@ import type { } from "skia-canvas"; import type { FontRenderer } from "#font"; import type { IntrinsicElement, IntrinsicRenders } from "./instrinsics.js"; +import type { WinterThemeService } from "../winter-theme.service.js"; export interface BaseThemeContext { renderer: FontRenderer; + winterTheme: WinterThemeService; } export interface ComputedThemeContext extends BaseThemeContext { diff --git a/packages/rendering/src/winter-theme.service.ts b/packages/rendering/src/winter-theme.service.ts new file mode 100644 index 000000000..69166560f --- /dev/null +++ b/packages/rendering/src/winter-theme.service.ts @@ -0,0 +1,39 @@ +/** + * Copyright (c) Statsify + * + * This source code is licensed under the GNU GPL v3 license found in the + * LICENSE file in the root directory of this source tree. + * https://github.com/Statsify/statsify/blob/main/LICENSE + */ + +import { Service } from "typedi"; +import { getAssetPath } from "@statsify/assets"; +import { loadImage } from "./index.js"; +import type { CanvasPattern, CanvasRenderingContext2D, Image } from "skia-canvas"; + +const WINTER_ASSETS = ["box-snow-center", "box-snow-left", "box-snow-right", "ice"]; +type WinterAsset = typeof WINTER_ASSETS[number]; + +@Service() +export class WinterThemeService { + private assets: Map = new Map(); + private ice?: CanvasPattern; + + public async init() { + await Promise.all( + WINTER_ASSETS.map((image) => + loadImage(getAssetPath(`winter/${image}.png`)).then((asset) => this.assets.set(image, asset)) + ) + ); + } + + public getAsset(asset: WinterAsset): Image { + return this.assets.get(asset)!; + } + + public getIce(ctx: CanvasRenderingContext2D): CanvasPattern { + if (this.ice) return this.ice; + this.ice = ctx.createPattern(this.getAsset("ice"), "repeat")!; + return this.ice; + } +} diff --git a/packages/util/src/minecraft-colors.ts b/packages/util/src/minecraft-colors.ts index 5ff61e00e..9f45b7073 100644 --- a/packages/util/src/minecraft-colors.ts +++ b/packages/util/src/minecraft-colors.ts @@ -24,3 +24,22 @@ export const minecraftColors = [ { code: "§e", hex: "#FFFF55", id: "YELLOW" }, { code: "§f", hex: "#FFFFFF", id: "WHITE" }, ]; + +export const winterMinecraftColors = [ + { code: "§0", hex: "#000A19", id: "BLACK" }, + { code: "§1", hex: "#151FDB", id: "DARK_BLUE" }, + { code: "§2", hex: "#00A26F", id: "DARK_GREEN" }, + { code: "§3", hex: "#0EA5C8", id: "DARK_AQUA" }, + { code: "§4", hex: "#990A5E", id: "DARK_RED" }, + { code: "§5", hex: "#9019DC", id: "DARK_PURPLE" }, + { code: "§6", hex: "#E2B450", id: "GOLD" }, + { code: "§7", hex: "#93A6C2", id: "GRAY" }, + { code: "§8", hex: "#283F62", id: "DARK_GRAY" }, + { code: "§9", hex: "#4953F1", id: "BLUE" }, + { code: "§a", hex: "#12E795", id: "GREEN" }, + { code: "§b", hex: "#1EEDFF", id: "AQUA" }, + { code: "§c", hex: "#E14A88", id: "RED" }, + { code: "§d", hex: "#D87BFC", id: "LIGHT_PURPLE" }, + { code: "§e", hex: "#D9F06C", id: "YELLOW" }, + { code: "§f", hex: "#E6F0FF", id: "WHITE" }, +]; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index afab5f344..5ef4b7ca0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -524,9 +524,6 @@ importers: '@statsify/logger': specifier: workspace:^ version: link:../logger - '@statsify/rendering': - specifier: workspace:^ - version: link:../rendering '@statsify/schemas': specifier: workspace:^ version: link:../schemas @@ -631,6 +628,9 @@ importers: '@sentry/node': specifier: ^7.118.0 version: 7.118.0 + '@statsify/assets': + specifier: workspace:^ + version: link:../assets '@statsify/util': specifier: workspace:^ version: link:../util From 4fc205eca414fd41631dfb14864346234bd68a3a Mon Sep 17 00:00:00 2001 From: jacobk999 Date: Sun, 5 Jan 2025 23:35:28 -0500 Subject: [PATCH 2/5] add darkness --- apps/discord-bot/src/themes/boxes/hd.box.ts | 5 +++++ apps/discord-bot/src/themes/boxes/uhd.box.ts | 9 +++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/apps/discord-bot/src/themes/boxes/hd.box.ts b/apps/discord-bot/src/themes/boxes/hd.box.ts index 68913faf9..d597a4492 100644 --- a/apps/discord-bot/src/themes/boxes/hd.box.ts +++ b/apps/discord-bot/src/themes/boxes/hd.box.ts @@ -21,6 +21,7 @@ export const render: Render = ( { x, y, width, height, padding }, { winterTheme } ) => { + ctx.filter = "brightness(70%)"; const fill = Box.resolveFill(color, ctx, x, y, width, height); ctx.fillStyle = winterTheme.getIce(ctx); @@ -72,10 +73,13 @@ export const render: Render = ( ctx.closePath(); ctx.fill(); + ctx.filter = "none"; + if (fill !== Box.DEFAULT_COLOR) { ctx.fillStyle = fill; ctx.fill(); } + ctx.filter = "brightness(70%)"; ctx.globalCompositeOperation = "overlay"; @@ -146,6 +150,7 @@ export const render: Render = ( } ctx.globalAlpha = 1; + ctx.filter = "none"; Box.renderSnow(ctx, winterTheme, x, y, width); }; diff --git a/apps/discord-bot/src/themes/boxes/uhd.box.ts b/apps/discord-bot/src/themes/boxes/uhd.box.ts index 7504b3693..83830adbc 100644 --- a/apps/discord-bot/src/themes/boxes/uhd.box.ts +++ b/apps/discord-bot/src/themes/boxes/uhd.box.ts @@ -9,10 +9,6 @@ import { Box, Render } from "@statsify/rendering"; import { CanvasRenderingContext2D } from "skia-canvas"; -const WHITE = "rgb(245, 248, 255)"; -const RED = "rgb(255, 53, 53)"; -const GREEN = "rgb(34, 175, 31)"; - export const render: Render = ( ctx, { @@ -26,6 +22,7 @@ export const render: Render = ( { x, y, width, height, padding }, { winterTheme } ) => { + ctx.filter = "brightness(70%)"; const fill = Box.resolveFill(color, ctx, x, y, width, height); ctx.fillStyle = winterTheme.getIce(ctx); @@ -50,11 +47,14 @@ export const render: Render = ( boxPath(ctx, x, y, width, height, border, 0); ctx.fill(); + ctx.filter = "none"; + if (fill !== Box.DEFAULT_COLOR) { ctx.fillStyle = fill; ctx.fill(); } + ctx.filter = "brightness(70%)"; ctx.globalCompositeOperation = "overlay"; const overlay = ctx.createLinearGradient(x, y, x, y + height); @@ -118,6 +118,7 @@ export const render: Render = ( ctx.fill(); ctx.globalAlpha = 1; + ctx.filter = "none"; Box.renderSnow(ctx, winterTheme, x, y, width); }; From 0c03cb47435abb657dfd20653bab22ffb821286c Mon Sep 17 00:00:00 2001 From: jacobk999 Date: Sun, 5 Jan 2025 23:58:44 -0500 Subject: [PATCH 3/5] add winter footer --- apps/discord-bot/src/components/Footer.tsx | 2 +- assets/private | 2 +- assets/public | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/discord-bot/src/components/Footer.tsx b/apps/discord-bot/src/components/Footer.tsx index da9fb3190..0bf1619c1 100644 --- a/apps/discord-bot/src/components/Footer.tsx +++ b/apps/discord-bot/src/components/Footer.tsx @@ -76,7 +76,7 @@ export const Footer = ({ logo, user, border }: FooterProps) => { break; case UserLogo.DEFAULT: - text = "§#D6DEF1s§#B0DBC5t§#8BD799a§#65D46Ct§#3FD040s§#71D57Bi§#A4D9B6f§#D6DEF1y§#D1B0C4.§#CC8196n§#C65369e§#C1243Bt"; + text = "§#6799E1s§#71A2E9t§#7AABF0a§#84B3F8t§#8DBCFFs§#A3C9FFi§#B9D6FFf§#CFE3FFy§#D5E7FF.§#DBEAFFn§#E0EEFFe§#E6F1FFt"; break; } } diff --git a/assets/private b/assets/private index 2ccb9ea22..559da53e1 160000 --- a/assets/private +++ b/assets/private @@ -1 +1 @@ -Subproject commit 2ccb9ea2253a6ee456468ef00fa28aa3a95e9f7e +Subproject commit 559da53e11b1552d018ead6a8dcb0d4a72d81e99 diff --git a/assets/public b/assets/public index 2916d43ad..9f21c8dea 160000 --- a/assets/public +++ b/assets/public @@ -1 +1 @@ -Subproject commit 2916d43ad4386cc85d3f61772751cb255cf979be +Subproject commit 9f21c8deab822bb5f491129deca40b0ffaed8f0b From 3bc53ccb6528658d0c4d4dbd0188a1cc1d2bc621 Mon Sep 17 00:00:00 2001 From: jacobk999 Date: Mon, 6 Jan 2025 00:34:53 -0500 Subject: [PATCH 4/5] aa --- apps/discord-bot/src/themes/boxes/hd.box.ts | 11 ++----- apps/discord-bot/src/themes/boxes/uhd.box.ts | 11 ++----- packages/rendering/src/intrinsics/Box.ts | 19 ++++++++++-- .../rendering/src/winter-theme.service.ts | 29 +++++++++++++++++-- 4 files changed, 48 insertions(+), 22 deletions(-) diff --git a/apps/discord-bot/src/themes/boxes/hd.box.ts b/apps/discord-bot/src/themes/boxes/hd.box.ts index 6c9396006..680954aae 100644 --- a/apps/discord-bot/src/themes/boxes/hd.box.ts +++ b/apps/discord-bot/src/themes/boxes/hd.box.ts @@ -21,7 +21,7 @@ export const render: Render = ( { x, y, width, height, padding }, { winterTheme } ) => { - ctx.filter = "brightness(70%)"; + ctx.filter = "brightness(90%)"; const fill = Box.resolveFill(color, ctx, x, y, width, height); ctx.fillStyle = winterTheme.getIce(ctx); @@ -76,15 +76,10 @@ export const render: Render = ( ctx.fill(); } - ctx.filter = "brightness(70%)"; + ctx.filter = "brightness(90%)"; ctx.globalCompositeOperation = "overlay"; - const overlay = ctx.createLinearGradient(x, y, x, y + height); - overlay.addColorStop(0, "rgba(255, 255, 255, 0.15)"); - overlay.addColorStop(1, "rgba(0, 0, 0, 0.15)"); - - ctx.fillStyle = overlay; - ctx.fill(); + Box.renderOverlay(ctx, x, y, height); ctx.globalCompositeOperation = "source-over"; diff --git a/apps/discord-bot/src/themes/boxes/uhd.box.ts b/apps/discord-bot/src/themes/boxes/uhd.box.ts index 9665650e4..9f62cf199 100644 --- a/apps/discord-bot/src/themes/boxes/uhd.box.ts +++ b/apps/discord-bot/src/themes/boxes/uhd.box.ts @@ -21,7 +21,7 @@ export const render: Render = ( { x, y, width, height, padding }, { winterTheme } ) => { - ctx.filter = "brightness(70%)"; + ctx.filter = "brightness(90%)"; const fill = Box.resolveFill(color, ctx, x, y, width, height); ctx.fillStyle = winterTheme.getIce(ctx); @@ -71,15 +71,10 @@ export const render: Render = ( ctx.fill(); } - ctx.filter = "brightness(70%)"; + ctx.filter = "brightness(90%)"; ctx.globalCompositeOperation = "overlay"; - const overlay = ctx.createLinearGradient(x, y, x, y + height); - overlay.addColorStop(0, "rgba(255, 255, 255, 0.15)"); - overlay.addColorStop(1, "rgba(0, 0, 0, 0.15)"); - ctx.fillStyle = overlay; - - ctx.fill(); + Box.renderOverlay(ctx, x, y, height); ctx.globalCompositeOperation = "source-over"; diff --git a/packages/rendering/src/intrinsics/Box.ts b/packages/rendering/src/intrinsics/Box.ts index 1b99b24df..fb5c75079 100644 --- a/packages/rendering/src/intrinsics/Box.ts +++ b/packages/rendering/src/intrinsics/Box.ts @@ -149,6 +149,19 @@ export const renderSnow = ( ctx.drawImage(rightSnow, x + leftSnow.width + snowWidth, y - SNOW_OFFSET + 4); }; +export const renderOverlay = ( + ctx: CanvasRenderingContext2D, + x: number, + y: number, + height: number +) => { + const overlay = ctx.createLinearGradient(x, y, x, y + height); + overlay.addColorStop(0, "rgba(255, 255, 255, 0.30)"); + overlay.addColorStop(1, "rgba(0, 0, 0, 0.30)"); + ctx.fillStyle = overlay; + ctx.fill(); +}; + export const render: JSX.Render = ( ctx, { @@ -162,7 +175,7 @@ export const render: JSX.Render = ( { x, y, width, height, padding }, { winterTheme } ) => { - ctx.filter = "brightness(70%)"; + ctx.filter = "brightness(90%)"; const fill = resolveFill(color, ctx, x, y, width, height); ctx.fillStyle = winterTheme.getIce(ctx); @@ -198,8 +211,8 @@ export const render: JSX.Render = ( ctx.fill(); } - ctx.filter = "brightness(70%)"; - + ctx.filter = "brightness(90%)"; + renderOverlay(ctx, x, y, height); ctx.globalCompositeOperation = "overlay"; const overlay = ctx.createLinearGradient(x, y, x, y + height); diff --git a/packages/rendering/src/winter-theme.service.ts b/packages/rendering/src/winter-theme.service.ts index 69166560f..d74059465 100644 --- a/packages/rendering/src/winter-theme.service.ts +++ b/packages/rendering/src/winter-theme.service.ts @@ -11,13 +11,17 @@ import { getAssetPath } from "@statsify/assets"; import { loadImage } from "./index.js"; import type { CanvasPattern, CanvasRenderingContext2D, Image } from "skia-canvas"; -const WINTER_ASSETS = ["box-snow-center", "box-snow-left", "box-snow-right", "ice"]; +const WINTER_ASSETS = ["box-snow-center", "box-snow-left", "box-snow-right", "ice", "blue_ice", "frosted_ice_0", "packed_ice"]; type WinterAsset = typeof WINTER_ASSETS[number]; @Service() export class WinterThemeService { private assets: Map = new Map(); + private ice?: CanvasPattern; + private blueIce?: CanvasPattern; + private frostedIce?: CanvasPattern; + private packedIce?: CanvasPattern; public async init() { await Promise.all( @@ -32,8 +36,27 @@ export class WinterThemeService { } public getIce(ctx: CanvasRenderingContext2D): CanvasPattern { - if (this.ice) return this.ice; + if (!this.ice) this.createIcePatterns(ctx); + const index = Math.floor(Math.random() * 4); + + switch (index) { + case 0: + return this.ice!; + case 1: + return this.blueIce!; + case 2: + return this.frostedIce!; + case 3: + return this.packedIce!; + default: + return this.ice!; + } + } + + private createIcePatterns(ctx: CanvasRenderingContext2D) { this.ice = ctx.createPattern(this.getAsset("ice"), "repeat")!; - return this.ice; + this.blueIce = ctx.createPattern(this.getAsset("blue_ice"), "repeat")!; + this.frostedIce = ctx.createPattern(this.getAsset("frosted_ice_0"), "repeat")!; + this.packedIce = ctx.createPattern(this.getAsset("packed_ice"), "repeat")!; } } From 44cb4ad075bf81e73afee7cb85550e163ced68f6 Mon Sep 17 00:00:00 2001 From: jacobk999 Date: Mon, 6 Jan 2025 00:52:54 -0500 Subject: [PATCH 5/5] update colors --- apps/discord-bot/src/themes/boxes/hd.box.ts | 3 --- apps/discord-bot/src/themes/boxes/uhd.box.ts | 5 ---- assets/private | 2 +- assets/public | 2 +- packages/rendering/src/intrinsics/Box.ts | 7 +---- packages/util/src/minecraft-colors.ts | 28 ++++++++++---------- 6 files changed, 17 insertions(+), 30 deletions(-) diff --git a/apps/discord-bot/src/themes/boxes/hd.box.ts b/apps/discord-bot/src/themes/boxes/hd.box.ts index 680954aae..1f433d933 100644 --- a/apps/discord-bot/src/themes/boxes/hd.box.ts +++ b/apps/discord-bot/src/themes/boxes/hd.box.ts @@ -21,7 +21,6 @@ export const render: Render = ( { x, y, width, height, padding }, { winterTheme } ) => { - ctx.filter = "brightness(90%)"; const fill = Box.resolveFill(color, ctx, x, y, width, height); ctx.fillStyle = winterTheme.getIce(ctx); @@ -76,7 +75,6 @@ export const render: Render = ( ctx.fill(); } - ctx.filter = "brightness(90%)"; ctx.globalCompositeOperation = "overlay"; Box.renderOverlay(ctx, x, y, height); @@ -141,7 +139,6 @@ export const render: Render = ( } ctx.globalAlpha = 1; - ctx.filter = "none"; Box.renderSnow(ctx, winterTheme, x, y, width); }; diff --git a/apps/discord-bot/src/themes/boxes/uhd.box.ts b/apps/discord-bot/src/themes/boxes/uhd.box.ts index 9f62cf199..523791cbe 100644 --- a/apps/discord-bot/src/themes/boxes/uhd.box.ts +++ b/apps/discord-bot/src/themes/boxes/uhd.box.ts @@ -21,7 +21,6 @@ export const render: Render = ( { x, y, width, height, padding }, { winterTheme } ) => { - ctx.filter = "brightness(90%)"; const fill = Box.resolveFill(color, ctx, x, y, width, height); ctx.fillStyle = winterTheme.getIce(ctx); @@ -64,14 +63,11 @@ export const render: Render = ( ctx.closePath(); ctx.fill(); - ctx.filter = "none"; - if (fill !== Box.DEFAULT_COLOR) { ctx.fillStyle = fill; ctx.fill(); } - ctx.filter = "brightness(90%)"; ctx.globalCompositeOperation = "overlay"; Box.renderOverlay(ctx, x, y, height); @@ -130,7 +126,6 @@ export const render: Render = ( ctx.fill(); ctx.globalAlpha = 1; - ctx.filter = "none"; Box.renderSnow(ctx, winterTheme, x, y, width); }; diff --git a/assets/private b/assets/private index 559da53e1..2896031a8 160000 --- a/assets/private +++ b/assets/private @@ -1 +1 @@ -Subproject commit 559da53e11b1552d018ead6a8dcb0d4a72d81e99 +Subproject commit 2896031a804eeb1eb9b5f51e562a0ae0a26287f8 diff --git a/assets/public b/assets/public index 9f21c8dea..a5652eebb 160000 --- a/assets/public +++ b/assets/public @@ -1 +1 @@ -Subproject commit 9f21c8deab822bb5f491129deca40b0ffaed8f0b +Subproject commit a5652eebbd941506bf0c3e3d99f703faf40858de diff --git a/packages/rendering/src/intrinsics/Box.ts b/packages/rendering/src/intrinsics/Box.ts index fb5c75079..3681a30f0 100644 --- a/packages/rendering/src/intrinsics/Box.ts +++ b/packages/rendering/src/intrinsics/Box.ts @@ -51,7 +51,7 @@ export const resolveFill = ( return fill(ctx, x, y, width, height); }; -export const DEFAULT_COLOR = "rgba(117, 146, 197, 0.5)"; +export const DEFAULT_COLOR = "rgba(75, 112, 177, 0.5)"; export const SHADOW_OPACITY = 0.84; function increaseSpacing( @@ -175,7 +175,6 @@ export const render: JSX.Render = ( { x, y, width, height, padding }, { winterTheme } ) => { - ctx.filter = "brightness(90%)"; const fill = resolveFill(color, ctx, x, y, width, height); ctx.fillStyle = winterTheme.getIce(ctx); @@ -204,14 +203,11 @@ export const render: JSX.Render = ( ctx.closePath(); ctx.fill(); - ctx.filter = "none"; - if (fill !== DEFAULT_COLOR) { ctx.fillStyle = fill; ctx.fill(); } - ctx.filter = "brightness(90%)"; renderOverlay(ctx, x, y, height); ctx.globalCompositeOperation = "overlay"; @@ -269,7 +265,6 @@ export const render: JSX.Render = ( ); ctx.globalAlpha = 1; - ctx.filter = "none"; renderSnow(ctx, winterTheme, x, y, width); }; diff --git a/packages/util/src/minecraft-colors.ts b/packages/util/src/minecraft-colors.ts index 9f45b7073..b7efc7033 100644 --- a/packages/util/src/minecraft-colors.ts +++ b/packages/util/src/minecraft-colors.ts @@ -27,19 +27,19 @@ export const minecraftColors = [ export const winterMinecraftColors = [ { code: "§0", hex: "#000A19", id: "BLACK" }, - { code: "§1", hex: "#151FDB", id: "DARK_BLUE" }, - { code: "§2", hex: "#00A26F", id: "DARK_GREEN" }, - { code: "§3", hex: "#0EA5C8", id: "DARK_AQUA" }, - { code: "§4", hex: "#990A5E", id: "DARK_RED" }, - { code: "§5", hex: "#9019DC", id: "DARK_PURPLE" }, - { code: "§6", hex: "#E2B450", id: "GOLD" }, - { code: "§7", hex: "#93A6C2", id: "GRAY" }, - { code: "§8", hex: "#283F62", id: "DARK_GRAY" }, - { code: "§9", hex: "#4953F1", id: "BLUE" }, - { code: "§a", hex: "#12E795", id: "GREEN" }, - { code: "§b", hex: "#1EEDFF", id: "AQUA" }, - { code: "§c", hex: "#E14A88", id: "RED" }, - { code: "§d", hex: "#D87BFC", id: "LIGHT_PURPLE" }, - { code: "§e", hex: "#D9F06C", id: "YELLOW" }, + { code: "§1", hex: "#111BDF", id: "DARK_BLUE" }, + { code: "§2", hex: "#009438", id: "DARK_GREEN" }, + { code: "§3", hex: "#08A9CC", id: "DARK_AQUA" }, + { code: "§4", hex: "#8A0A57", id: "DARK_RED" }, + { code: "§5", hex: "#9313E2", id: "DARK_PURPLE" }, + { code: "§6", hex: "#E6B54C", id: "GOLD" }, + { code: "§7", hex: "#90A5C4", id: "GRAY" }, + { code: "§8", hex: "#243E66", id: "DARK_GRAY" }, + { code: "§9", hex: "#444EF5", id: "BLUE" }, + { code: "§a", hex: "#0AF095", id: "GREEN" }, + { code: "§b", hex: "#00EDFF", id: "AQUA" }, + { code: "§c", hex: "#E6387C", id: "RED" }, + { code: "§d", hex: "#D978FF", id: "LIGHT_PURPLE" }, + { code: "§e", hex: "#D8F055", id: "YELLOW" }, { code: "§f", hex: "#E6F0FF", id: "WHITE" }, ];