Automaattinen kuvanpienennys ja paremmat virheilmoitukset uploadissa

This commit is contained in:
2026-03-08 01:06:45 +02:00
parent 2def3d2c3e
commit d380884248
2 changed files with 80 additions and 6 deletions

View File

@@ -455,11 +455,45 @@
// =========================== // ===========================
// IMAGE UPLOAD // IMAGE UPLOAD
// =========================== // ===========================
async function resizeImage(file, maxPx = 1920, quality = 0.85) {
if (file.type === 'image/gif') return file;
return new Promise(resolve => {
const img = new Image();
const url = URL.createObjectURL(file);
img.onload = () => {
URL.revokeObjectURL(url);
const ratio = Math.min(maxPx / img.naturalWidth, maxPx / img.naturalHeight, 1);
if (ratio === 1 && file.size < 1.5 * 1024 * 1024) { resolve(file); return; }
const canvas = document.createElement('canvas');
canvas.width = Math.round(img.naturalWidth * ratio);
canvas.height = Math.round(img.naturalHeight * ratio);
canvas.getContext('2d').drawImage(img, 0, 0, canvas.width, canvas.height);
canvas.toBlob(
blob => resolve(new File([blob], 'image.jpg', { type: 'image/jpeg' })),
'image/jpeg', quality
);
};
img.src = url;
});
}
async function uploadImgAdmin(input, hiddenId, previewId, labelId) { async function uploadImgAdmin(input, hiddenId, previewId, labelId) {
const file = input.files[0]; const file = input.files[0];
if (!file) return; if (!file) return;
const allowed = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
if (!allowed.includes(file.type)) {
showToast('⚠️ Tuetut muodot: JPG, PNG, GIF, WebP');
input.value = '';
return;
}
const lbl = document.getElementById(labelId);
lbl.style.opacity = '0.5';
const resized = await resizeImage(file);
const formData = new FormData(); const formData = new FormData();
formData.append('file', file); formData.append('file', resized, resized.name || 'image.jpg');
try { try {
const res = await fetch('upload.php', { method: 'POST', body: formData }); const res = await fetch('upload.php', { method: 'POST', body: formData });
if (!res.ok) throw new Error(await res.text()); if (!res.ok) throw new Error(await res.text());
@@ -468,9 +502,11 @@
const prev = document.getElementById(previewId); const prev = document.getElementById(previewId);
prev.src = data.url; prev.src = data.url;
prev.style.display = 'block'; prev.style.display = 'block';
document.getElementById(labelId).classList.add('has-image'); lbl.classList.add('has-image');
} catch (e) { } catch (e) {
showToast('⚠️ Kuvan lataus epäonnistui.'); showToast('⚠️ Kuvan lataus epäonnistui. Tuetut muodot: JPG, PNG, GIF, WebP.');
} finally {
lbl.style.opacity = '';
} }
} }

View File

@@ -389,11 +389,47 @@ function closeSubmitModal() {
document.body.style.overflow = ''; document.body.style.overflow = '';
} }
async function resizeImage(file, maxPx = 1920, quality = 0.85) {
// Älä muuta GIF:ejä (animaatio menisi rikki)
if (file.type === 'image/gif') return file;
return new Promise(resolve => {
const img = new Image();
const url = URL.createObjectURL(file);
img.onload = () => {
URL.revokeObjectURL(url);
const ratio = Math.min(maxPx / img.naturalWidth, maxPx / img.naturalHeight, 1);
// Jos kuva on jo tarpeeksi pieni, palauta sellaisenaan
if (ratio === 1 && file.size < 1.5 * 1024 * 1024) { resolve(file); return; }
const canvas = document.createElement('canvas');
canvas.width = Math.round(img.naturalWidth * ratio);
canvas.height = Math.round(img.naturalHeight * ratio);
canvas.getContext('2d').drawImage(img, 0, 0, canvas.width, canvas.height);
canvas.toBlob(
blob => resolve(new File([blob], 'image.jpg', { type: 'image/jpeg' })),
'image/jpeg', quality
);
};
img.src = url;
});
}
async function uploadImg(input, hiddenId, previewId, labelId) { async function uploadImg(input, hiddenId, previewId, labelId) {
const file = input.files[0]; const file = input.files[0];
if (!file) return; if (!file) return;
const allowed = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
if (!allowed.includes(file.type)) {
alert('Tuetut kuvamuodot: JPG, PNG, GIF, WebP');
input.value = '';
return;
}
const lbl = document.getElementById(labelId);
lbl.style.opacity = '0.5';
const resized = await resizeImage(file);
const formData = new FormData(); const formData = new FormData();
formData.append('file', file); formData.append('file', resized, resized.name || 'image.jpg');
try { try {
const res = await fetch('upload.php', { method: 'POST', body: formData }); const res = await fetch('upload.php', { method: 'POST', body: formData });
if (!res.ok) throw new Error(await res.text()); if (!res.ok) throw new Error(await res.text());
@@ -402,9 +438,11 @@ async function uploadImg(input, hiddenId, previewId, labelId) {
const prev = document.getElementById(previewId); const prev = document.getElementById(previewId);
prev.src = data.url; prev.src = data.url;
prev.style.display = 'block'; prev.style.display = 'block';
document.getElementById(labelId).classList.add('has-image'); lbl.classList.add('has-image');
} catch (e) { } catch (e) {
alert('Kuvan lataus epäonnistui: ' + e.message); alert('Kuvan lataus epäonnistui. Tuetut muodot: JPG, PNG, GIF, WebP (max 8 MB).');
} finally {
lbl.style.opacity = '';
} }
} }