// Kleiner Helfer für fleißige Moodle-Kurs-Ersteller:innen // Kachelbild hochladen --> unzählige Kacheln in verschiedenen Farben erhalten // einzeln oder als ZIP runterladen. // jesko@linuxmuster.net im Oktober 2024 // Lizenz: GPL3 // // Die Farben in der Context-Map, die englische Namen haben sind die standardfarben, die mit deutschen Namen sind die Farben aus dem Moodle-Kachelkursformat... Alles ist anpassbar. Have fun! const imageUpload = document.getElementById('imageUpload'); const downloadAllLink = document.getElementById('downloadAll'); let img = new Image(); let originalFileName = ''; let originalImageData = {}; // To store the original image data for each canvas const ctxMap = { "red": document.getElementById('canvas-red').getContext('2d'), "green": document.getElementById('canvas-green').getContext('2d'), "yellow": document.getElementById('canvas-yellow').getContext('2d'), "blue": document.getElementById('canvas-blue').getContext('2d'), "purple": document.getElementById('canvas-purple').getContext('2d'), "pink": document.getElementById('canvas-pink').getContext('2d'), "blau": document.getElementById('canvas-blau').getContext('2d'), "hellblau": document.getElementById('canvas-hellblau').getContext('2d'), "gruen": document.getElementById('canvas-gruen').getContext('2d'), "dunkelgruen": document.getElementById('canvas-dunkelgruen').getContext('2d'), "rot": document.getElementById('canvas-rot').getContext('2d'), "violett": document.getElementById('canvas-violett').getContext('2d'), }; // Bild hochladen und darstellen imageUpload.addEventListener('change', function(event) { const file = event.target.files[0]; originalFileName = file.name.split('.')[0]; // Originaldateinamen ohne Erweiterung speichern const reader = new FileReader(); reader.onload = function(e) { img.src = e.target.result; img.onload = function() { setCanvasDimensions(); // Setze die Größe der Canvas entsprechend der Bildgröße drawImageOnAll(); // Zeige das Bild auf allen Canvas an saveOriginalImageData(); // Speichere die Original-Image-Daten applyOverlayToAll(); // Wende direkt nach dem Hochladen die Overlays an }; }; reader.readAsDataURL(file); }); // Setze die Canvas-Größe auf die des hochgeladenen Bildes function setCanvasDimensions() { Object.values(ctxMap).forEach(ctx => { const canvas = ctx.canvas; canvas.width = img.width; canvas.height = img.height; }); } // Zeichne das Originalbild auf alle Canvas-Elemente function drawImageOnAll() { Object.values(ctxMap).forEach(ctx => ctx.drawImage(img, 0, 0)); } // Speichere das Originalbild auf jedem Canvas, um es später wiederherstellen zu können function saveOriginalImageData() { Object.entries(ctxMap).forEach(([colorName, ctx]) => { originalImageData[colorName] = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height); }); } // Stelle das Originalbild wieder her, bevor ein neues Overlay angewendet wird function restoreOriginalImage() { Object.entries(ctxMap).forEach(([colorName, ctx]) => { ctx.putImageData(originalImageData[colorName], 0, 0); // Originale Bilddaten zurücksetzen }); } // Wende das Overlay auf alle Canvas-Elemente an function applyOverlayToAll() { restoreOriginalImage(); // Stelle sicher, dass das Original wiederhergestellt wird // Führe die Overlays basierend auf den aktuellen Farben aus Object.entries(ctxMap).forEach(([colorName, ctx]) => { const color = document.getElementById(`color-${colorName}`).value; applyOverlay(ctx, color); }); // Zeige den Download-Link an downloadAllLink.style.display = 'block'; downloadAllLink.textContent = `Alle Bilder als ${originalFileName}-gefärbt.zip herunterladen`; } // Overlay-Funktion, die das Overlay auf ein Canvas-Element anwendet function applyOverlay(ctx, overlayColor) { const imageData = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height); const data = imageData.data; // Hex-Farbe in RGB umwandeln const rOverlay = parseInt(overlayColor.slice(1, 3), 16); const gOverlay = parseInt(overlayColor.slice(3, 5), 16); const bOverlay = parseInt(overlayColor.slice(5, 7), 16); // Überlagere die nicht-transparenten Pixel for (let i = 0; i < data.length; i += 4) { const alpha = data[i + 3]; if (alpha > 0) { data[i] = (data[i] + rOverlay) / 2; // Rot data[i + 1] = (data[i + 1] + gOverlay) / 2; // Grün data[i + 2] = (data[i + 2] + bOverlay) / 2; // Blau } } ctx.putImageData(imageData, 0, 0); } // ZIP-Download erstellen downloadAllLink.addEventListener('click', function() { const zip = new JSZip(); Object.entries(ctxMap).forEach(([colorName, ctx]) => { const colorCode = document.getElementById(`color-${colorName}`).value; const fileName = `${originalFileName}-${colorCode.slice(1)}.png`; // Name mit Farbcodes const dataUrl = ctx.canvas.toDataURL('image/png'); const imgData = dataUrl.split(',')[1]; zip.file(fileName, imgData, { base64: true }); }); // ZIP-Datei zum Download erstellen zip.generateAsync({ type: 'blob' }).then(function(content) { const link = document.createElement('a'); link.href = URL.createObjectURL(content); link.download = `${originalFileName}-gefärbt.zip`; // Name für ZIP-Datei link.click(); }); });