/** * Glossar-Experimente — Gruppe „geowelt". * * Kleine interaktive SVG-Widgets für das Detail-Modal eines Glossar-Eintrags * (Abschnitt „Selbst ausprobieren"). Registrierung am Ende der Datei via * window.GlossarExperiments[key_slug] = fn. * * Richtlinien: Vanilla JS, keine Libraries, nur bestehende .ge-*-CSS-Klassen. * Grosse Tap-Ziele, keine Hover-Abhängigkeit. rAF-Schleifen stoppen, sobald das * Modal geschlossen ist (root.isConnected-Guard). Zahlen quellenbar (ge-note). */ (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; }; const fmtInt = n => Math.round(n).toLocaleString('de-AT'); const fmtDec = (n, d) => n.toLocaleString('de-AT', { minimumFractionDigits: d, maximumFractionDigits: d }); // ===================================================================== // gletscher — Zeit-Schieberegler 1900 → heute, Gletscher zieht sich zurück // ===================================================================== function gletscher(root) { root.innerHTML = `

🏔 Wie ein Alpengletscher schrumpft

Schiebe durch die Jahre. Beobachte, wie sich die Gletscherzunge das Tal hinaufzieht und der Eis-Vorrat sinkt.

190019502000heute
Eis-Vorrat (1900 = 100 %): 100 %
noch fast unberührt

Werte veranschaulichen den Volumen-Rückgang der Alpengletscher seit 1900. Allein zwischen 2022 und 2023 verloren die Schweizer Gletscher rund 10 % ihres Volumens. Quelle: GLAMOS (Gletschermessnetz Schweiz).

`; const svg = root.querySelector('.ge-gh-svg'); const rng = root.querySelector('#ge-gl-range'); const yearOut = root.querySelector('#ge-gl-year'); const volOut = root.querySelector('[data-ref="vol"]'); const verdict = root.querySelector('[data-ref="verdict"]'); if (!svg || !rng) return; // Statische Szene: Himmel, Berge, Tal svgEl('rect', { x: 0, y: 0, width: 600, height: 300, fill: '#eaf2f6' }, svg); svgEl('polygon', { points: '0,300 130,70 260,300', fill: '#b9c3c9' }, svg); svgEl('polygon', { points: '180,300 320,50 470,300', fill: '#a7b3ba' }, svg); svgEl('polygon', { points: '380,300 520,90 600,300', fill: '#b9c3c9' }, svg); // Schneekappen svgEl('polygon', { points: '130,70 108,105 152,105', fill: '#ffffff' }, svg); svgEl('polygon', { points: '320,50 292,95 348,95', fill: '#ffffff' }, svg); // Talboden (grün) svgEl('rect', { x: 0, y: 250, width: 600, height: 50, fill: '#6f9c5f' }, svg); // Gletscher als dicke Linie von der Quelle (oben) zur wandernden Zunge (unten) const SRC = { x: 300, y: 78 }, TIP = { x: 300, y: 258 }; const glacierShade = svgEl('line', { x1: SRC.x, y1: SRC.y, x2: TIP.x, y2: TIP.y, stroke: '#9cc4e4', 'stroke-width': '34', 'stroke-linecap': 'round' }, svg); const glacier = svgEl('line', { x1: SRC.x, y1: SRC.y, x2: TIP.x, y2: TIP.y, stroke: '#e2eef7', 'stroke-width': '24', 'stroke-linecap': 'round' }, svg); const tipLabel = svgEl('text', { x: 300, y: 250, 'text-anchor': 'middle', 'font-size': '11', 'font-weight': '800', fill: '#1f4e5a' }, svg); tipLabel.textContent = 'Zunge'; // Volumen-Balken rechts svgEl('rect', { x: 552, y: 60, width: 26, height: 200, fill: '#ffffff', stroke: '#1f4e5a', 'stroke-width': '1.4', rx: '6' }, svg); const volBar = svgEl('rect', { x: 555, y: 63, width: 20, height: 194, fill: '#4a9cc4', rx: '5' }, svg); svgEl('text', { x: 565, y: 52, 'text-anchor': 'middle', 'font-size': '10', 'font-weight': '700', fill: '#1f4e5a' }, svg).textContent = 'Eis'; const anchors = [[1900, 100], [1950, 88], [1980, 78], [2000, 70], [2010, 60], [2020, 48], [2022, 44], [2023, 40]]; function volAt(y) { if (y <= anchors[0][0]) return anchors[0][1]; for (let i = 0; i < anchors.length - 1; i++) { const [y0, v0] = anchors[i], [y1, v1] = anchors[i + 1]; if (y <= y1) { const t = (y - y0) / (y1 - y0); return v0 + (v1 - v0) * t; } } return anchors[anchors.length - 1][1]; } function update() { const year = +rng.value; const vol = volAt(year); yearOut.textContent = year; volOut.textContent = Math.round(vol) + ' %'; // Zunge wandert nach oben, je weniger Eis const frac = vol / 100; const tipY = SRC.y + (TIP.y - SRC.y) * frac; glacier.setAttribute('y2', tipY); glacierShade.setAttribute('y2', tipY); tipLabel.setAttribute('y', Math.min(255, tipY + 22)); // Balken const full = 194; const h = full * frac; volBar.setAttribute('y', 63 + (full - h)); volBar.setAttribute('height', h); let txt, state; if (vol >= 85) { txt = 'noch fast unberührt'; state = 'good'; } else if (vol >= 65) { txt = 'Eis geht spürbar zurück'; state = 'now'; } else if (vol >= 45) { txt = 'Zunge zieht sich stark zurück'; state = 'warn'; } else { txt = 'rasanter Rückgang — allein 2022 – 2023 rund −10 %'; state = 'bad'; } verdict.textContent = txt; verdict.dataset.state = state; } rng.addEventListener('input', update); update(); } // ===================================================================== // lawinenwarnstufe — Regler Stufe 1 – 5, Gefahr steigt sprunghaft // ===================================================================== function lawinenwarnstufe(root) { root.innerHTML = `

