feat: move top screen components to own folder, and implement calendar
This commit is contained in:
13
app/components/TopScreen/Background.vue
Normal file
13
app/components/TopScreen/Background.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<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/background.png" hidden />
|
||||
</template>
|
||||
75
app/components/TopScreen/Calendar.vue
Normal file
75
app/components/TopScreen/Calendar.vue
Normal file
@@ -0,0 +1,75 @@
|
||||
<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/calendar_last-row.png" hidden />
|
||||
<img ref="daySelectorImage" src="/assets/calendar_day-selector.png" hidden />
|
||||
</template>
|
||||
8
app/components/TopScreen/TopScreen.vue
Normal file
8
app/components/TopScreen/TopScreen.vue
Normal file
@@ -0,0 +1,8 @@
|
||||
<template>
|
||||
<Screen>
|
||||
<TopScreenBackground />
|
||||
<TopScreenCalendar />
|
||||
|
||||
<slot />
|
||||
</Screen>
|
||||
</template>
|
||||
Reference in New Issue
Block a user