moodle-kachel-colorizer/script.js

136 lines
5.5 KiB
JavaScript

// 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();
});
});