🏔 Die Lawinen-Warnstufen

Stelle die Warnstufe ein. Achte darauf: Die Gefahr steigt nicht gleichmäßig — der Sprung von Stufe 3 auf 4 ist besonders groß.

12345
Gefahr: gering

Fünfstufige Europäische Lawinen-Gefahrenskala (EAWS). Die Skala ist nicht linear: Jede Stufe steht ungefähr für eine Verdopplung der Gefahr, der Schritt von 3 (erheblich) auf 4 (groß) ist besonders deutlich. Quelle: European Avalanche Warning Services.

`; const svg = root.querySelector('.ge-gh-svg'); const rng = root.querySelector('#ge-lw-range'); const numOut = root.querySelector('#ge-lw-num'); const nameOut = root.querySelector('#ge-lw-name'); const riskOut = root.querySelector('[data-ref="risk"]'); const info = root.querySelector('[data-ref="info"]'); if (!svg || !rng) return; const levels = { 1: { name: 'gering', risk: 8, state: 'good', txt: 'Meist sichere Verhältnisse. Auslösen nur bei sehr großer Belastung an wenigen Steilstellen.' }, 2: { name: 'mäßig', risk: 20, state: 'now', txt: 'An einzelnen steilen Hängen möglich. Sorgfältige Routenwahl nötig.' }, 3: { name: 'erheblich', risk: 45, state: 'warn', txt: 'An vielen Steilhängen möglich — oft reicht schon eine Person. Die meisten Unfälle passieren bei Stufe 3.' }, 4: { name: 'groß', risk: 80, state: 'bad', txt: 'An den meisten Steilhängen wahrscheinlich, auch von selbst. Sehr gefährlich — Touren nur mit viel Erfahrung.' }, 5: { name: 'sehr groß', risk: 100, state: 'bad', txt: 'Zahlreiche große, auch spontane Lawinen bis ins flache Gelände. Extrem — Touren tabu.' } }; // Statische Szene: Himmel + Hang svgEl('rect', { x: 0, y: 0, width: 600, height: 300, fill: '#eaf2f6' }, svg); // Hang als weißes Schnee-Dreieck svgEl('polygon', { points: '0,300 0,120 600,260 600,300', fill: '#f4f8fb', stroke: '#c4d4de', 'stroke-width': '1.5' }, svg); // Fels-Untergrund unten svgEl('polygon', { points: '0,300 600,300 600,278 0,150', fill: '#8a7d6b', opacity: '0.5' }, svg); // Bäume am Hangfuß [ [90, 262], [150, 274] ].forEach(([x, y]) => { svgEl('polygon', { points: `${x},${y - 26} ${x - 11},${y} ${x + 11},${y}`, fill: '#3a6b3e' }, svg); }); // Dynamische Gruppen: Risse + abgehendes Schneebrett const cracksG = svgEl('g', {}, svg); const slabG = svgEl('g', {}, svg); // Gefahren-Balken svgEl('rect', { x: 40, y: 40, width: 520, height: 20, fill: '#ffffff', stroke: '#1f4e5a', 'stroke-width': '1.2', rx: '10' }, svg); const riskBar = svgEl('rect', { x: 42, y: 42, width: 10, height: 16, fill: '#6f9c5f', rx: '8' }, svg); svgEl('text', { x: 40, y: 32, 'font-size': '11', 'font-weight': '700', fill: '#1f4e5a' }, svg).textContent = 'Gefahr'; const stateColor = { good: '#6f9c5f', now: '#4a7c8a', warn: '#e08a2a', bad: '#c85c4a' }; function update() { const n = +rng.value; const L = levels[n]; numOut.textContent = n; nameOut.textContent = L.name; riskOut.textContent = L.name + ' (Stufe ' + n + ')'; info.textContent = L.txt; info.dataset.state = L.state; // Balken (nicht-linear → zeigt den Sprung 3→4) riskBar.setAttribute('width', Math.max(8, (516 * L.risk) / 100)); riskBar.setAttribute('fill', stateColor[L.state]); // Risse proportional zur Stufe cracksG.innerHTML = ''; const nCracks = n - 1; for (let i = 0; i < nCracks; i++) { const x = 220 + i * 70 + Math.sin(i * 2) * 20; const y = 150 + i * 18; svgEl('path', { d: `M ${x} ${y} q 14 12 8 30 q -6 14 10 26`, stroke: '#7c8a94', 'stroke-width': '2', fill: 'none', 'stroke-linecap': 'round' }, cracksG); } // Abgehendes Schneebrett ab Stufe 4 slabG.innerHTML = ''; if (n >= 4) { svgEl('polygon', { points: '300,175 470,205 460,240 300,215', fill: '#dbe7ef', stroke: '#c85c4a', 'stroke-width': '2.5', 'stroke-dasharray': n >= 5 ? '0' : '6 4' }, slabG); // Bruchkante svgEl('line', { x1: 300, y1: 173, x2: 300, y2: 213, stroke: '#c85c4a', 'stroke-width': '3', 'stroke-linecap': 'round' }, slabG); if (n >= 5) { svgEl('polygon', { points: '150,225 340,250 330,285 150,260', fill: '#eef4f8', stroke: '#c85c4a', 'stroke-width': '2' }, slabG); } } } rng.addEventListener('input', update); update(); } // ===================================================================== // lichtgeschwindigkeit — Ziel-Auswahl, Lichtlaufzeit-Uhr // ===================================================================== function lichtgeschwindigkeit(root) { root.innerHTML = `

