Files
geograsim/App/assets/js/glossar-experiments-klimazonen.js
T
Adminator 685b4700f8 Glossar: 4 erklärende Widgets + 2 Einträge anschaulicher
Widgets: Ernährungspyramide (US-1992 vs DACH-2024 vs Denkfehler), Kakao-Bohne
(Schoko-Fließband + Mischverhältnis→Sorte/kaputte Masse), Klimazone (Bänder Äquator→Pol
mit Beispielpflanzen), Monsun (Monatsregen-Balkendiagramm Mumbai + Wien-Vergleich, Quelle IMD).
Texte: off-season-import (Winter-Erdbeere ~10× CO₂, Schiff vs Flug) + lebensmittelverschwendung
(70 kg = ~6 Wochen Essen; 700 Mio. Hungernde) — greifbare Vergleiche.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 01:42:20 +02:00

199 lines
8.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Glossar-Experimente — Klimazonen.
*
* Registrierung: window.GlossarExperiments['klimazone'] = function (root) { … }
* Der Renderer (glossar.php) hängt einen leeren Container ein und ruft die
* Funktion mit diesem Container als einzigem Argument auf.
*
* Nur bestehende .ge-*-Klassen aus glossar.php verwenden, kein neues CSS.
*/
(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: Klimazonen der Erde — Querschnitt Äquator → Pol
// Bänder anklicken → Temperatur, Regen und was dort wächst.
// =====================================================================
function climateZones(root) {
// Bänder von OBEN (Pol, kalt) nach UNTEN (Äquator, heiß).
// y-Werte passen zu viewBox 0 0 600 340.
const zones = [
{
key: 'polar',
name: 'Polargebiete',
where: 'Arktis · Antarktis',
temp: '30 0 °C',
rain: 'sehr wenig, meist Schnee',
grows: 'kein Ackerbau — zu kalt',
emoji: '🧊',
color: '#dbe9ee', text: '#2a4a55', border: '#9fbcc6',
state: 'now'
},
{
key: 'boreal',
name: 'Kalte Zone (Nadelwald)',
where: 'Skandinavien · Kanada',
temp: '0 5 °C im Jahr',
rain: 'mittel, lange kalte Winter',
grows: 'Nadelwald, Beeren — kaum Ackerbau',
emoji: '🌲',
color: '#5a8a8f', text: '#ffffff', border: '#3d6b70',
state: 'now'
},
{
key: 'temperate',
name: 'Gemäßigte Zone',
where: 'Österreich · Mitteleuropa',
temp: '8 12 °C im Jahr',
rain: '600 1.000 mm, 4 Jahreszeiten',
grows: 'Äpfel, Getreide, Erdäpfel',
emoji: '🍎',
color: '#4a7c4e', text: '#ffffff', border: '#356139',
state: 'good',
home: true
},
{
key: 'subtropic',
name: 'Subtropen',
where: 'Mittelmeer · Kalifornien',
temp: '15 22 °C im Jahr',
rain: 'trockene heiße Sommer',
grows: 'Oliven, Zitrusfrüchte, Mandeln',
emoji: '🍊',
color: '#e8c547', text: '#4a3d0a', border: '#c9a516',
state: 'warn'
},
{
key: 'tropic',
name: 'Tropen (Äquator)',
where: 'heiß und feucht',
temp: '24 28 °C, immer warm',
rain: '1.500 3.000 mm, sehr viel Regen',
grows: 'Kakao, Banane, Kaffee, Reis',
emoji: '🍌',
color: '#2e7d4f', text: '#ffffff', border: '#1f5a38',
state: 'warn'
}
];
root.innerHTML = `
<div class="ge-wrap">
<div class="ge-head">
<h3>🌍 Die Klimazonen der Erde</h3>
<p>Von unten (Äquator, viel Sonne) nach oben (Pol, wenig Sonne) wird es kühler. Tippe auf ein Band und schau, was dort wächst.</p>
</div>
<svg class="ge-gh-svg" viewBox="0 0 600 340" preserveAspectRatio="xMidYMid meet" role="group" aria-label="Klimazonen von Äquator bis Pol"></svg>
<div class="ge-gh-result">
<div class="ge-gh-pill" id="ge-kz-info" data-state="good">Tippe auf ein Band …</div>
<div class="ge-gh-pill" id="ge-kz-key" data-state="now">Wo etwas wächst, hängt von Wärme und Regen ab.</div>
</div>
<p class="ge-note">Einteilung nach den Klimazonen der Köppen-Geiger-Klassifikation; Temperatur- und Niederschlagsbereiche sind grobe kindgerechte Richtwerte. Quelle: Klimadiagramme &amp; Köppen-Geiger-Klassifikation.</p>
</div>
`;
const svg = root.querySelector('.ge-gh-svg');
const info = root.querySelector('#ge-kz-info');
const keyPill = root.querySelector('#ge-kz-key');
if (!svg || !info || !keyPill) return;
const BAND_X = 92;
const BAND_W = 466;
const BAND_H = 54;
const TOP = 26;
// Linke Achse: Pol oben → Äquator unten, mit Sonnen-Symbol.
const axisTop = TOP;
const axisBot = TOP + zones.length * BAND_H;
svgEl('line', { x1: 60, y1: axisTop, x2: 60, y2: axisBot, stroke: '#4a4a4a', 'stroke-width': '1.5' }, svg);
// Pfeilspitzen (oben = kalt, unten = warm)
svgEl('polygon', { points: `60,${axisTop - 8} 55,${axisTop + 2} 65,${axisTop + 2}`, fill: '#4a4a4a' }, svg);
svgEl('polygon', { points: `60,${axisBot + 8} 55,${axisBot - 2} 65,${axisBot - 2}`, fill: '#4a4a4a' }, svg);
const polTxt = svgEl('text', { x: 44, y: axisTop + 6, 'text-anchor': 'middle', 'font-size': '11', 'font-weight': '800', fill: '#2a4a55', transform: `rotate(-90, 44, ${axisTop + 40})` }, svg);
polTxt.textContent = 'Pol ❄';
const aeqTxt = svgEl('text', { x: 44, y: axisBot - 4, 'text-anchor': 'middle', 'font-size': '11', 'font-weight': '800', fill: '#2e7d4f', transform: `rotate(-90, 44, ${axisBot - 40})` }, svg);
aeqTxt.textContent = 'Äquator ☀';
const nodes = [];
let current = null;
zones.forEach((z, i) => {
const y = TOP + i * BAND_H;
const g = svgEl('g', { class: 'ge-kz-band', style: 'cursor:pointer', tabindex: '0', role: 'button', 'aria-label': z.name }, svg);
const rect = svgEl('rect', {
x: BAND_X, y: y + 2, width: BAND_W, height: BAND_H - 4, rx: 8,
fill: z.color, stroke: z.border, 'stroke-width': '1.5'
}, g);
// Emoji links im Band
svgEl('text', { x: BAND_X + 26, y: y + BAND_H / 2 + 9, 'text-anchor': 'middle', 'font-size': '26' }, g)
.textContent = z.emoji;
// Zonenname
const name = svgEl('text', { x: BAND_X + 52, y: y + BAND_H / 2 - 2, 'font-size': '14', 'font-weight': '800', fill: z.text }, g);
name.textContent = z.name;
// Wo (klein darunter)
const sub = svgEl('text', { x: BAND_X + 52, y: y + BAND_H / 2 + 15, 'font-size': '10.5', 'font-weight': '600', fill: z.text, opacity: '0.9' }, g);
sub.textContent = z.where;
// „Hier ist Österreich"-Marker
if (z.home) {
const marker = svgEl('g', {}, g);
svgEl('rect', { x: BAND_X + BAND_W - 118, y: y + BAND_H / 2 - 13, width: 112, height: 24, rx: 12, fill: '#ffffff', stroke: '#c85c4a', 'stroke-width': '1.5' }, marker);
svgEl('text', { x: BAND_X + BAND_W - 62, y: y + BAND_H / 2 + 3, 'text-anchor': 'middle', 'font-size': '11', 'font-weight': '800', fill: '#c85c4a' }, marker)
.textContent = '📍 Österreich';
}
nodes.push({ z, rect });
const activate = () => select(i);
g.addEventListener('click', activate);
g.addEventListener('keydown', (ev) => {
if (ev.key === 'Enter' || ev.key === ' ') { ev.preventDefault(); activate(); }
});
});
function select(i) {
const z = zones[i];
current = i;
// Auswahl-Rahmen setzen
nodes.forEach((n, j) => {
n.rect.setAttribute('stroke', j === i ? '#1f4e5a' : n.z.border);
n.rect.setAttribute('stroke-width', j === i ? '3.5' : '1.5');
});
info.dataset.state = z.state;
info.innerHTML =
`<strong>${z.name}</strong> · ${z.where}` +
`<br>🌡 ${z.temp}` +
`<br>💧 Regen: ${z.rain}` +
`<br>🌱 Wächst: <strong>${z.grows}</strong>`;
// Kernerkenntnis dynamisch auf die gewählte Zone beziehen
let msg;
if (z.key === 'tropic') {
msg = 'In den Tropen ist es heiß und feucht — nur hier wächst Kakao für Schokolade.';
} else if (z.key === 'temperate') {
msg = 'Bei uns in Österreich ist es mild mit Regen — perfekt für Äpfel und Getreide, aber zu kühl für Kakao.';
} else if (z.key === 'polar' || z.key === 'boreal') {
msg = 'Zu kalt und zu wenig Sonne: hier gibt es kaum oder gar keinen Ackerbau.';
} else {
msg = 'Heiße, trockene Sommer mögen Oliven und Zitrusfrüchte — bei uns wäre es dafür zu kühl.';
}
keyPill.dataset.state = 'now';
keyPill.innerHTML = `<strong>Merke:</strong> ${msg}`;
}
// Startzustand: gemäßigte Zone (Österreich) vorgewählt
select(2);
}
// Registry — Object.assign, damit die Ladereihenfolge egal ist.
window.GlossarExperiments = Object.assign(window.GlossarExperiments || {}, {
'klimazone': climateZones
});
})();