2024-10-23 19:14:08 +02:00
// 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
2024-10-23 19:44:43 +02:00
// Lizenz: MIT oder GPLv3
2024-10-23 19:14:08 +02:00
//
2024-10-23 19:44:43 +02:00
// Das Skript nutzt JSZip von Stuart Knightley, um die Bilder beim Download in eine Zip-Datei zu packen. <http://stuartk.com/jszip>
//
//
2024-10-23 19:14:08 +02:00
// 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
2024-10-23 19:44:43 +02:00
displayImageDimensions ( img . width , img . height ) ; // zeige die Bildmaße an
2024-10-23 19:14:08 +02:00
} ;
} ;
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 ;
} ) ;
}
2024-10-23 19:44:43 +02:00
function displayImageDimensions ( width , height ) {
const dimensionsDiv = document . getElementById ( 'imageDimensions' ) ;
dimensionsDiv . innerHTML = ` Bildmaße: ${ width } px (B) x ${ height } px (H) ` ; // Zeige die Maße an
}
2024-10-23 19:14:08 +02:00
// 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' ;
2024-10-23 19:44:43 +02:00
downloadAllLink . textContent = ` alle Bilder als ZIP-Datei herunterladen ( ${ originalFileName } -gefärbt.zip) ` ;
2024-10-23 19:14:08 +02:00
}
// 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 ( ) ;
} ) ;
} ) ;