💡 Wie lange braucht das Licht?

Wähle ein Ziel. Ein Lichtblitz startet auf der Erde. Sieh, wie lange das Licht bis dorthin unterwegs ist.

Entfernung: 384.400 km
Lichtlaufzeit: 1,3 Sekunden

Licht legt rund 299.792 km pro Sekunde zurück — extrem schnell. Und doch braucht es bis zum nächsten Stern über 4 Jahre: Das All ist unvorstellbar groß. Entfernungen gerundet, Quelle: NASA.

`; const svg = root.querySelector('.ge-gh-svg'); const distOut = root.querySelector('[data-ref="dist"]'); const timeOut = root.querySelector('[data-ref="time"]'); if (!svg) return; const targets = { mond: { name: 'Mond', dist: '384.400 km', time: '1,3 Sekunden', emoji: '🌙' }, sonne: { name: 'Sonne', dist: '149,6 Mio. km', time: '8 Minuten 20 Sekunden', emoji: '☀' }, mars: { name: 'Mars', dist: 'im Schnitt 225 Mio. km', time: 'rund 12,5 Minuten (3 – 22 min je nach Bahn)', emoji: '🔴' }, proxima: { name: 'Proxima Centauri', dist: 'rund 40 Billionen km', time: 'etwa 4,2 Jahre', emoji: '⭐' } }; // Statische Szene: Erde links, Ziel rechts, Bahn dazwischen svgEl('rect', { x: 0, y: 0, width: 600, height: 200, fill: '#10233a' }, svg); // ein paar Sterne for (let i = 0; i < 26; i++) { svgEl('circle', { cx: 20 + Math.random() * 560, cy: 10 + Math.random() * 180, r: Math.random() * 1.3 + 0.4, fill: '#dfe8f2', opacity: (0.4 + Math.random() * 0.5).toFixed(2) }, svg); } svgEl('line', { x1: 70, y1: 100, x2: 520, y2: 100, stroke: '#3a5a7a', 'stroke-width': '2', 'stroke-dasharray': '5 6' }, svg); svgEl('circle', { cx: 60, cy: 100, r: 22, fill: '#3a7cc4' }, svg); svgEl('circle', { cx: 60, cy: 100, r: 22, fill: 'none', stroke: '#6fae5e', 'stroke-width': '3', 'stroke-dasharray': '10 8' }, svg); svgEl('text', { x: 60, y: 150, 'text-anchor': 'middle', 'font-size': '12', 'font-weight': '700', fill: '#dfe8f2' }, svg).textContent = 'Erde'; const targetIcon = svgEl('text', { x: 530, y: 108, 'text-anchor': 'middle', 'font-size': '34' }, svg); const targetLabel = svgEl('text', { x: 530, y: 150, 'text-anchor': 'middle', 'font-size': '12', 'font-weight': '700', fill: '#dfe8f2' }, svg); // Lichtblitz (Photon) const photon = svgEl('circle', { cx: 82, cy: 100, r: 6, fill: '#f4e04a' }, svg); const photonGlow = svgEl('circle', { cx: 82, cy: 100, r: 12, fill: '#f4e04a', opacity: '0.35' }, svg); const X0 = 82, X1 = 508; let animId = null, current = 'mond'; function animate() { cancelAnimationFrame(animId); const dur = 2200; const start = performance.now(); function tick(now) { if (!root.isConnected) { cancelAnimationFrame(animId); return; } const raw = (now - start) / dur; const t = raw % 1; const x = X0 + (X1 - X0) * t; photon.setAttribute('cx', x); photonGlow.setAttribute('cx', x); const op = t > 0.9 ? (1 - t) * 10 : 1; photon.setAttribute('opacity', op.toFixed(2)); photonGlow.setAttribute('opacity', (op * 0.35).toFixed(2)); animId = requestAnimationFrame(tick); } animId = requestAnimationFrame(tick); } function select(key) { const T = targets[key] || targets.mond; current = key; distOut.textContent = T.dist; timeOut.textContent = 'Lichtlaufzeit: ' + T.time; timeOut.dataset.state = key === 'proxima' ? 'bad' : (key === 'sonne' || key === 'mars' ? 'warn' : 'now'); targetIcon.textContent = T.emoji; targetLabel.textContent = T.name; root.querySelectorAll('.ge-albedo-choice .ge-btn').forEach(b => { b.classList.toggle('ge-btn-primary', b.dataset.key === key); }); animate(); } root.querySelectorAll('.ge-albedo-choice .ge-btn').forEach(b => { b.addEventListener('click', () => select(b.dataset.key)); }); select('mond'); } // ===================================================================== // gigawattstunde — Schieberegler GWh, „Strom für X Haushalte einen Tag" // ===================================================================== function gigawattstunde(root) { root.innerHTML = `

