refactor: restructure components and assets

This commit is contained in:
2025-11-11 14:52:41 +01:00
parent 03d063b11f
commit 3384dacf0f
18 changed files with 42 additions and 29 deletions

View File

@@ -11,7 +11,7 @@ useRender((ctx) => {
<template>
<img
ref="backgroundImage"
src="/assets/home-screen_bottom_background.png"
src="/assets/images/home/bottom-screen/background.png"
hidden
/>
</template>

View File

@@ -0,0 +1,17 @@
<script setup lang="ts">
const backgroundImage = useTemplateRef("backgroundImage");
useRender((ctx) => {
if (!backgroundImage.value) return;
ctx.drawImage(backgroundImage.value, 0, 0);
});
</script>
<template>
<img
ref="backgroundImage"
src="/assets/images/home/top-screen/background.png"
hidden
/>
</template>

View File

@@ -0,0 +1,83 @@
<script setup lang="ts">
// NOTE: calendar background is handled by TopScreenBackground
const lastRowImage = useTemplateRef("lastRowImage");
const daySelectorImage = useTemplateRef("daySelectorImage");
useRender((ctx) => {
if (!lastRowImage.value || !daySelectorImage.value) return;
ctx.fillStyle = "black";
ctx.font = "7px NDS7";
const CALENDAR_COLS = 7;
const CALENDAR_ROWS = 5;
const CALENDAR_LEFT = 128;
const CALENDAR_TOP = 64;
ctx.fillStyle = "#343434";
const now = new Date();
const year = now.getFullYear();
const month = now.getMonth();
const firstDay = new Date(year, month, 1).getDay();
const daysInMonth = new Date(year, month + 1, 0).getDate();
const extraRow = CALENDAR_COLS * CALENDAR_ROWS - daysInMonth - firstDay < 0;
if (extraRow) {
ctx.drawImage(lastRowImage.value, CALENDAR_LEFT - 3, CALENDAR_TOP + 79);
}
for (let col = 0; col < CALENDAR_ROWS + (extraRow ? 1 : 0); col += 1) {
for (let row = 0; row < CALENDAR_COLS; row += 1) {
const cellIndex = col * CALENDAR_COLS + row;
const day = cellIndex - firstDay + 1;
if (day > 0 && day <= daysInMonth) {
const dayText = day.toString();
const { actualBoundingBoxRight: width } = ctx.measureText(dayText);
const cellLeft = CALENDAR_LEFT + row * 16;
const cellTop = CALENDAR_TOP + col * 16;
if (now.getDate() === day) {
ctx.drawImage(daySelectorImage.value, cellLeft, cellTop);
}
ctx.fillText(
dayText,
cellLeft + Math.floor((15 - width) / 2),
cellTop + 11,
);
}
}
}
ctx.fillStyle = "black";
ctx.font = "9px NDS9";
ctx.letterSpacing = "2px";
const timeText = `${month}/${year}`;
const { actualBoundingBoxRight: width } = ctx.measureText(timeText);
ctx.fillText(
timeText,
CALENDAR_LEFT + Math.floor((111 - width) / 2),
CALENDAR_TOP - 20,
);
});
</script>
<template>
<img
ref="lastRowImage"
src="/assets/images/home/top-screen/calendar/last-row.png"
hidden
/>
<img
ref="daySelectorImage"
src="/assets/images/home/top-screen/calendar/day-selector.png"
hidden
/>
</template>

View File

@@ -0,0 +1,78 @@
<script setup lang="ts">
const CENTER_X = 63;
const CENTER_Y = 95;
function drawLine(
ctx: CanvasRenderingContext2D,
x0: number,
y0: number,
x1: number,
y1: number,
width: number,
) {
const dx = Math.abs(x1 - x0);
const dy = Math.abs(y1 - y0);
const sx = x0 < x1 ? 1 : -1;
const sy = y0 < y1 ? 1 : -1;
let err = dx - dy;
const drawThickPixel = (x: number, y: number) => {
const isVertical = dy > dx;
if (width === 1) {
ctx.fillRect(x, y, 1, 1);
} else if (isVertical) {
const offset = Math.floor((width - 1) / 2);
ctx.fillRect(x - offset, y, width, 1);
} else {
const offset = Math.floor((width - 1) / 2);
ctx.fillRect(x, y - offset, 1, width);
}
};
while (true) {
drawThickPixel(x0, y0);
if (x0 === x1 && y0 === y1) break;
const e2 = 2 * err;
if (e2 > -dy) {
err -= dy;
x0 += sx;
}
if (e2 < dx) {
err += dx;
y0 += sy;
}
}
}
useRender((ctx) => {
const now = new Date();
const renderHand = (
value: number,
color: string,
length: number,
width: number,
) => {
const angle = value * Math.PI * 2 - Math.PI / 2;
const endX = Math.round(CENTER_X + Math.cos(angle) * length);
const endY = Math.round(CENTER_Y + Math.sin(angle) * length);
ctx.fillStyle = color;
drawLine(ctx, CENTER_X, CENTER_Y, endX, endY, width);
};
renderHand(now.getMinutes() / 60, "#797979", 30, 2);
renderHand(
now.getHours() / 12 + now.getMinutes() / 60 / 12,
"#797979",
23,
2,
);
renderHand(now.getSeconds() / 60, "#49db8a", 35, 2);
ctx.fillStyle = "#494949";
ctx.fillRect(CENTER_X - 2, CENTER_Y - 2, 5, 5);
});
</script>

View File

@@ -0,0 +1,62 @@
<script setup lang="ts">
const gbaDisplayImage = useTemplateRef("gbaDisplayImage");
const startupModeImage = useTemplateRef("startupModeImage");
const batteryImage = useTemplateRef("batteryImage");
useRender((ctx) => {
if (!gbaDisplayImage.value || !startupModeImage.value || !batteryImage.value)
return;
const TEXT_Y = 11;
ctx.fillStyle = "#ffffff";
ctx.font = "7px NDS7";
// username
ctx.fillText("pihkaal", 3, TEXT_Y);
// time + date
const fillNumberCell = (value: number, cellX: number, offset: number) => {
const text = value.toFixed().padStart(2, "0");
const { actualBoundingBoxRight: width } = ctx.measureText(text);
const x = cellX * 16;
ctx.fillText(text, Math.floor(x + offset + (16 - width) / 2), TEXT_Y);
};
const now = new Date();
fillNumberCell(now.getHours(), 9, 1);
if (Math.floor(now.getMilliseconds() / 500) % 2 == 0) {
ctx.fillText(":", 159, TEXT_Y);
}
fillNumberCell(now.getMinutes(), 10, -1);
fillNumberCell(now.getDate(), 11, 1);
ctx.fillText("/", 190, TEXT_Y);
fillNumberCell(now.getMonth() + 1, 12, -1);
// icons
ctx.drawImage(gbaDisplayImage.value, 210, 2);
ctx.drawImage(startupModeImage.value, 226, 2);
ctx.drawImage(batteryImage.value, 242, 4);
});
</script>
<template>
<img
ref="gbaDisplayImage"
src="/assets/images/home/top-screen/status-bar/gba-display.png"
hidden
/>
<img
ref="startupModeImage"
src="/assets/images/home/top-screen/status-bar/startup-mode.png"
hidden
/>
<img
ref="batteryImage"
src="/assets/images/home/top-screen/status-bar/battery.png"
hidden
/>
</template>

View File

@@ -0,0 +1,10 @@
<template>
<Screen>
<HomeTopScreenBackground />
<HomeTopScreenCalendar />
<HomeTopScreenClock />
<HomeTopScreenStatusBar />
<slot />
</Screen>
</template>