UNPKG

@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
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 }) }