⚡ Wie viel ist eine Gigawattstunde?

Schiebe den Regler. Sieh, für wie viele Haushalte diese Strommenge einen ganzen Tag lang reicht.

1255075100
= 1.000.000 kWh

Ein durchschnittlicher österreichischer Haushalt verbraucht rund 3.500 kWh Strom pro Jahr, also etwa 9,6 kWh pro Tag. Quelle: E-Control. Schon 1 GWh ist eine riesige Strommenge.

`; const svg = root.querySelector('.ge-gh-svg'); const rng = root.querySelector('#ge-gw-range'); const valOut = root.querySelector('#ge-gw-val'); const kwhOut = root.querySelector('[data-ref="kwh"]'); const hhOut = root.querySelector('[data-ref="hh"]'); if (!svg || !rng) return; const PER_DAY = 3500 / 365; // ≈ 9,589 kWh pro Haushalt und Tag const housesG = svgEl('g', {}, svg); // jedes Symbol steht für eine feste Anzahl Haushalte const HOUSES_PER_ICON = 5000; const COLS = 20; function drawHouse(x, y, s) { const g = svgEl('g', { transform: `translate(${x},${y})` }, housesG); svgEl('rect', { x: -s / 2, y: -s * 0.55, width: s, height: s * 0.7, fill: '#f4c94e' }, g); svgEl('polygon', { points: `${-s / 2 - 1},${-s * 0.55} 0,${-s * 1.05} ${s / 2 + 1},${-s * 0.55}`, fill: '#c85c4a' }, g); } function update() { const gwh = +rng.value; valOut.textContent = gwh; kwhOut.textContent = fmtInt(gwh * 1e6) + ' kWh'; const households = (gwh * 1e6) / PER_DAY; hhOut.textContent = 'Strom für ca. ' + fmtInt(households) + ' Haushalte einen Tag lang'; housesG.innerHTML = ''; const nIcons = Math.max(1, Math.min(60, Math.round(households / HOUSES_PER_ICON))); const s = 20; for (let i = 0; i < nIcons; i++) { const c = i % COLS, r = Math.floor(i / COLS); drawHouse(30 + c * 28, 60 + r * 46, s); } svgEl('text', { x: 300, y: 168, 'text-anchor': 'middle', 'font-size': '11', 'font-weight': '600', fill: '#4a7c8a' }, housesG) .textContent = '1 Haus-Symbol ≈ ' + fmtInt(HOUSES_PER_ICON) + ' Haushalte'; } rng.addEventListener('input', update); update(); } // ===================================================================== // netzspannung — Land-Buttons, Volt + Steckertyp + Lade-Hinweis // ===================================================================== function netzspannung(root) { root.innerHTML = `

