/** * Verkleinert große Fotos, bevor sie hochgeladen werden (Handy-Fotos haben oft 5–15 MB). * Das macht den Upload deutlich schneller. Ist etwas nicht möglich, wird die Originaldatei unverändert hochgeladen. * Gilt für alle auf der Seite; nur JPG/PNG über 1 MB, längste Seite höchstens 2400 px. */ (function () { var MAX_SIDE = 2400, MIN_BYTES = 1024 * 1024, QUALITY = 0.82; if (!window.DataTransfer || !window.HTMLCanvasElement || !window.URL) return; function note(input, text) { var el = input.parentNode && input.parentNode.querySelector('.upload-note'); if (!el) { el = document.createElement('div'); el.className = 'upload-note'; el.style.cssText = 'font-size:.8rem;color:#64748b;margin-top:4px'; input.insertAdjacentElement('afterend', el); } el.textContent = text; } function shrink(file) { return new Promise(function (resolve) { if (!/^image\/(jpeg|png)$/.test(file.type) || file.size < MIN_BYTES) return resolve(file); var url = URL.createObjectURL(file), img = new Image(); img.onerror = function () { URL.revokeObjectURL(url); resolve(file); }; img.onload = function () { URL.revokeObjectURL(url); var w = img.naturalWidth, h = img.naturalHeight, k = Math.min(1, MAX_SIDE / Math.max(w, h)); var c = document.createElement('canvas'); c.width = Math.round(w * k); c.height = Math.round(h * k); var ctx = c.getContext('2d'); if (!ctx) return resolve(file); ctx.fillStyle = '#fff'; ctx.fillRect(0, 0, c.width, c.height); ctx.drawImage(img, 0, 0, c.width, c.height); c.toBlob(function (blob) { if (!blob || blob.size >= file.size) return resolve(file); var name = file.name.replace(/\.(png|jpe?g)$/i, '') + '.jpg'; resolve(new File([blob], name, { type: 'image/jpeg', lastModified: file.lastModified })); }, 'image/jpeg', QUALITY); }; img.src = url; }); } document.addEventListener('change', function (e) { var input = e.target; if (!input || input.type !== 'file' || input.dataset.shrunk === '1' || !input.files || !input.files.length) return; var files = Array.prototype.slice.call(input.files); if (!files.some(function (f) { return /^image\/(jpeg|png)$/.test(f.type) && f.size >= MIN_BYTES; })) return; note(input, 'Bilder werden für einen schnelleren Upload verkleinert …'); Promise.all(files.map(shrink)).then(function (out) { try { var dt = new DataTransfer(); out.forEach(function (f) { dt.items.add(f); }); input.dataset.shrunk = '1'; input.files = dt.files; input.dispatchEvent(new Event('change', { bubbles: true })); input.dataset.shrunk = ''; var before = files.reduce(function (s, f) { return s + f.size; }, 0), after = out.reduce(function (s, f) { return s + f.size; }, 0); note(input, after < before ? 'Bilder verkleinert: ' + (before / 1048576).toFixed(1) + ' MB → ' + (after / 1048576).toFixed(1) + ' MB' : ''); } catch (err) { note(input, ''); } }); }, true); // Beim Absenden: Knopf sperren, damit nicht doppelt hochgeladen wird, und Fortschritt anzeigen document.addEventListener('submit', function (e) { var form = e.target; if (!form || !form.querySelector || !form.querySelector('input[type=file]')) return; var has = Array.prototype.some.call(form.querySelectorAll('input[type=file]'), function (i) { return i.files && i.files.length; }); if (!has) return; setTimeout(function () { if (e.defaultPrevented) return; var b = form.querySelector('button[type=submit]'); if (b) { b.disabled = true; b.textContent = 'Wird hochgeladen …'; } }, 0); }); })();