[dyad] Implemented "auto" image dimensioning - wrote 1 file(s)

This commit is contained in:
[dyad]
2026-01-18 13:25:54 +01:00
parent ae0dd76c7a
commit 626ce09686

View File

@@ -38,7 +38,6 @@ import {
} from "@/components/ui/tooltip"; } from "@/components/ui/tooltip";
const aspectRatios = [ const aspectRatios = [
{ name: "Original", value: "original" },
{ name: "Custom", value: "custom" }, { name: "Custom", value: "custom" },
{ name: "1:1 (Square)", value: "1/1" }, { name: "1:1 (Square)", value: "1/1" },
{ name: "4:3 (Standard)", value: "4/3" }, { name: "4:3 (Standard)", value: "4/3" },
@@ -71,7 +70,6 @@ export function ImageConverter() {
const [width, setWidth] = useState<number | string>(initialSettings.width); const [width, setWidth] = useState<number | string>(initialSettings.width);
const [height, setHeight] = useState<number | string>(initialSettings.height); const [height, setHeight] = useState<number | string>(initialSettings.height);
const [aspectRatio, setAspectRatio] = useState<string>(initialSettings.aspectRatio); const [aspectRatio, setAspectRatio] = useState<string>(initialSettings.aspectRatio);
const [originalImageRatio, setOriginalImageRatio] = useState<number | null>(null);
const [keepOrientation, setKeepOrientation] = useState<boolean>(initialSettings.keepOrientation); const [keepOrientation, setKeepOrientation] = useState<boolean>(initialSettings.keepOrientation);
const [format, setFormat] = useState<"png" | "jpeg" | "webp">(initialSettings.format); const [format, setFormat] = useState<"png" | "jpeg" | "webp">(initialSettings.format);
const [quality, setQuality] = useState<number>(initialSettings.quality); const [quality, setQuality] = useState<number>(initialSettings.quality);
@@ -110,19 +108,6 @@ export function ImageConverter() {
return; return;
} }
if (images.length === 0 && imageFiles.length > 0) {
const firstImage = imageFiles[0];
const img = new Image();
img.src = URL.createObjectURL(firstImage);
img.onload = () => {
setOriginalImageRatio(img.naturalWidth / img.naturalHeight);
setAspectRatio("original");
setWidth(img.naturalWidth);
setHeight(img.naturalHeight);
URL.revokeObjectURL(img.src);
};
}
const newImages = [...images, ...imageFiles]; const newImages = [...images, ...imageFiles];
const newPreviewUrls = [ const newPreviewUrls = [
...previewUrls, ...previewUrls,
@@ -174,13 +159,6 @@ export function ImageConverter() {
setImages(newImages); setImages(newImages);
setPreviewUrls(newPreviewUrls); setPreviewUrls(newPreviewUrls);
setFilenames(newFilenames); setFilenames(newFilenames);
if (newImages.length === 0) {
setOriginalImageRatio(null);
setAspectRatio(initialSettings.aspectRatio);
setWidth(initialSettings.width);
setHeight(initialSettings.height);
}
}; };
const handleClearAll = () => { const handleClearAll = () => {
@@ -188,8 +166,6 @@ export function ImageConverter() {
setImages([]); setImages([]);
setPreviewUrls([]); setPreviewUrls([]);
setFilenames([]); setFilenames([]);
setOriginalImageRatio(null);
setAspectRatio(initialSettings.aspectRatio);
setWidth(initialSettings.width); setWidth(initialSettings.width);
setHeight(initialSettings.height); setHeight(initialSettings.height);
toast.info("All images cleared."); toast.info("All images cleared.");
@@ -221,12 +197,31 @@ export function ImageConverter() {
img.onload = () => { img.onload = () => {
const canvas = document.createElement("canvas"); const canvas = document.createElement("canvas");
let targetWidth = width ? Number(width) : img.naturalWidth; const sourceRatio = img.naturalWidth / img.naturalHeight;
let targetHeight = height ? Number(height) : img.naturalHeight;
let targetWidth: number;
let targetHeight: number;
if (keepOrientation && width && height) { const inputWidth = width ? Number(width) : 0;
const inputHeight = height ? Number(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 (keepOrientation && (inputWidth || inputHeight)) {
const isOriginalPortrait = img.naturalHeight > img.naturalWidth; const isOriginalPortrait = img.naturalHeight > img.naturalWidth;
const isTargetPortrait = Number(height) > Number(width); const isTargetPortrait = targetHeight > targetWidth;
if (isOriginalPortrait !== isTargetPortrait) { if (isOriginalPortrait !== isTargetPortrait) {
[targetWidth, targetHeight] = [targetHeight, targetWidth]; [targetWidth, targetHeight] = [targetHeight, targetWidth];
} }
@@ -365,14 +360,13 @@ export function ImageConverter() {
setDefaultBaseName(initialSettings.defaultBaseName); setDefaultBaseName(initialSettings.defaultBaseName);
setScaleMode(initialSettings.scaleMode); setScaleMode(initialSettings.scaleMode);
setObjectPosition(initialSettings.objectPosition); setObjectPosition(initialSettings.objectPosition);
setOriginalImageRatio(null);
toast.success("All settings have been reset to their defaults."); toast.success("All settings have been reset to their defaults.");
}; };
const handleAspectRatioChange = (value: string) => { const handleAspectRatioChange = (value: string) => {
setAspectRatio(value); setAspectRatio(value);
if (value === "custom" || value === "original") { if (value === "custom") {
return; return;
} }
@@ -396,27 +390,13 @@ export function ImageConverter() {
}; };
const handleWidthChange = (e: React.ChangeEvent<HTMLInputElement>) => { const handleWidthChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newWidthValue = e.target.value; setWidth(e.target.value);
setWidth(newWidthValue); setAspectRatio("custom");
if (aspectRatio === 'original' && originalImageRatio && newWidthValue) {
const newHeight = Math.round(Number(newWidthValue) / originalImageRatio);
setHeight(newHeight);
} else if (aspectRatio !== 'original') {
setAspectRatio("custom");
}
}; };
const handleHeightChange = (e: React.ChangeEvent<HTMLInputElement>) => { const handleHeightChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newHeightValue = e.target.value; setHeight(e.target.value);
setHeight(newHeightValue); setAspectRatio("custom");
if (aspectRatio === 'original' && originalImageRatio && newHeightValue) {
const newWidth = Math.round(Number(newHeightValue) * originalImageRatio);
setWidth(newWidth);
} else if (aspectRatio !== 'original') {
setAspectRatio("custom");
}
}; };
const handleSwapDimensions = () => { const handleSwapDimensions = () => {
@@ -584,13 +564,13 @@ export function ImageConverter() {
</TooltipContent> </TooltipContent>
</Tooltip> </Tooltip>
</div> </div>
<Select value={aspectRatio} onValueChange={handleAspectRatioChange} disabled={!hasImages && aspectRatio === 'original'}> <Select value={aspectRatio} onValueChange={handleAspectRatioChange}>
<SelectTrigger id="aspect-ratio" className="mt-2"> <SelectTrigger id="aspect-ratio" className="mt-2">
<SelectValue placeholder="Select aspect ratio" /> <SelectValue placeholder="Select aspect ratio" />
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
{aspectRatios.map((ratio) => ( {aspectRatios.map((ratio) => (
<SelectItem key={ratio.value} value={ratio.value} disabled={ratio.value === 'original' && !originalImageRatio}> <SelectItem key={ratio.value} value={ratio.value}>
{ratio.name} {ratio.name}
</SelectItem> </SelectItem>
))} ))}
@@ -610,7 +590,7 @@ export function ImageConverter() {
</TooltipContent> </TooltipContent>
</Tooltip> </Tooltip>
</div> </div>
<Input id="width" type="number" placeholder="Original" value={width} onChange={handleWidthChange} /> <Input id="width" type="number" placeholder="Auto" value={width} onChange={handleWidthChange} />
</div> </div>
<Tooltip> <Tooltip>
<TooltipTrigger asChild> <TooltipTrigger asChild>
@@ -634,7 +614,7 @@ export function ImageConverter() {
</TooltipContent> </TooltipContent>
</Tooltip> </Tooltip>
</div> </div>
<Input id="height" type="number" placeholder="Original" value={height} onChange={handleHeightChange} /> <Input id="height" type="number" placeholder="Auto" value={height} onChange={handleHeightChange} />
</div> </div>
</div> </div>
<div className="flex items-center space-x-2 pt-2"> <div className="flex items-center space-x-2 pt-2">