🔌 Netzspannung rund um die Welt

Tippe ein Land an. Sieh die Spannung, die Steckerform und ob dein Handy-Netzteil dort direkt lädt.

Spannung: 230 V
Steckertyp: Typ C / F

Nennspannungen und Steckertypen nach IEC: EU 230 V, USA 120 V, Japan 100 V, Großbritannien 230 V. Handy-Netzteile sind fast immer für 100 – 240 V gebaut und gleichen die Spannung selbst aus — nur die Steckerform ist weltweit verschieden.

`; const svg = root.querySelector('.ge-gh-svg'); const voltOut = root.querySelector('[data-ref="volt"]'); const plugOut = root.querySelector('[data-ref="plug"]'); const chargeOut = root.querySelector('[data-ref="charge"]'); if (!svg) return; const lands = { at: { volt: 230, plug: 'Typ C / F (Schuko)', home: true }, us: { volt: 120, plug: 'Typ A / B', home: false }, jp: { volt: 100, plug: 'Typ A / B', home: false }, gb: { volt: 230, plug: 'Typ G', home: false } }; // Spannungs-Skala als Balken (Bezug 240 V) svgEl('rect', { x: 40, y: 60, width: 520, height: 26, fill: '#ffffff', stroke: '#1f4e5a', 'stroke-width': '1.2', rx: '13' }, svg); const voltBar = svgEl('rect', { x: 42, y: 62, width: 100, height: 22, fill: '#4a7c8a', rx: '11' }, svg); const voltLabel = svgEl('text', { x: 300, y: 78, 'text-anchor': 'middle', 'font-size': '14', 'font-weight': '800', fill: '#ffffff' }, svg); svgEl('text', { x: 40, y: 50, 'font-size': '11', 'font-weight': '700', fill: '#1f4e5a' }, svg).textContent = '0 V'; svgEl('text', { x: 560, y: 50, 'text-anchor': 'end', 'font-size': '11', 'font-weight': '700', fill: '#1f4e5a' }, svg).textContent = '240 V'; // Blitz-Icon + Steckerform const plugIcon = svgEl('text', { x: 300, y: 135, 'text-anchor': 'middle', 'font-size': '13', 'font-weight': '700', fill: '#1f4e5a' }, svg); function select(key) { const L = lands[key] || lands.at; voltOut.textContent = L.volt + ' V'; plugOut.textContent = L.plug; voltBar.setAttribute('width', Math.max(20, (516 * L.volt) / 240)); voltBar.setAttribute('fill', L.volt >= 220 ? '#c85c4a' : '#4a7c8a'); voltLabel.textContent = L.volt + ' V'; plugIcon.textContent = 'Steckerform: ' + L.plug; if (L.home) { chargeOut.textContent = 'Dein Netzteil lädt direkt — und der Stecker passt (deine Heimat-Norm).'; chargeOut.dataset.state = 'good'; } else { chargeOut.textContent = 'Dein Handy-Netzteil (100 – 240 V) lädt direkt — aber für die Steckerform brauchst du einen Reise-Adapter.'; chargeOut.dataset.state = 'warn'; } root.querySelectorAll('.ge-albedo-choice .ge-btn').forEach(b => { b.classList.toggle('ge-btn-primary', b.dataset.key === key); }); } root.querySelectorAll('.ge-albedo-choice .ge-btn').forEach(b => { b.addEventListener('click', () => select(b.dataset.key)); }); select('at'); } // ===================================================================== // kartenmaßstab — Maßstab-Schieberegler, gleicher Ort in versch. Ausschnitten // ===================================================================== function kartenmassstab(root) { root.innerHTML = `

