diff --git a/.gitignore b/.gitignore
index e36be2a..72879b1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
# generated
public/nds/images/projects/pokemons
+public/nds/atlas.webp
app/composables/useAssets.ts
# ESlint
diff --git a/app/components/Common/Bars.vue b/app/components/Common/Bars.vue
index c26042d..8f5d2a8 100644
--- a/app/components/Common/Bars.vue
+++ b/app/components/Common/Bars.vue
@@ -13,29 +13,17 @@ const props = withDefaults(
);
const { onRender } = useScreen();
-
-const app = useAppStore();
const { assets } = useAssets();
-const BAR_WIDTH = 256;
-const BAR_HEIGHT = 24;
const TITLE_Y = 5;
onRender((ctx) => {
ctx.globalAlpha = props.opacity;
// top bar
- ctx.drawImage(
- assets.common.barsSheet,
- 0,
- (app.color.row * 4 + app.color.col) * BAR_HEIGHT,
- BAR_WIDTH,
- BAR_HEIGHT,
- 0,
- -props.yOffset,
- BAR_WIDTH,
- BAR_HEIGHT,
- );
+ assets.images.common.barsSheet.draw(ctx, 0, -props.yOffset, {
+ colored: true,
+ });
if (props.title) {
ctx.fillStyle = "#000000";
@@ -46,17 +34,9 @@ onRender((ctx) => {
ctx.scale(1, -1);
// bottom bar
- ctx.drawImage(
- assets.common.barsSheet,
- 0,
- (app.color.row * 4 + app.color.col) * BAR_HEIGHT,
- BAR_WIDTH,
- BAR_HEIGHT,
- 0,
- -192 - props.yOffset,
- BAR_WIDTH,
- BAR_HEIGHT,
- );
+ assets.images.common.barsSheet.draw(ctx, 0, -192 - props.yOffset, {
+ colored: true,
+ });
}, 50);
defineOptions({
diff --git a/app/components/Common/ButtonSelector.vue b/app/components/Common/ButtonSelector.vue
index 9fa0f92..57a90a5 100644
--- a/app/components/Common/ButtonSelector.vue
+++ b/app/components/Common/ButtonSelector.vue
@@ -11,11 +11,9 @@ const props = withDefaults(
const { onRender } = useScreen();
-const app = useAppStore();
const { assets } = useAssets();
const ANIMATION_SPEED = 15;
-const CORNER_SIZE = 11;
let [currentX, currentY, currentWidth, currentHeight] = props.rect;
@@ -48,67 +46,31 @@ onRender((ctx, deltaTime) => {
ctx.globalAlpha = props.opacity;
- const spriteY = (app.color.row * 4 + app.color.col) * CORNER_SIZE;
+ // top-left corner
+ assets.images.common.selectorCornersSheet.draw(ctx, x, y, { colored: true });
- // Top-left corner
- ctx.drawImage(
- assets.common.selectorCornersSheet,
- 0,
- spriteY,
- CORNER_SIZE,
- CORNER_SIZE,
- x,
- y,
- CORNER_SIZE,
- CORNER_SIZE,
- );
-
- // Top-right corner
+ // top-right corner
ctx.save();
ctx.scale(-1, 1);
- ctx.drawImage(
- assets.common.selectorCornersSheet,
- 0,
- spriteY,
- CORNER_SIZE,
- CORNER_SIZE,
- -(x + w),
- y,
- CORNER_SIZE,
- CORNER_SIZE,
- );
+ assets.images.common.selectorCornersSheet.draw(ctx, -(x + w), y, {
+ colored: true,
+ });
ctx.restore();
- // Bottom-left corner
+ // bottom-left corner
ctx.save();
ctx.scale(1, -1);
- ctx.drawImage(
- assets.common.selectorCornersSheet,
- 0,
- spriteY,
- CORNER_SIZE,
- CORNER_SIZE,
- x,
- -(y + h),
- CORNER_SIZE,
- CORNER_SIZE,
- );
+ assets.images.common.selectorCornersSheet.draw(ctx, x, -(y + h), {
+ colored: true,
+ });
ctx.restore();
- // Bottom-right corner
+ // bottom-right corner
ctx.save();
ctx.scale(-1, -1);
- ctx.drawImage(
- assets.common.selectorCornersSheet,
- 0,
- spriteY,
- CORNER_SIZE,
- CORNER_SIZE,
- -(x + w),
- -(y + h),
- CORNER_SIZE,
- CORNER_SIZE,
- );
+ assets.images.common.selectorCornersSheet.draw(ctx, -(x + w), -(y + h), {
+ colored: true,
+ });
ctx.restore();
}, 40);
diff --git a/app/components/Common/Buttons.vue b/app/components/Common/Buttons.vue
index 4a4f901..8ba58f2 100644
--- a/app/components/Common/Buttons.vue
+++ b/app/components/Common/Buttons.vue
@@ -15,9 +15,9 @@ const { onRender, onClick } = useScreen();
const { assets } = useAssets();
-const BUTTON_WIDTH = assets.common.button.width;
-const BUTTON_HEIGHT = assets.common.button.height;
-const LETTER_WIDTH = assets.common.B.width;
+const BUTTON_WIDTH = assets.images.common.button.rect.width;
+const BUTTON_HEIGHT = assets.images.common.button.rect.height;
+const LETTER_WIDTH = assets.images.common.B.rect.width;
const B_BUTTON: Rect = [31, 172, BUTTON_WIDTH, BUTTON_HEIGHT];
const A_BUTTON: Rect = [144, 172, BUTTON_WIDTH, BUTTON_HEIGHT];
@@ -29,23 +29,25 @@ onRender((ctx) => {
ctx.translate(0, props.yOffset);
const drawButton = (
- image: HTMLImageElement,
+ image: {
+ draw: (ctx: CanvasRenderingContext2D, x: number, y: number) => void;
+ },
text: string,
x: number,
offset: number,
) => {
- ctx.drawImage(assets.common.button, x, 172);
+ assets.images.common.button.draw(ctx, x, 172);
const { actualBoundingBoxRight: textWidth } = ctx.measureText(text);
const width = LETTER_WIDTH + 4 + textWidth;
const left = Math.ceil(x + BUTTON_WIDTH / 2 - width / 2 - offset / 2);
- ctx.drawImage(image, left, 176);
+ image.draw(ctx, left, 176);
ctx.fillText(text, left + LETTER_WIDTH + 4, 185);
};
- drawButton(assets.common.B, props.bLabel, 31, 5);
- drawButton(assets.common.A, props.aLabel, 144, 0);
+ drawButton(assets.images.common.B, props.bLabel, 31, 5);
+ drawButton(assets.images.common.A, props.aLabel, 144, 0);
}, 60);
onClick((x, y) => {
diff --git a/app/components/Common/ConfirmationModal.vue b/app/components/Common/ConfirmationModal.vue
index 58b0e1e..3f1aa2b 100644
--- a/app/components/Common/ConfirmationModal.vue
+++ b/app/components/Common/ConfirmationModal.vue
@@ -6,8 +6,8 @@ const { onRender } = useScreen();
const { assets } = useAssets();
const confirmationModal = useConfirmationModal();
-const BG_WIDTH = assets.common.confirmationModal.width;
-const BG_HEIGHT = assets.common.confirmationModal.height;
+const BG_WIDTH = assets.images.common.confirmationModal.rect.width;
+const BG_HEIGHT = assets.images.common.confirmationModal.rect.height;
const BG_X = Math.floor((SCREEN_WIDTH - BG_WIDTH) / 2);
const BG_Y = Math.floor((SCREEN_HEIGHT - BG_HEIGHT) / 2);
@@ -34,7 +34,7 @@ onRender((ctx) => {
ctx.translate(0, confirmationModal.offsetY);
- ctx.drawImage(assets.common.confirmationModal, BG_X, BG_Y);
+ assets.images.common.confirmationModal.draw(ctx, BG_X, BG_Y);
ctx.font = "16px Pokemon DP Pro";
ctx.textBaseline = "top";
diff --git a/app/components/Contact/BottomScreen/Background.vue b/app/components/Contact/BottomScreen/Background.vue
index 867ce97..74dc81d 100644
--- a/app/components/Contact/BottomScreen/Background.vue
+++ b/app/components/Contact/BottomScreen/Background.vue
@@ -5,12 +5,12 @@ const store = useContactStore();
const { assets } = useAssets();
onRender((ctx) => {
- ctx.drawImage(assets.home.bottomScreen.background, 0, 0);
+ assets.images.home.bottomScreen.background.draw(ctx, 0, 0);
ctx.globalAlpha = store.isIntro
? store.intro.stage2Opacity
: store.outro.stage3Opacity;
- ctx.drawImage(assets.contact.bottomScreen.background, 0, 0);
+ assets.images.contact.bottomScreen.background.draw(ctx, 0, 0);
});
defineOptions({
diff --git a/app/components/Contact/BottomScreen/Buttons.vue b/app/components/Contact/BottomScreen/Buttons.vue
index 3c6ad72..f48a6c2 100644
--- a/app/components/Contact/BottomScreen/Buttons.vue
+++ b/app/components/Contact/BottomScreen/Buttons.vue
@@ -8,7 +8,7 @@ onRender((ctx) => {
ctx.globalAlpha = store.isIntro
? store.intro.stage3Opacity
: store.outro.stage1Opacity;
- ctx.drawImage(assets.contact.bottomScreen.buttons, 31, 32);
+ assets.images.contact.bottomScreen.buttons.draw(ctx, 31, 32);
});
defineOptions({
diff --git a/app/components/Contact/TopScreen/Background.vue b/app/components/Contact/TopScreen/Background.vue
index dd4b714..ccc78a5 100644
--- a/app/components/Contact/TopScreen/Background.vue
+++ b/app/components/Contact/TopScreen/Background.vue
@@ -5,12 +5,12 @@ const store = useContactStore();
const { assets } = useAssets();
onRender((ctx) => {
- ctx.drawImage(assets.home.topScreen.background, 0, 0);
+ assets.images.home.topScreen.background.draw(ctx, 0, 0);
ctx.globalAlpha = store.isIntro
? store.intro.stage2Opacity
: store.outro.stage3Opacity;
- ctx.drawImage(assets.contact.topScreen.background, 0, 0);
+ assets.images.contact.topScreen.background.draw(ctx, 0, 0);
});
defineOptions({
diff --git a/app/components/Contact/TopScreen/LeftBar.vue b/app/components/Contact/TopScreen/LeftBar.vue
index f499e96..2c9157a 100644
--- a/app/components/Contact/TopScreen/LeftBar.vue
+++ b/app/components/Contact/TopScreen/LeftBar.vue
@@ -8,12 +8,12 @@ onRender((ctx) => {
ctx.globalAlpha = store.isIntro
? store.intro.stage1Opacity
: store.outro.stage2Opacity;
- ctx.drawImage(assets.contact.topScreen.leftBar, 0, 0);
+ assets.images.contact.topScreen.leftBar.draw(ctx, 0, 0);
ctx.globalAlpha = store.isIntro
? store.intro.stage3Opacity
: store.outro.stage1Opacity;
- ctx.drawImage(assets.contact.topScreen.leftBarThings, 0, 0);
+ assets.images.contact.topScreen.leftBarThings.draw(ctx, 0, 0);
});
defineOptions({
diff --git a/app/components/Contact/TopScreen/Notifications.vue b/app/components/Contact/TopScreen/Notifications.vue
index 07d707f..3d8f524 100644
--- a/app/components/Contact/TopScreen/Notifications.vue
+++ b/app/components/Contact/TopScreen/Notifications.vue
@@ -15,7 +15,7 @@ onRender((ctx) => {
const y = 169 - 24 * index + store.notificationsYOffset;
if (y < -24) break;
- ctx.drawImage(assets.contact.bottomScreen.notification, 21, y);
+ assets.images.contact.bottomScreen.notification.draw(ctx, 21, y);
const content = store.notifications[i]!;
ctx.fillStyle = content.includes("opened") ? "#00fbba" : "#e3f300";
@@ -26,8 +26,8 @@ onRender((ctx) => {
ctx.globalAlpha = store.isIntro
? store.intro.stage1Opacity
: store.outro.stage2Opacity;
- ctx.drawImage(
- assets.contact.topScreen.title,
+ assets.images.contact.topScreen.title.draw(
+ ctx,
21,
store.isIntro
? store.intro.titleY
diff --git a/app/components/Gallery/BottomScreen/BottomScreen.vue b/app/components/Gallery/BottomScreen/BottomScreen.vue
index b0c256e..7315e53 100644
--- a/app/components/Gallery/BottomScreen/BottomScreen.vue
+++ b/app/components/Gallery/BottomScreen/BottomScreen.vue
@@ -4,7 +4,7 @@ const store = useGalleryStore();
const { assets } = useAssets();
onRender((ctx) => {
- ctx.drawImage(assets.home.bottomScreen.background, 0, 0);
+ assets.images.home.bottomScreen.background.draw(ctx, 0, 0);
ctx.fillStyle = "#000000";
ctx.globalAlpha = store.isIntro
diff --git a/app/components/Gallery/TopScreen/TopScreen.vue b/app/components/Gallery/TopScreen/TopScreen.vue
index 7bbdc61..03e1c34 100644
--- a/app/components/Gallery/TopScreen/TopScreen.vue
+++ b/app/components/Gallery/TopScreen/TopScreen.vue
@@ -14,7 +14,7 @@ onMounted(() => {
});
onRender((ctx) => {
- ctx.drawImage(assets.home.topScreen.background, 0, 0);
+ assets.images.home.topScreen.background.draw(ctx, 0, 0);
ctx.fillStyle = "#000000";
ctx.globalAlpha = store.isIntro
diff --git a/app/components/Home/BottomScreen/Background.vue b/app/components/Home/BottomScreen/Background.vue
index 3b5dc8d..16cabcf 100644
--- a/app/components/Home/BottomScreen/Background.vue
+++ b/app/components/Home/BottomScreen/Background.vue
@@ -3,11 +3,12 @@ const { onRender } = useScreen();
const store = useHomeStore();
const app = useAppStore();
+
const { assets } = useAssets();
onRender((ctx) => {
ctx.globalAlpha = app.booted ? 1 : store.intro.stage1Opacity;
- ctx.drawImage(assets.home.bottomScreen.background, 0, 0);
+ assets.images.home.bottomScreen.background.draw(ctx, 0, 0);
});
defineOptions({
diff --git a/app/components/Home/BottomScreen/Button.vue b/app/components/Home/BottomScreen/Button.vue
index 63900c7..2337472 100644
--- a/app/components/Home/BottomScreen/Button.vue
+++ b/app/components/Home/BottomScreen/Button.vue
@@ -3,14 +3,16 @@ const props = defineProps<{
x: number;
y: number;
opacity: number;
- image: HTMLImageElement;
+ image: {
+ draw: (ctx: CanvasRenderingContext2D, x: number, y: number) => void;
+ };
}>();
const { onRender } = useScreen();
onRender((ctx) => {
ctx.globalAlpha = props.opacity;
- ctx.drawImage(props.image, props.x, props.y);
+ props.image.draw(ctx, props.x, props.y);
});
defineOptions({
diff --git a/app/components/Home/BottomScreen/Buttons.vue b/app/components/Home/BottomScreen/Buttons.vue
index 7533248..077fc0d 100644
--- a/app/components/Home/BottomScreen/Buttons.vue
+++ b/app/components/Home/BottomScreen/Buttons.vue
@@ -128,45 +128,45 @@ onRender((ctx) => {
:x="33"
:y="25 + getButtonOffset('projects')"
:opacity="getOpacity('projects')"
- :image="assets.home.bottomScreen.buttons.game"
+ :image="assets.images.home.bottomScreen.buttons.game"
/>
diff --git a/app/components/Home/TopScreen/Background.vue b/app/components/Home/TopScreen/Background.vue
index 3ccc37f..88ae153 100644
--- a/app/components/Home/TopScreen/Background.vue
+++ b/app/components/Home/TopScreen/Background.vue
@@ -7,7 +7,7 @@ const { assets } = useAssets();
onRender((ctx) => {
ctx.globalAlpha = app.booted ? 1 : store.intro.stage1Opacity;
- ctx.drawImage(assets.home.topScreen.background, 0, 0);
+ assets.images.home.topScreen.background.draw(ctx, 0, 0);
});
defineOptions({
diff --git a/app/components/Home/TopScreen/Calendar.vue b/app/components/Home/TopScreen/Calendar.vue
index 68d6cb5..3c2f71d 100644
--- a/app/components/Home/TopScreen/Calendar.vue
+++ b/app/components/Home/TopScreen/Calendar.vue
@@ -2,7 +2,6 @@
const { onRender } = useScreen();
// NOTE: calendar background is handled by TopScreenBackground
-const app = useAppStore();
const store = useHomeStore();
const { assets } = useAssets();
@@ -14,7 +13,6 @@ onRender((ctx) => {
const CALENDAR_ROWS = 5;
const CALENDAR_LEFT = 128;
const CALENDAR_TOP = 64;
- const SELECTOR_SIZE = 13;
ctx.fillStyle = "#343434";
@@ -30,16 +28,16 @@ onRender((ctx) => {
: store.isOutro && store.outro.animateTop
? store.outro.stage1Opacity
: 1;
- ctx.drawImage(
- assets.home.topScreen.calendar.calendar,
+ assets.images.home.topScreen.calendar.calendar.draw(
+ ctx,
CALENDAR_LEFT - 3,
CALENDAR_TOP - 33,
);
const extraRow = CALENDAR_COLS * CALENDAR_ROWS - daysInMonth - firstDay < 0;
if (extraRow) {
- ctx.drawImage(
- assets.home.topScreen.calendar.lastRow,
+ assets.images.home.topScreen.calendar.lastRow.draw(
+ ctx,
CALENDAR_LEFT - 3,
CALENDAR_TOP + 79,
);
@@ -63,16 +61,11 @@ onRender((ctx) => {
const cellTop = CALENDAR_TOP + col * 16;
if (now.getDate() === day) {
- ctx.drawImage(
- assets.home.topScreen.calendar.daySelectorsSheet,
- 0,
- (app.color.row * 4 + app.color.col) * SELECTOR_SIZE,
- SELECTOR_SIZE,
- SELECTOR_SIZE,
+ assets.images.home.topScreen.calendar.daySelectorsSheet.draw(
+ ctx,
cellLeft + 1,
cellTop + 1,
- SELECTOR_SIZE,
- SELECTOR_SIZE,
+ { colored: true },
);
}
diff --git a/app/components/Home/TopScreen/Clock.vue b/app/components/Home/TopScreen/Clock.vue
index bfd564a..606e3cc 100644
--- a/app/components/Home/TopScreen/Clock.vue
+++ b/app/components/Home/TopScreen/Clock.vue
@@ -59,7 +59,7 @@ onRender((ctx) => {
: store.isOutro && store.outro.animateTop
? store.outro.stage1Opacity
: 1;
- ctx.drawImage(assets.home.topScreen.clock, 13, 45);
+ assets.images.home.topScreen.clock.draw(ctx, 13, 45);
ctx.globalAlpha = store.isIntro
? store.intro.stage1Opacity
diff --git a/app/components/Home/TopScreen/StatusBar.vue b/app/components/Home/TopScreen/StatusBar.vue
index 727066c..88e82c2 100644
--- a/app/components/Home/TopScreen/StatusBar.vue
+++ b/app/components/Home/TopScreen/StatusBar.vue
@@ -1,13 +1,9 @@