From d380884248da972c2493a74f86b1d780c2558cd1 Mon Sep 17 00:00:00 2001 From: Jukka Lampikoski Date: Sun, 8 Mar 2026 01:06:45 +0200 Subject: [PATCH] Automaattinen kuvanpienennys ja paremmat virheilmoitukset uploadissa --- admin.html | 42 +++++++++++++++++++++++++++++++++++++++--- script.js | 44 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 80 insertions(+), 6 deletions(-) diff --git a/admin.html b/admin.html index b5c0d2f..d1f59f6 100644 --- a/admin.html +++ b/admin.html @@ -455,11 +455,45 @@ // =========================== // 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) { const file = input.files[0]; 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(); - formData.append('file', file); + formData.append('file', resized, resized.name || 'image.jpg'); try { const res = await fetch('upload.php', { method: 'POST', body: formData }); if (!res.ok) throw new Error(await res.text()); @@ -468,9 +502,11 @@ const prev = document.getElementById(previewId); prev.src = data.url; prev.style.display = 'block'; - document.getElementById(labelId).classList.add('has-image'); + lbl.classList.add('has-image'); } catch (e) { - showToast('⚠️ Kuvan lataus epäonnistui.'); + showToast('⚠️ Kuvan lataus epäonnistui. Tuetut muodot: JPG, PNG, GIF, WebP.'); + } finally { + lbl.style.opacity = ''; } } diff --git a/script.js b/script.js index e090bc3..0699293 100644 --- a/script.js +++ b/script.js @@ -389,11 +389,47 @@ function closeSubmitModal() { 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) { const file = input.files[0]; 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(); - formData.append('file', file); + formData.append('file', resized, resized.name || 'image.jpg'); try { const res = await fetch('upload.php', { method: 'POST', body: formData }); 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); prev.src = data.url; prev.style.display = 'block'; - document.getElementById(labelId).classList.add('has-image'); + lbl.classList.add('has-image'); } 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 = ''; } }