🗺 Der Kartenmaßstab

Schiebe den Regler vom Detail bis zum Landausschnitt. Sieh, wie derselbe Ort immer kleiner wird — und das Lineal, wie weit 1 cm auf der Karte in echt sind.

DetailOrtRegionLand
Lineal: 1 cm = 1 m

Rechenweg: 1 cm auf der Karte · Maßstabszahl = Strecke in echt. Merke: großer Maßstab (kleine Zahl) = kleiner Ausschnitt mit vielen Details, kleiner Maßstab (große Zahl) = großer Ausschnitt mit wenig Details.

`; const svg = root.querySelector('.ge-gh-svg'); const rng = root.querySelector('#ge-km-range'); const scaleOut = root.querySelector('#ge-km-scale'); const rulerOut = root.querySelector('[data-ref="ruler"]'); const viewOut = root.querySelector('[data-ref="view"]'); if (!svg || !rng) return; const scales = [100, 200, 500, 1000, 2000, 5000, 10000, 25000, 50000, 100000, 250000, 500000, 1000000]; const sceneG = svgEl('g', {}, svg); const rulerG = svgEl('g', {}, svg); function levelOf(scale) { if (scale <= 500) return 0; // Haus if (scale <= 5000) return 1; // Straßenzug if (scale <= 50000) return 2; // Ort / Viertel if (scale <= 250000) return 3; // Region return 4; // Land } function drawScene(level) { sceneG.innerHTML = ''; svgEl('rect', { x: 20, y: 20, width: 560, height: 180, fill: '#eef4ee', stroke: '#c4d4ca', 'stroke-width': '1.5', rx: '8' }, sceneG); const cx = 300, cy = 110; if (level === 0) { // Ein Haus mit Garten svgEl('rect', { x: 40, y: 40, width: 520, height: 140, fill: '#d8ead0' }, sceneG); svgEl('rect', { x: 210, y: 70, width: 180, height: 100, fill: '#f4c94e', stroke: '#1f4e5a', 'stroke-width': '2' }, sceneG); svgEl('polygon', { points: '200,70 300,20 400,70', fill: '#c85c4a' }, sceneG); svgEl('rect', { x: 285, y: 120, width: 30, height: 50, fill: '#6b4a2e' }, sceneG); svgEl('polygon', { points: '110,175 128,135 146,175', fill: '#3a6b3e' }, sceneG); svgEl('polygon', { points: '450,175 468,135 486,175', fill: '#3a6b3e' }, sceneG); } else if (level === 1) { // Straßenzug mit mehreren Häusern svgEl('rect', { x: 40, y: 100, width: 520, height: 28, fill: '#c9cdd2' }, sceneG); svgEl('line', { x1: 40, y1: 114, x2: 560, y2: 114, stroke: '#ffffff', 'stroke-width': '2', 'stroke-dasharray': '16 12' }, sceneG); for (let i = 0; i < 6; i++) { const x = 70 + i * 80; svgEl('rect', { x, y: 55, width: 44, height: 34, fill: '#f4c94e', stroke: '#1f4e5a', 'stroke-width': '1.2' }, sceneG); svgEl('polygon', { points: `${x - 3},55 ${x + 22},38 ${x + 47},55`, fill: '#c85c4a' }, sceneG); svgEl('rect', { x: x + 6, y: 138, width: 36, height: 26, fill: '#a9c99a' }, sceneG); } } else if (level === 2) { // Ort / Viertel: Häuserblöcke + Straßenraster svgEl('rect', { x: 40, y: 40, width: 520, height: 140, fill: '#dfe8df' }, sceneG); for (let gx = 0; gx < 5; gx++) for (let gy = 0; gy < 3; gy++) { svgEl('rect', { x: 70 + gx * 96, y: 55 + gy * 42, width: 70, height: 28, fill: '#c4a97a', stroke: '#8a7256', 'stroke-width': '1' }, sceneG); } for (let i = 1; i < 5; i++) svgEl('line', { x1: 40 + i * 104, y1: 40, x2: 40 + i * 104, y2: 180, stroke: '#c9cdd2', 'stroke-width': '6' }, sceneG); for (let i = 1; i < 3; i++) svgEl('line', { x1: 40, y1: 40 + i * 47, x2: 560, y2: 40 + i * 47, stroke: '#c9cdd2', 'stroke-width': '6' }, sceneG); } else if (level === 3) { // Region: Grün-/Wasserflächen, Fluss, Ortspunkte svgEl('rect', { x: 40, y: 40, width: 520, height: 140, fill: '#cfe3c4' }, sceneG); svgEl('path', { d: 'M 40 60 Q 200 90 300 70 T 560 120', stroke: '#4a9cc4', 'stroke-width': '9', fill: 'none', 'stroke-linecap': 'round' }, sceneG); svgEl('polygon', { points: '380,90 470,110 440,175 350,150', fill: '#b7d59e' }, sceneG); [ [140, 120], [300, 150], [470, 70], [230, 90] ].forEach(([x, y]) => { svgEl('circle', { cx: x, cy: y, r: 7, fill: '#c85c4a', stroke: '#fff', 'stroke-width': '1.5' }, sceneG); }); } else { // Land: großer Ausschnitt mit Städten svgEl('rect', { x: 40, y: 40, width: 520, height: 140, fill: '#cfe3c4' }, sceneG); svgEl('path', { d: 'M 60 150 Q 120 60 240 90 Q 360 120 440 70 Q 520 40 545 120 L 545 175 L 60 175 Z', fill: '#b7d59e', stroke: '#6f9c5f', 'stroke-width': '2' }, sceneG); svgEl('path', { d: 'M 40 40 Q 120 55 180 45 L 180 40 Z', fill: '#9cc4e4' }, sceneG); [ [140, 130, 'groß'], [300, 100, 'mittel'], [430, 130, 'klein'], [230, 155, 'klein'] ].forEach(([x, y, sz]) => { const r = sz === 'groß' ? 8 : (sz === 'mittel' ? 6 : 4); svgEl('circle', { cx: x, cy: y, r, fill: '#c85c4a', stroke: '#fff', 'stroke-width': '1.5' }, sceneG); }); } } function drawRuler(scale) { rulerG.innerHTML = ''; // Referenzlinie „1 cm auf der Karte" (fixe Länge 90 px als Anschauung) const x0 = 40, x1 = 130, y = 218; svgEl('line', { x1: x0, y1: y, x2: x1, y2: y, stroke: '#1f4e5a', 'stroke-width': '3', 'stroke-linecap': 'round' }, rulerG); svgEl('line', { x1: x0, y1: y - 6, x2: x0, y2: y + 6, stroke: '#1f4e5a', 'stroke-width': '3' }, rulerG); svgEl('line', { x1: x1, y1: y - 6, x2: x1, y2: y + 6, stroke: '#1f4e5a', 'stroke-width': '3' }, rulerG); svgEl('text', { x: 85, y: y + 24, 'text-anchor': 'middle', 'font-size': '12', 'font-weight': '700', fill: '#1f4e5a' }, rulerG).textContent = '1 cm auf der Karte'; const realM = scale / 100; // 1 cm * scale = scale cm = scale/100 m let real; if (realM >= 1000) real = fmtDec(realM / 1000, realM % 1000 === 0 ? 0 : 1) + ' km'; else real = fmtInt(realM) + ' m'; svgEl('text', { x: 150, y: y + 4, 'font-size': '14', 'font-weight': '800', fill: '#c85c4a' }, rulerG).textContent = '= ' + real + ' in echt'; return real; } function update() { const scale = scales[+rng.value]; scaleOut.textContent = fmtInt(scale); const level = levelOf(scale); drawScene(level); const real = drawRuler(scale); rulerOut.textContent = '1 cm = ' + real; const viewNames = ['Einzelnes Haus mit Garten', 'Ein Straßenzug', 'Ein Ort / Stadtviertel', 'Eine ganze Region', 'Großer Landausschnitt']; const big = scale <= 5000; viewOut.textContent = viewNames[level] + ' — ' + (big ? 'großer Maßstab, viele Details' : 'kleiner Maßstab, wenig Details'); viewOut.dataset.state = big ? 'good' : (level >= 3 ? 'warn' : 'now'); } rng.addEventListener('input', update); update(); } // Registry — Keys entsprechen key_slug aus DB. window.GlossarExperiments = Object.assign(window.GlossarExperiments || {}, { 'gletscher': gletscher, 'lawinenwarnstufe': lawinenwarnstufe, 'lichtgeschwindigkeit': lichtgeschwindigkeit, 'gigawattstunde': gigawattstunde, 'netzspannung': netzspannung, 'kartenmaßstab': kartenmassstab }); })();