initial: bootstrap from BukidBountyApp base

This commit is contained in:
Jonathan Sykes
2026-06-06 18:43:00 +08:00
commit eb4a5731fb
5674 changed files with 160857 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
/**
* Resize an image file while preserving aspect ratio.
*
* @param {File|Blob} file
* @param {number} maxWidth
* @param {number} maxHeight
* @param {number} [quality=0.7] - JPEG/WebP quality (01)
* @returns {Promise<Blob>}
*
* @example
* const resized = await resizeImage(file, 800, 800)
*/
export function resizeImage(file, maxWidth, maxHeight, quality = 0.7) {
return new Promise((resolve, reject) => {
if (!(file instanceof Blob)) {
reject(new Error('Invalid file'))
return
}
const reader = new FileReader()
reader.onload = e => {
const img = new Image()
img.onload = () => {
let { width, height } = img
const widthRatio = maxWidth / width
const heightRatio = maxHeight / height
const ratio = Math.min(widthRatio, heightRatio, 1)
width = Math.round(width * ratio)
height = Math.round(height * ratio)
const canvas = document.createElement('canvas')
canvas.width = width
canvas.height = height
const ctx = canvas.getContext('2d')
ctx.drawImage(img, 0, 0, width, height)
canvas.toBlob(
blob => {
if (!blob) {
reject(new Error('Image resize failed'))
return
}
resolve(blob)
},
file.type || 'image/jpeg',
quality
)
}
img.onerror = () => reject(new Error('Invalid image'))
img.src = e.target.result
}
reader.onerror = () => reject(new Error('File read error'))
reader.readAsDataURL(file)
})
}