@shopify/shop-minis-react
Version:
React component library for Shopify Shop Minis with Tailwind CSS v4 support (source-only, requires TypeScript)
109 lines (94 loc) • 2.39 kB
text/typescript
import type {
ImageQuality,
CustomImageQuality,
} from '../../providers/ImagePickerProvider'
interface ResizeSettings {
size: number
compression: number
}
export interface ResizeImageParams {
file: File
quality: ImageQuality
customQuality?: CustomImageQuality
}
const QUALITY_SETTINGS: {
[key in Exclude<ImageQuality, 'original'>]: ResizeSettings
} = {
low: {
size: 1080,
compression: 0.7,
},
medium: {
size: 1600,
compression: 0.85,
},
high: {
size: 2048,
compression: 0.92,
},
} as const
export function resizeImage({
file,
quality,
customQuality,
}: ResizeImageParams): Promise<File> {
if (quality === 'original') {
return Promise.resolve(file)
}
const defaultSettings = QUALITY_SETTINGS[quality]
const settings: ResizeSettings = customQuality
? {
size: customQuality.size ?? defaultSettings.size,
compression: customQuality.compression ?? defaultSettings.compression,
}
: defaultSettings
const maxSize = settings.size
return new Promise((resolve, reject) => {
const img = new Image()
const url = URL.createObjectURL(file)
img.onerror = () => {
URL.revokeObjectURL(url)
reject(new Error('Failed to load image'))
}
img.onload = () => {
URL.revokeObjectURL(url)
const canvas = document.createElement('canvas')
let width = img.width
let height = img.height
// Resize image dimensions maintaining aspect ratio
if (width > height) {
if (width > maxSize) {
height *= maxSize / width
width = maxSize
}
} else if (height > maxSize) {
width *= maxSize / height
height = maxSize
}
canvas.width = width
canvas.height = height
const ctx = canvas.getContext('2d')
if (!ctx) {
reject(new Error('Failed to get canvas context'))
return
}
ctx.drawImage(img, 0, 0, width, height)
canvas.toBlob(
blob => {
if (!blob) {
reject(new Error('Failed to create blob'))
return
}
const resizedFile = new File([blob], file.name, {
type: 'image/jpeg',
lastModified: Date.now(),
})
resolve(resizedFile)
},
'image/jpeg',
settings.compression
)
}
img.src = url
})
}