feat(settings/options/2048): per-color scheme
This commit is contained in:
@@ -42,28 +42,55 @@ const handleActivateA = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: one color scheme per app color
|
const app = useAppStore();
|
||||||
const TILE_COLORS: Record<number, { bg: string; fg: string }> = {
|
|
||||||
|
const TILE_VALUES = [0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096];
|
||||||
|
const APP_COLOR_INDEX = TILE_VALUES.indexOf(2048);
|
||||||
|
|
||||||
|
const buildTileColors = (
|
||||||
|
base: string,
|
||||||
|
): Record<number, { bg: string; fg: string }> => {
|
||||||
|
const result: Record<number, { bg: string; fg: string }> = {
|
||||||
[0]: { bg: "#f7f7f7", fg: "#776e65" },
|
[0]: { bg: "#f7f7f7", fg: "#776e65" },
|
||||||
[2]: { bg: "#ebebf3", fg: "#292929" },
|
};
|
||||||
[4]: { bg: "#d3dbe3", fg: "#292929" },
|
|
||||||
[8]: { bg: "#bacbd3", fg: "#292929" },
|
for (let i = 1; i < TILE_VALUES.length; i += 1) {
|
||||||
[16]: { bg: "#a2bac3", fg: "#f9f6f2" },
|
const value = TILE_VALUES[i]!;
|
||||||
[32]: { bg: "#8aa2b2", fg: "#f9f6f2" },
|
// 0 -> 1 = tile 2 -> 2048
|
||||||
[64]: { bg: "#7192a2", fg: "#f9f6f2" },
|
const progress = (i - 1) / (APP_COLOR_INDEX - 1);
|
||||||
[128]: { bg: "#698aa2", fg: "#f9f6f2" },
|
|
||||||
[256]: { bg: "#61829a", fg: "#f9f6f2" },
|
let lightnessBoost: number;
|
||||||
[512]: { bg: "#5c7b92", fg: "#f9f6f2" },
|
let chromaFactor: number;
|
||||||
[1024]: { bg: "#57758a", fg: "#f9f6f2" }, // -2.5L, -0.8C
|
|
||||||
[2048]: { bg: "#476277", fg: "#f9f6f2" },
|
if (i <= APP_COLOR_INDEX) {
|
||||||
[4046]: { bg: "#173446", fg: "#f9f6f2" },
|
lightnessBoost = (1 - progress) * 0.35;
|
||||||
|
chromaFactor = 0.05 + progress * 0.95;
|
||||||
|
} else {
|
||||||
|
const stepsAbove2048 = i - APP_COLOR_INDEX;
|
||||||
|
lightnessBoost = -stepsAbove2048 * 0.07;
|
||||||
|
chromaFactor = 1 + stepsAbove2048 * 0.15;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bg = `oklch(from ${base} calc(l + ${lightnessBoost}) calc(c * ${chromaFactor}) h)`;
|
||||||
|
// change text color based on background lightness
|
||||||
|
const fg = `oklch(from ${bg} clamp(0, (0.6 - l) * 999, 1) 0 h)`;
|
||||||
|
result[value] = { bg, fg };
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
};
|
};
|
||||||
const LAST_TILE_COLOR =
|
|
||||||
Object.values(TILE_COLORS)[Object.values(TILE_COLORS).length - 1]!;
|
const TILE_COLORS = computed(() => buildTileColors(app.color.hex));
|
||||||
|
const LAST_TILE_COLOR = computed(() => {
|
||||||
|
const values = Object.values(TILE_COLORS.value);
|
||||||
|
return values[values.length - 1]!;
|
||||||
|
});
|
||||||
const TILE_SIZE = 28;
|
const TILE_SIZE = 28;
|
||||||
const ANIM_DURATION = 0.1;
|
const ANIM_DURATION = 0.1;
|
||||||
|
|
||||||
const BORDER_COLOR = "#d7d7d7";
|
const BORDER_COLOR = computed(
|
||||||
|
() => `oklch(from ${app.color.hex} 0.88 0.015 h)`,
|
||||||
|
);
|
||||||
const BORDER_SIZE = 3;
|
const BORDER_SIZE = 3;
|
||||||
|
|
||||||
const BOARD_X = 64;
|
const BOARD_X = 64;
|
||||||
@@ -215,7 +242,7 @@ onRender((ctx) => {
|
|||||||
|
|
||||||
assets.images.settings.bottomScreen.options._2048.frame.draw(ctx, -3, -3);
|
assets.images.settings.bottomScreen.options._2048.frame.draw(ctx, -3, -3);
|
||||||
|
|
||||||
ctx.fillStyle = BORDER_COLOR;
|
ctx.fillStyle = BORDER_COLOR.value;
|
||||||
ctx.fillRect(
|
ctx.fillRect(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@@ -225,7 +252,7 @@ onRender((ctx) => {
|
|||||||
|
|
||||||
for (let row = 0; row < BOARD_SIZE; row += 1) {
|
for (let row = 0; row < BOARD_SIZE; row += 1) {
|
||||||
for (let col = 0; col < BOARD_SIZE; col += 1) {
|
for (let col = 0; col < BOARD_SIZE; col += 1) {
|
||||||
ctx.fillStyle = TILE_COLORS[0]!.bg;
|
ctx.fillStyle = TILE_COLORS.value[0]!.bg;
|
||||||
ctx.fillRect(cellX(col), cellY(row), TILE_SIZE, TILE_SIZE);
|
ctx.fillRect(cellX(col), cellY(row), TILE_SIZE, TILE_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -236,7 +263,7 @@ onRender((ctx) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const tile of tiles) {
|
for (const tile of tiles) {
|
||||||
const color = TILE_COLORS[tile.value] ?? LAST_TILE_COLOR;
|
const color = TILE_COLORS.value[tile.value] ?? LAST_TILE_COLOR.value;
|
||||||
|
|
||||||
ctx.save();
|
ctx.save();
|
||||||
const cx = tile.x + TILE_SIZE / 2;
|
const cx = tile.x + TILE_SIZE / 2;
|
||||||
@@ -567,15 +594,6 @@ const slide = (rowDir: number, colDir: number) => {
|
|||||||
useKeyDown(({ key }) => {
|
useKeyDown(({ key }) => {
|
||||||
if (isAnimating.value) return;
|
if (isAnimating.value) return;
|
||||||
switch (key) {
|
switch (key) {
|
||||||
// TODO: remove this, testing only
|
|
||||||
case "n":
|
|
||||||
savedState.value.board = [
|
|
||||||
[0, 0, 2, 4],
|
|
||||||
[8, 16, 32, 64],
|
|
||||||
[128, 256, 512, 1024],
|
|
||||||
[2048, 4096, 8192, 16384],
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
case "NDS_UP":
|
case "NDS_UP":
|
||||||
case "NDS_SWIPE_UP":
|
case "NDS_SWIPE_UP":
|
||||||
slide(-1, 0);
|
slide(-1, 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user