const workspace = document.getElementById('workspace'); const spawnBtns = document.querySelectorAll('.spawn-btn'); let elementsOnDesk = []; let draggingElement = null; let offsetX = 0; let offsetY = 0; // Rezepturenbuch (die Formeln müssen genau den Kombinationen der Symbole entsprechen) const recipes = [ { ingredients: ['H', 'H', 'O'], // 2x Wasserstoff, 1x Sauerstoff result: 'H₂O (Wasser)', color: '#3498db' }, { ingredients: ['Cl', 'Na'], // 1x Natrium, 1x Chlor result: 'NaCl (Kochsalz)', color: '#ecf0f1' }, { ingredients: ['O', 'O'], // 2x Sauerstoff result: 'O₂ (Sauerstoff-Molekül)', color: '#bdc3c7' }, { ingredients: ['C', 'O', 'O'], // 1x Kohlenstoff, 2x Sauerstoff result: 'CO₂ (Kohlendioxid)', color: '#7f8c8d' }, { ingredients: ['C', 'H', 'H', 'H', 'H'], // 1x Kohlenstoff, 4x Wasserstoff result: 'CH₄ (Methan)', color: '#f39c12' }, { ingredients: ['N', 'H', 'H', 'H'], // 1x Stickstoff, 3x Wasserstoff result: 'NH₃ (Ammoniak)', color: '#9b59b6' } ]; // Button-Klicks registrieren spawnBtns.forEach(btn => { btn.addEventListener('click', () => { spawnAtom(btn.dataset.element, btn.dataset.color); }); }); function spawnAtom(symbol, color) { const el = document.createElement('div'); el.classList.add('atom'); el.innerText = symbol; el.dataset.symbol = symbol; el.style.backgroundColor = color; // Zufällige Position auf dem Tisch const x = Math.random() * (workspace.clientWidth - 50); const y = Math.random() * (workspace.clientHeight - 50); el.style.left = x + 'px'; el.style.top = y + 'px'; makeDraggable(el); workspace.appendChild(el); elementsOnDesk.push(el); } function makeDraggable(el) { el.addEventListener('mousedown', (e) => { draggingElement = el; const rect = el.getBoundingClientRect(); offsetX = e.clientX - rect.left; offsetY = e.clientY - rect.top; el.style.zIndex = 1000; }); } document.addEventListener('mousemove', (e) => { if (draggingElement) { const workspaceRect = workspace.getBoundingClientRect(); let newX = e.clientX - workspaceRect.left - offsetX; let newY = e.clientY - workspaceRect.top - offsetY; // Grenzen beachten newX = Math.max(0, Math.min(newX, workspaceRect.width - draggingElement.offsetWidth)); newY = Math.max(0, Math.min(newY, workspaceRect.height - draggingElement.offsetHeight)); draggingElement.style.left = newX + 'px'; draggingElement.style.top = newY + 'px'; } }); document.addEventListener('mouseup', () => { if (draggingElement) { draggingElement.style.zIndex = ''; checkForReactions(); draggingElement = null; } }); function checkForReactions() { if (!draggingElement) return; const rect1 = draggingElement.getBoundingClientRect(); // Finde alle Elemente, die sich berühren (inklusive des gezogenen Elements) // Einfache Kollisionserkennung: Wir gruppieren alle Elemente, die nahe beieinander liegen. let cluster = [draggingElement]; let added = true; // Erweitere den Cluster iterativ, bis keine berührenden Elemente mehr gefunden werden while(added) { added = false; for (let el of elementsOnDesk) { if (cluster.includes(el)) continue; // Prüfe Kollision mit irgendeinem Element im Cluster let touches = cluster.some(cEl => { const r1 = cEl.getBoundingClientRect(); const r2 = el.getBoundingClientRect(); return !(r1.right < r2.left || r1.left > r2.right || r1.bottom < r2.top || r1.top > r2.bottom); }); if (touches) { cluster.push(el); added = true; } } } if (cluster.length > 1) { const symbols = cluster.map(el => el.dataset.symbol).sort(); // Prüfe gegen alle Rezepte for (const recipe of recipes) { const recipeSymbols = [...recipe.ingredients].sort(); if (JSON.stringify(symbols) === JSON.stringify(recipeSymbols)) { // REAKTION! const midX = draggingElement.style.left; const midY = draggingElement.style.top; // Lösche alte Atome cluster.forEach(el => { if (workspace.contains(el)) { workspace.removeChild(el); } elementsOnDesk = elementsOnDesk.filter(e => e !== el); }); // Neues Molekül erstellen createMolecule(recipe.result, recipe.color, midX, midY); break; } } } } function createMolecule(name, color, x, y) { const el = document.createElement('div'); el.classList.add('molecule'); el.innerText = name; el.dataset.symbol = name; // Für diesen Prototyp können Moleküle noch nicht weiterreagieren el.style.backgroundColor = color; el.style.left = x; el.style.top = y; makeDraggable(el); workspace.appendChild(el); elementsOnDesk.push(el); // Animation el.animate([ { transform: 'scale(0.5)' }, { transform: 'scale(1.2)' }, { transform: 'scale(1)' } ], { duration: 300 }); }