/** * Glossar-Experimente — kleine interaktive Widgets im Detail-Modal. * * Registrierung: window.GlossarExperiments[key_slug] = function (root) { … } * Der Renderer (glossar.php) hängt einen leeren Container ein und ruft die * Funktion mit diesem Container als einzigem Argument auf. Das Widget baut * selbst seinen DOM und bindet seine Events. * * Richtlinien: * - Keine externen Libraries. * - Mobile-/Tap-freundlich: grosse Buttons, keine Hover-Abhängigkeit. * - Zahlen quellenbar, kurze Begründung in der UI sichtbar. */ (function () { 'use strict'; const NS = 'http://www.w3.org/2000/svg'; const svgEl = (tag, attrs, parent) => { const el = document.createElementNS(NS, tag); if (attrs) for (const k in attrs) el.setAttribute(k, attrs[k]); if (parent) parent.appendChild(el); return el; }; // ===================================================================== // Experiment: kWh-Rennen — wie weit kommt man mit 1 Kilowattstunde? // ===================================================================== function kwhRace(root) { root.innerHTML = `

🏁 Das kWh-Rennen

Drei Fahrzeuge starten rechts mit derselben Energie: 1 Kilowattstunde. Wie weit kommen sie nach links?

Quellen: ADAC Stromverbrauchstests E-Auto · Hersteller-Angaben E-Bike Bosch Performance · WLTP Benziner 6 L/100 km × 8,8 kWh/L. Der Benziner verliert rund 70 % der Kraftstoffenergie als Motor-Wärme — deshalb kommt er weniger weit.

`; const svg = root.querySelector('.ge-track'); // Emoji-Fahrzeuge: auf Windows/Chrome schauen 🚴 🚗 🚙 nach links → sie fahren // von rechts nach links, Emojis passen zur Fahrtrichtung ohne Plattform-Trick. const vehicles = [ { label: 'E-Fahrrad', emoji: '🚴', km: 100, color: '#5a8a5e', y: 100 }, { label: 'E-Auto', emoji: '🚗', km: 6.5, color: '#4a7c8a', y: 190 }, { label: 'Benzin-Auto', emoji: '🚙', km: 1.9, color: '#c85c4a', y: 280 } ]; const MAX_KM = 100; const TRACK_L = 50, TRACK_R = 560; const trackLen = TRACK_R - TRACK_L; // Skala oben — Start rechts (0 km), Ziel links (100 km) const axis = svgEl('g', { class: 'ge-axis' }, svg); svgEl('line', { x1: TRACK_L, y1: 52, x2: TRACK_R, y2: 52, stroke: '#1f4e5a', 'stroke-width': '1.2' }, axis); [0, 25, 50, 75, 100].forEach(km => { const x = TRACK_R - (km / MAX_KM) * trackLen; svgEl('line', { x1: x, y1: 48, x2: x, y2: 56, stroke: '#1f4e5a', 'stroke-width': '1' }, axis); const t = svgEl('text', { x, y: 40, 'text-anchor': 'middle', 'font-size': '11', fill: '#4a4a4a', 'font-weight': '600' }, axis); t.textContent = km + ' km'; }); // „Start" Marker ganz rechts const startTxt = svgEl('text', { x: TRACK_R, y: 20, 'text-anchor': 'end', 'font-size': '11', fill: '#1f4e5a', 'font-weight': '700' }, svg); startTxt.textContent = '← Start mit 1 kWh'; // Spuren + Fahrzeuge const nodes = vehicles.map(v => { const g = svgEl('g', { class: 'ge-lane' }, svg); // Label ÜBER der Spur, rechts beim Start const label = svgEl('text', { x: TRACK_R, y: v.y - 22, 'text-anchor': 'end', 'font-size': '12', 'font-weight': '800', fill: v.color }, g); label.textContent = v.label; // Straßenlinie svgEl('line', { x1: TRACK_L, y1: v.y, x2: TRACK_R, y2: v.y, stroke: '#dae8ec', 'stroke-width': '5', 'stroke-linecap': 'round' }, g); // Ziel-Markierung (links vom Start) const xEnd = TRACK_R - (v.km / MAX_KM) * trackLen; svgEl('line', { x1: xEnd, y1: v.y - 16, x2: xEnd, y2: v.y + 16, stroke: v.color, 'stroke-width': '2', 'stroke-dasharray': '3 2', opacity: '.55' }, g); // Emoji-Fahrzeug const icon = svgEl('text', { x: TRACK_R, y: v.y + 8, 'text-anchor': 'middle', 'font-size': '30' }, g); icon.textContent = v.emoji; // Ergebnis-Label LINKS vom Ziel (in Fahrtrichtung weiter) const result = svgEl('text', { x: xEnd - 10, y: v.y + 4, 'text-anchor': 'end', 'font-size': '12', 'font-weight': '800', fill: v.color, opacity: '0' }, g); result.textContent = v.km.toFixed(1).replace('.', ',') + ' km'; return { v, icon, result, xStart: TRACK_R, xEnd }; }); // Animation let animId = null; function setX(n, x) { n.icon.setAttribute('x', x); } function animate() { cancelAnimationFrame(animId); const dur = 6500; // ms — bewusst langsam const start = performance.now(); nodes.forEach(n => { setX(n, n.xStart); n.result.setAttribute('opacity', '0'); }); function tick(now) { const t = Math.min(1, (now - start) / dur); const e = 1 - Math.pow(1 - t, 3); nodes.forEach(n => { const x = n.xStart + (n.xEnd - n.xStart) * e; setX(n, x); if (t > 0.96) n.result.setAttribute('opacity', '1'); }); if (t < 1) animId = requestAnimationFrame(tick); } animId = requestAnimationFrame(tick); } function reset() { cancelAnimationFrame(animId); nodes.forEach(n => { setX(n, n.xStart); n.result.setAttribute('opacity', '0'); }); } root.querySelector('[data-act="start"]').addEventListener('click', animate); root.querySelector('[data-act="reset"]').addEventListener('click', reset); } // ===================================================================== // Experiment: ppm-Raster — 1 Teilchen von 1.000.000 findet man kaum // ===================================================================== function ppmGrid(root) { root.innerHTML = `

🔍 Finde das eine Teilchen

Unten siehst du ein Gitter mit 10.000 Punkten. Ein einziger Punkt ist rot — das entspräche 100 ppm (echte 1 ppm wäre nochmal 100× feiner). Versuche, ihn zu finden und zu tippen!

Bei der aktuellen CO₂-Konzentration von 422 ppm sind 422 von 1.000.000 Luftteilchen CO₂. Das klingt winzig — reicht aber, um die Erde messbar zu erwärmen. Quelle: NOAA Mauna Loa (2024).

`; const grid = root.querySelector('#ge-ppm'); const msg = root.querySelector('.ge-ppm-msg'); const COLS = 100, ROWS = 100; let special = Math.floor(Math.random() * COLS * ROWS); let found = false; function render() { grid.innerHTML = ''; grid.style.gridTemplateColumns = `repeat(${COLS}, 1fr)`; for (let i = 0; i < COLS * ROWS; i++) { const cell = document.createElement('span'); if (i === special) cell.className = 'ge-ppm-special'; grid.appendChild(cell); } msg.textContent = ''; msg.classList.remove('show', 'miss'); found = false; } function highlight() { const el = grid.children[special]; if (!el) return; el.classList.add('ge-ppm-flash'); setTimeout(() => el.classList.remove('ge-ppm-flash'), 1800); } function newOne() { special = Math.floor(Math.random() * COLS * ROWS); render(); } function onHit(cell) { if (found) return; found = true; cell.classList.add('ge-ppm-hit'); msg.textContent = '🎉 Getroffen! Das war 1 von 10.000 Punkten.'; msg.classList.remove('miss'); msg.classList.add('show'); } function onMiss() { if (found) return; msg.textContent = 'Daneben — probier "Tipp zeigen" für eine kurze Hilfe.'; msg.classList.remove('show'); msg.classList.add('show', 'miss'); } // Click-Handler delegiert auf das Grid (funktioniert auch bei 4-px-Zellen) grid.addEventListener('click', ev => { const target = ev.target; if (target === grid) return; if (target.classList && target.classList.contains('ge-ppm-special')) onHit(target); else onMiss(); }); render(); root.querySelector('[data-act="highlight"]').addEventListener('click', highlight); root.querySelector('[data-act="new"]').addEventListener('click', newOne); } // ===================================================================== // Experiment: Albedo-Slider — Oberfläche wechseln, Reflexion beobachten // ===================================================================== function albedoSlider(root) { const surfaces = [ { key: 'snow', label: 'Frischer Schnee', albedo: 0.85, color: '#ffffff', border: '#b5c9cf' }, { key: 'desert', label: 'Sand-Wüste', albedo: 0.35, color: '#e8d5b5', border: '#c4a97a' }, { key: 'forest', label: 'Wald', albedo: 0.12, color: '#3a6b3e', border: '#2a5030' }, { key: 'ocean', label: 'Ozean', albedo: 0.06, color: '#1f4e5a', border: '#0f2f3a' }, { key: 'asphalt', label: 'Asphalt', albedo: 0.05, color: '#2a2a2a', border: '#1a1a1a' } ]; root.innerHTML = `

☀ Welche Oberfläche reflektiert wie viel?

Wähle eine Oberfläche. Die Pfeile zeigen, wie viel Sonnenlicht zurückgeworfen wird.

${surfaces.map((s, i) => ` `).join('')}
Albedo: 0,85
Reflektiert: 85 %
Absorbiert: 15 %

Darum erwärmt sich die Arktis 4-mal schneller als die Erde insgesamt: Schmilzt Eis, kommt darunter dunkler Ozean zum Vorschein, der viel mehr Sonnenenergie aufnimmt. Quelle: Rantanen et al. 2022.

`; const svg = root.querySelector('.ge-albedo-svg'); const valEl = root.querySelector('#ge-alb-val'); const reflEl = root.querySelector('#ge-alb-refl'); const absEl = root.querySelector('#ge-alb-abs'); // Statischer Aufbau: Himmel + Sonne + Bodenrechteck svgEl('rect', { x: 0, y: 0, width: 600, height: 210, fill: '#eff5f6' }, svg); svgEl('circle', { cx: 90, cy: 70, r: 30, fill: '#f4c94e' }, svg); const surfaceRect = svgEl('rect', { x: 0, y: 210, width: 600, height: 110, fill: '#ffffff', stroke: '#b5c9cf', 'stroke-width': '1.5' }, svg); // Einfallender Lichtstrahl (Sonne → Boden) svgEl('line', { x1: 110, y1: 100, x2: 300, y2: 210, stroke: '#e8833a', 'stroke-width': '3', 'stroke-linecap': 'round' }, svg); svgEl('polygon', { points: '295,205 306,208 300,215', fill: '#e8833a' }, svg); // Reflexions-Pfeile (dynamisch nach Albedo) const reflG = svgEl('g', { class: 'ge-albedo-refl' }, svg); function setSurface(key) { const s = surfaces.find(x => x.key === key) || surfaces[0]; surfaceRect.setAttribute('fill', s.color); surfaceRect.setAttribute('stroke', s.border); // Anzahl reflektierter Pfeile proportional zur Albedo (1 bis 9 Pfeile) reflG.innerHTML = ''; const nArrows = Math.max(1, Math.round(s.albedo * 10)); for (let i = 0; i < nArrows; i++) { const angle = -60 + i * (120 / Math.max(1, nArrows - 1)); const rad = angle * Math.PI / 180; const startX = 300, startY = 210; const len = 120; const endX = startX + Math.cos(rad) * len; const endY = startY - Math.sin(Math.abs(rad) * Math.PI / 180 + 0.3) * Math.abs(len * Math.cos(rad) / 90) - 60; // Simpler: Linien gleichmäßig nach oben gefächert const e2x = 300 + Math.sin(rad) * len; const e2y = 210 - Math.cos(rad) * len; svgEl('line', { x1: startX, y1: startY, x2: e2x, y2: e2y, stroke: '#f4c94e', 'stroke-width': '2', 'stroke-linecap': 'round', opacity: '0.85' }, reflG); } valEl.textContent = s.albedo.toFixed(2).replace('.', ','); reflEl.textContent = Math.round(s.albedo * 100) + ' %'; absEl.textContent = Math.round((1 - s.albedo) * 100) + ' %'; root.querySelectorAll('.ge-albedo-choice .ge-btn').forEach(b => { b.classList.toggle('ge-btn-primary', b.dataset.key === s.key); }); } root.querySelectorAll('.ge-albedo-choice .ge-btn').forEach(b => { b.addEventListener('click', () => setSurface(b.dataset.key)); }); setSurface('snow'); } // ===================================================================== // Experiment: CO₂-Fußabdruck-Rechner — schneller Alltags-Schätzer // ===================================================================== function footprintCalc(root) { root.innerHTML = `

🧮 Schätze deinen CO₂-Fußabdruck

Einfache Auswahl pro Bereich. Das Ergebnis ist eine Richtgröße — kein genauer Wert.

🏠 Wohnen
🚗 Verkehr
🍽 Ernährung
🛒 Konsum
Dein geschätzter Fußabdruck:
7,6 t CO₂ / Jahr
0 tWelt-Ø 4,7AT-Ø 7,710 t
Klimaneutral-Ziel: unter 1 t — Welt-Durchschnitt: 4,7 t — Österreich: 7,7 t.

Die Anteile decken sich mit den Haupt-Kategorien im Klimaschutzbericht 2024 des Umweltbundesamts Österreich. Details pro Kategorie unter CO₂-Fußabdruck.

`; const totals = { home: 2.0, car: 1.8, food: 1.8, shop: 2.0 }; function update() { const sum = Object.values(totals).reduce((a, b) => a + b, 0); root.querySelector('.ge-calc-total').textContent = sum.toFixed(1).replace('.', ',') + ' t CO₂ / Jahr'; const pct = Math.min(100, (sum / 10) * 100); root.querySelector('.ge-calc-fill').style.width = pct + '%'; } root.querySelectorAll('.ge-calc-opts').forEach(group => { const key = group.dataset.key; group.querySelectorAll('.ge-btn').forEach(btn => { btn.addEventListener('click', () => { group.querySelectorAll('.ge-btn').forEach(b => b.classList.remove('ge-btn-primary')); btn.classList.add('ge-btn-primary'); totals[key] = parseFloat(btn.dataset.val); update(); }); }); }); update(); } // ===================================================================== // Experiment: Treibhauseffekt-Slider — CO₂-ppm → globale Erwärmung // ===================================================================== function greenhouseSlider(root) { root.innerHTML = `

🌡 Wie viel CO₂ verträgt das Klima?

Schiebe den Regler und beobachte, wie sich die Atmosphäre füllt und die Erde wärmer wird.

200280
1750
420
heute
560
Verdopplung
800
Temperaturanstieg gegenüber 1850: +1,2 °C
nahe heutiger Wert

Vereinfachte Faustformel: ΔT = 3 °C × log₂(CO₂ / 280 ppm). Das bildet die IPCC-Klimasensitivität (rund 3 °C pro Verdopplung) grob ab. Quellen: IPCC AR6 WG1 Kap. 7 · NOAA Mauna Loa.

`; const svg = root.querySelector('.ge-gh-svg'); const rng = root.querySelector('#ge-gh-range'); const ppmOut = root.querySelector('#ge-gh-ppm'); const dtOut = root.querySelector('#ge-gh-dt'); const verdict = root.querySelector('#ge-gh-verdict'); // Statisches Szenen-Layout // Sonne svgEl('circle', { cx: 90, cy: 55, r: 28, fill: '#f4c94e' }, svg); svgEl('text', { x: 90, y: 62, 'text-anchor': 'middle', 'font-size': '22' }, svg).textContent = '☀'; // Atmosphäre (gradient wird per Opacity per Zustand gesteuert) const sky = svgEl('rect', { x: 0, y: 30, width: 600, height: 190, fill: '#4a7c8a', opacity: '0.15' }, svg); // Erdoberfläche const earth = svgEl('rect', { x: 0, y: 220, width: 600, height: 80, fill: '#5a8a5e' }, svg); // Baum und Haus dekorativ svgEl('polygon', { points: '100,220 115,195 130,220', fill: '#3a6b3e' }, svg); svgEl('rect', { x: 112, y: 220, width: 6, height: 10, fill: '#6b4a2e' }, svg); svgEl('rect', { x: 470, y: 198, width: 36, height: 22, fill: '#e8d5b5', stroke: '#1f4e5a', 'stroke-width': '1' }, svg); svgEl('polygon', { points: '468,199 488,182 508,199', fill: '#c85c4a' }, svg); // Container für dynamische Moleküle const molGroup = svgEl('g', { class: 'ge-gh-mols' }, svg); // Temperatur-Anzeige rechts oben const thermo = svgEl('g', { transform: 'translate(540, 40)' }, svg); svgEl('rect', { x: -10, y: 0, width: 20, height: 140, fill: '#fff', stroke: '#1f4e5a', rx: '10' }, thermo); const mercury = svgEl('rect', { x: -6, y: 130, width: 12, height: 0, fill: '#c85c4a', rx: '6' }, thermo); svgEl('circle', { cx: 0, cy: 148, r: 10, fill: '#c85c4a' }, thermo); function update() { const ppm = +rng.value; ppmOut.textContent = ppm; // ΔT gegen 1850 (≈ 280 ppm als Referenz) const dt = 3 * Math.log2(ppm / 280); const dtRounded = Math.round(dt * 10) / 10; dtOut.textContent = (dtRounded >= 0 ? '+' : '') + dtRounded.toFixed(1).replace('.', ',') + ' °C'; // Sky-Farbton rotläuft je höher der CO₂-Wert (rotes Leuchten) const warmth = Math.min(1, Math.max(0, (ppm - 280) / 520)); const redAmount = Math.round(40 + warmth * 140); sky.setAttribute('fill', `rgb(${40 + redAmount}, ${140 - warmth * 50}, ${170 - warmth * 80})`); sky.setAttribute('opacity', (0.15 + warmth * 0.35).toFixed(2)); earth.setAttribute('fill', warmth > 0.6 ? '#c4a97a' : (warmth > 0.3 ? '#9bab74' : '#5a8a5e')); // Moleküle proportional zu ppm molGroup.innerHTML = ''; const nMols = Math.round((ppm - 200) / 8); // 0..75 Moleküle for (let i = 0; i < nMols; i++) { const mx = 40 + Math.random() * 520; const my = 50 + Math.random() * 155; const isMethane = Math.random() < 0.12; svgEl('circle', { cx: mx, cy: my, r: 5, fill: isMethane ? '#e8833a' : '#c85c4a', opacity: '0.7' }, molGroup); } // Mercury-Säule (0 °C = y=130, max +5°C bei y=10 → 120 px / 5°C = 24 px/°C) const mh = Math.max(0, Math.min(120, dt * 24)); mercury.setAttribute('y', 130 - mh); mercury.setAttribute('height', mh); // Verdict-Text let v, cls; if (ppm < 300) { v = '🟢 Vorindustrielles Klima'; cls = 'good'; } else if (ppm < 450) { v = '🟡 nahe heutiger Wert'; cls = 'now'; } else if (ppm < 600) { v = '🟠 Verdopplung — kritisch'; cls = 'warn'; } else { v = '🔴 weit jenseits 2 °C-Ziel'; cls = 'bad'; } verdict.textContent = v; verdict.dataset.state = cls; } rng.addEventListener('input', update); update(); } // ===================================================================== // Experiment: Methan-GWP-Waage — 1 kg Methan gegen wie viel CO₂? // ===================================================================== function methaneBalance(root) { root.innerHTML = `

⚖ Wie stark ist 1 kg Methan?

Auf der linken Waagschale liegt 1 kg Methan. Lege so viele kg CO₂ auf die rechte Schale, bis die Waage im Gleichgewicht ist (auf 100 Jahre).

noch zu leicht

Laut IPCC AR6 (2021) hat 1 kg Methan auf 100 Jahre die Klimawirkung von 28 kg CO₂ (GWP-100). Auf 20 Jahre sogar 82 kg.

`; const svg = root.querySelector('.ge-bal-svg'); const rng = root.querySelector('#ge-bal-range'); const kgOut = root.querySelector('#ge-bal-kg'); const verdict = root.querySelector('#ge-bal-verdict'); // Grundaufbau: Ständer + Balken svgEl('rect', { x: 296, y: 200, width: 8, height: 120, fill: '#6b4a2e' }, svg); svgEl('rect', { x: 260, y: 316, width: 80, height: 10, fill: '#6b4a2e', rx: '3' }, svg); svgEl('circle', { cx: 300, cy: 200, r: 6, fill: '#1f4e5a' }, svg); // Balken (rotiert um 300,200) const beam = svgEl('g', { transform: 'rotate(0, 300, 200)' }, svg); svgEl('rect', { x: 100, y: 196, width: 400, height: 8, fill: '#4a4a4a', rx: '4' }, beam); // Aufhängungen svgEl('line', { x1: 120, y1: 200, x2: 120, y2: 150, stroke: '#4a4a4a', 'stroke-width': '1.2' }, beam); svgEl('line', { x1: 480, y1: 200, x2: 480, y2: 150, stroke: '#4a4a4a', 'stroke-width': '1.2' }, beam); // Schalen svgEl('ellipse', { cx: 120, cy: 152, rx: 45, ry: 8, fill: '#c4a97a', stroke: '#1f4e5a', 'stroke-width': '1' }, beam); svgEl('path', { d: 'M 75 152 L 85 170 L 155 170 L 165 152 Z', fill: '#c4a97a', stroke: '#1f4e5a', 'stroke-width': '1' }, beam); svgEl('ellipse', { cx: 480, cy: 152, rx: 45, ry: 8, fill: '#c4a97a', stroke: '#1f4e5a', 'stroke-width': '1' }, beam); svgEl('path', { d: 'M 435 152 L 445 170 L 515 170 L 525 152 Z', fill: '#c4a97a', stroke: '#1f4e5a', 'stroke-width': '1' }, beam); // Links: 1 Methan-Molekül (dick und orange) const methaneG = svgEl('g', {}, beam); svgEl('circle', { cx: 120, cy: 140, r: 14, fill: '#e8833a', stroke: '#1f4e5a', 'stroke-width': '1' }, methaneG); const methaneLabel = svgEl('text', { x: 120, y: 144, 'text-anchor': 'middle', 'font-size': '11', 'font-weight': '800', fill: '#fff' }, methaneG); methaneLabel.textContent = 'CH₄'; const methaneCount = svgEl('text', { x: 120, y: 125, 'text-anchor': 'middle', 'font-size': '10', 'font-weight': '700', fill: '#1f4e5a' }, methaneG); methaneCount.textContent = '1 kg'; // Rechts: variable CO₂-Moleküle const co2G = svgEl('g', {}, beam); const co2Count = svgEl('text', { x: 480, y: 125, 'text-anchor': 'middle', 'font-size': '10', 'font-weight': '700', fill: '#1f4e5a' }, beam); function update() { const kg = +rng.value; kgOut.textContent = kg; co2Count.textContent = kg + ' kg'; // CO₂-Moleküle auf rechte Schale (gestapelt, maximal 60) co2G.innerHTML = ''; const perRow = 8; const cols = Math.min(perRow, kg); const rows = Math.ceil(kg / perRow); for (let i = 0; i < Math.min(kg, 60); i++) { const r = Math.floor(i / perRow); const c = i % perRow; const cx = 480 - ((cols - 1) * 9) / 2 + c * 9; const cy = 145 - r * 9; svgEl('circle', { cx, cy, r: 4, fill: '#c85c4a', opacity: '0.95' }, co2G); } // Balken-Rotation: Methan ist immer gleich "schwer" wie 28 kg CO₂ // Diff in kg-Äquivalent; Max-Rotation ±18° const diff = kg - 28; const angle = Math.max(-18, Math.min(18, diff * 0.8)); beam.setAttribute('transform', `rotate(${angle}, 300, 200)`); // Verdict if (kg < 20) verdict.textContent = '⬇ noch zu leicht'; else if (kg < 27) verdict.textContent = '🟡 fast — mehr CO₂ drauf'; else if (kg <= 29) verdict.textContent = '🎯 genau! 1 kg Methan ≈ 28 kg CO₂'; else verdict.textContent = '⬆ jetzt zu viel CO₂'; verdict.dataset.state = (kg >= 27 && kg <= 29) ? 'good' : 'now'; } rng.addEventListener('input', update); update(); } // Registry — Key entspricht key_slug aus DB window.GlossarExperiments = { 'kilowattstunde': kwhRace, 'ppm': ppmGrid, 'albedo': albedoSlider, 'co2-fussabdruck': footprintCalc, 'treibhauseffekt': greenhouseSlider, 'methan': methaneBalance // 'windenergie' bewusst raus — redundant mit windrad-groessenvergleich.svg }; })();