[dyad] Refactoring the app for modularity - wrote 12 file(s)

This commit is contained in:
[dyad]
2026-01-18 16:22:20 +01:00
parent 69a9b62da8
commit d33dceb08c
12 changed files with 1052 additions and 889 deletions

128
src/lib/image-processor.ts Normal file
View File

@@ -0,0 +1,128 @@
import { ConversionSettings, ImageFile } from "@/types";
export function generateFinalFilename(
baseFilename: string,
settings: ConversionSettings,
index: number
): string {
const { prefix, suffix, useCounter, counterStart, counterDigits } = settings;
let finalName = `${prefix}${baseFilename}${suffix}`;
if (useCounter) {
const counter = (index + counterStart).toString().padStart(counterDigits, '0');
finalName += `${counter}`;
}
return finalName;
}
export function processImage(
imageFile: ImageFile,
settings: ConversionSettings
): Promise<string> {
return new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = "anonymous";
img.src = imageFile.previewUrl;
img.onload = () => {
const canvas = document.createElement("canvas");
const sourceRatio = img.naturalWidth / img.naturalHeight;
let targetWidth: number;
let targetHeight: number;
const inputWidth = settings.width ? Number(settings.width) : 0;
const inputHeight = settings.height ? Number(settings.height) : 0;
if (inputWidth && !inputHeight) {
targetWidth = inputWidth;
targetHeight = Math.round(targetWidth / sourceRatio);
} else if (!inputWidth && inputHeight) {
targetHeight = inputHeight;
targetWidth = Math.round(targetHeight * sourceRatio);
} else if (inputWidth && inputHeight) {
targetWidth = inputWidth;
targetHeight = inputHeight;
} else {
targetWidth = img.naturalWidth;
targetHeight = img.naturalHeight;
}
if (settings.keepOrientation && (inputWidth || inputHeight)) {
const isOriginalPortrait = img.naturalHeight > img.naturalWidth;
const isTargetPortrait = targetHeight > targetWidth;
if (isOriginalPortrait !== isTargetPortrait) {
[targetWidth, targetHeight] = [targetHeight, targetWidth];
}
}
canvas.width = targetWidth;
canvas.height = targetHeight;
const ctx = canvas.getContext("2d");
if (ctx) {
const sWidth = img.naturalWidth;
const sHeight = img.naturalHeight;
const dWidth = targetWidth;
const dHeight = targetHeight;
if (settings.scaleMode === 'fill' || !settings.width || !settings.height) {
ctx.drawImage(img, 0, 0, dWidth, dHeight);
} else {
const sourceRatio = sWidth / sHeight;
const targetRatio = dWidth / dHeight;
let sx = 0, sy = 0, sRenderWidth = sWidth, sRenderHeight = sHeight;
let dx = 0, dy = 0, dRenderWidth = dWidth, dRenderHeight = dHeight;
const [hPos, vPos] = settings.objectPosition.split(' ');
if (settings.scaleMode === 'cover') {
if (sourceRatio > targetRatio) {
sRenderHeight = sHeight;
sRenderWidth = sHeight * targetRatio;
if (hPos === 'center') sx = (sWidth - sRenderWidth) / 2;
if (hPos === 'right') sx = sWidth - sRenderWidth;
} else {
sRenderWidth = sWidth;
sRenderHeight = sWidth / targetRatio;
if (vPos === 'center') sy = (sHeight - sRenderHeight) / 2;
if (vPos === 'bottom') sy = sHeight - sRenderHeight;
}
ctx.drawImage(img, sx, sy, sRenderWidth, sRenderHeight, 0, 0, dWidth, dHeight);
} else if (settings.scaleMode === 'contain') {
if (sourceRatio > targetRatio) {
dRenderWidth = dWidth;
dRenderHeight = dWidth / sourceRatio;
if (vPos === 'center') dy = (dHeight - dRenderHeight) / 2;
if (vPos === 'bottom') dy = dHeight - dRenderHeight;
} else {
dRenderHeight = dHeight;
dRenderWidth = dHeight * sourceRatio;
if (hPos === 'center') dx = (dWidth - dRenderWidth) / 2;
if (hPos === 'right') dx = dWidth - dRenderWidth;
}
ctx.drawImage(img, 0, 0, sWidth, sHeight, dx, dy, dRenderWidth, dRenderHeight);
}
}
const mimeType = `image/${settings.format}`;
const dataUrl = canvas.toDataURL(mimeType, settings.format === 'png' ? undefined : settings.quality / 100);
resolve(dataUrl);
} else {
reject(new Error(`Could not get canvas context for ${imageFile.file.name}.`));
}
};
img.onerror = () => {
reject(new Error(`Failed to load ${imageFile.file.name} for conversion.`));
};
});
}
export function downloadDataUrl(dataUrl: string, filename: string) {
const link = document.createElement("a");
link.href = dataUrl;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}