feat: add header and footer images for 1x4 and 2x2 layouts, update canvas dimensions accordingly

This commit is contained in:
mrkad@rpi
2026-01-17 22:35:08 +07:00
parent 0d6d08f952
commit 2891ed9620
16 changed files with 77 additions and 18 deletions

View File

@@ -4,7 +4,7 @@ import HelloWorld from './components/HelloWorld.vue'
</script>
<template>
<header>
<!-- <header >
<img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" />
<div class="wrapper">
@@ -15,8 +15,9 @@ import HelloWorld from './components/HelloWorld.vue'
<RouterLink to="/about">About</RouterLink>
</nav>
</div>
</header>
</header> -->
<RouterLink to="/">Home</RouterLink>
<RouterView />
</template>

BIN
src/assets/footer-1x4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
src/assets/footer-2x2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
src/assets/header-1x4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
src/assets/header-2x2.png Normal file

Binary file not shown.

View File

@@ -69,7 +69,7 @@ const goBack = () => {
</div>
</section>
<section class="frame-section">
<section class="frame-section" style="display: none;">
<h2>เลอกกรอบ</h2>
<div class="frame-options">
<div

View File

@@ -84,15 +84,23 @@ const generateAndCacheImage = async () => {
const gap = 20 // ระยะห่างระหว่างรูป
let canvasWidth, canvasHeight
let headerHeight = 0, footerHeight = 0
let sidePadding = 0
if (layout.value === '1x4') {
// 1x4: 1 คอลัมน์ 4 แถว
canvasWidth = photoWidth + 40
canvasHeight = (photoHeight * 4) + (gap * 3) + 40
// 1x4: 1 คอลัมน์ 4 แถว + header/footer
headerHeight = 50
footerHeight = 50
sidePadding = 30 // padding ซ้ายขวาเพื่อให้ total width = 420
canvasWidth = 420
canvasHeight = headerHeight + (photoHeight * 4) + (gap * 3) + footerHeight
} else {
// 2x2: 2 คอลัมน์ 2 แถว
canvasWidth = (photoWidth * 2) + gap + 40
canvasHeight = (photoHeight * 2) + gap + 40
// 2x2: 2 คอลัมน์ 2 แถว + header/footer
headerHeight = 60
footerHeight = 60
sidePadding = 20 // padding ซ้ายขวาเพื่อให้ total width = 780
canvasWidth = 780
canvasHeight = headerHeight + (photoHeight * 2) + gap + footerHeight
}
console.log('Canvas dimensions:', canvasWidth, 'x', canvasHeight)
@@ -102,7 +110,15 @@ const generateAndCacheImage = async () => {
// วาด background ตาม frame
drawFrameBackground(context, canvasWidth, canvasHeight, frame.value)
// วาดรูปภาพ
// วาด header image
const headerImagePath = layout.value === '1x4' ? '/assets/header-1x4.png' : '/assets/header-2x2.png'
await drawHeaderFooterImage(context, headerImagePath, 0, 0, canvasWidth, headerHeight)
// วาด footer image
const footerImagePath = layout.value === '1x4' ? '/assets/footer-1x4.png' : '/assets/footer-2x2.png'
await drawHeaderFooterImage(context, footerImagePath, 0, canvasHeight - footerHeight, canvasWidth, footerHeight)
// วาดรูปภาพ (มี padding ซ้ายขวา)
for (let i = 0; i < photos.value.length; i++) {
const photoSrc = photos.value[i]
if (!photoSrc) continue
@@ -115,15 +131,15 @@ const generateAndCacheImage = async () => {
let x, y
if (layout.value === '1x4') {
// 1x4 layout
x = 0
y = i * (photoHeight + gap)
// 1x4 layout - วาดรูปตรงกลาง (มี padding ซ้ายขวา)
x = sidePadding
y = headerHeight + i * (photoHeight + gap)
} else {
// 2x2 layout
// 2x2 layout - วาดรูปตรงกลาง (มี padding ซ้ายขวา)
const col = i % 2
const row = Math.floor(i / 2)
x = col * (photoWidth + gap)
y = row * (photoHeight + gap)
x = sidePadding + col * (photoWidth + gap)
y = headerHeight + row * (photoHeight + gap)
}
// วาดรูปภาพ
@@ -187,7 +203,7 @@ const drawFrameBackground = (context: CanvasRenderingContext2D, width: number, h
// วาด background ตาม frame type
switch (frameType) {
case 0: // Classic - white
context.fillStyle = '#ffffff'
context.fillStyle = '#000000'
break
case 1: // Modern - gradient
const gradient1 = context.createLinearGradient(0, 0, width, height)
@@ -211,12 +227,38 @@ const drawFrameBackground = (context: CanvasRenderingContext2D, width: number, h
context.fillStyle = '#f8f9fa'
break
default:
context.fillStyle = '#ffffff'
context.fillStyle = '#000000'
}
context.fillRect(0, 0, width, height)
}
const drawHeaderFooterImage = async (context: CanvasRenderingContext2D, imagePath: string, x: number, y: number, width: number, height: number) => {
return new Promise<void>((resolve) => {
const img = new Image()
img.onload = () => {
context.drawImage(img, x, y, width, height)
resolve()
}
img.onerror = () => {
console.warn(`Failed to load header/footer image: ${imagePath}, drawing placeholder`)
// วาด placeholder color แทน
if (imagePath.includes('header-1x4')) {
context.fillStyle = '#007bff' // น้ำเงินสำหรับ 1x4 header
} else if (imagePath.includes('footer-1x4')) {
context.fillStyle = '#dc3545' // แดงสำหรับ 1x4 footer
} else if (imagePath.includes('header-2x2')) {
context.fillStyle = '#28a745' // เขียวสำหรับ 2x2 header
} else if (imagePath.includes('footer-2x2')) {
context.fillStyle = '#ffc107' // เหลืองสำหรับ 2x2 footer
}
context.fillRect(x, y, width, height)
resolve()
}
img.src = imagePath
})
}
const startOver = () => {
// เคลียร์ข้อมูลและกลับไปหน้าแรก
localStorage.removeItem('photobooth-photos')