Mini HTML-Editor
Neu
Exportieren
Link-Graph
🎨 Galerie
Projekt-Code:
Öffnen
📋 Kein Projekt-Code eingegeben — Dateien werden im
öffentlichen Bereich
gespeichert und nach 24 Stunden automatisch gelöscht. Lege ein
neues Projekt
an um Dateien dauerhaft zu speichern.
milena3.html
Speichern
Öffnen
↩ Undo
↪ Redo
A−
A+
Einfügen ▾
🔗 Link
🖼 Bild
🎨 Farbcode
📋 Liste (ul/li)
🃏 Karte (div)
⚡ Javascript-Block
🔒 Schützen
<!DOCTYPE html> <html lang="de"> <head> <meta charset="UTF-8"> <title>Multi-Sport Trainingsplan Generator</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> body { margin: 0; font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background: #f5f5f5; color: #222; } .container { max-width: 720px; margin: 32px auto; background: #fff; padding: 24px; border-radius: 12px; box-shadow: 0 2px 10px rgba(0,0,0,0.08); } h1, h2 { margin-top: 0; font-weight: 600; } p { margin-top: 4px; margin-bottom: 12px; font-size: 0.95rem; } label { display: block; margin-top: 14px; font-size: 0.9rem; font-weight: 600; } input, select { width: 100%; padding: 9px 10px; margin-top: 6px; border-radius: 6px; border: 1px solid #ccc; font-size: 0.95rem; box-sizing: border-box; } small { display: block; margin-top: 4px; color: #666; font-size: 0.8rem; } button { margin-top: 22px; width: 100%; padding: 11px; background: #222; color: #fff; border: none; border-radius: 6px; font-size: 1rem; cursor: pointer; } button:hover { background: #444; } #planScreen { display: none; max-width: 900px; margin: 32px auto; background: #fff; padding: 24px; border-radius: 12px; box-shadow: 0 2px 10px rgba(0,0,0,0.08); } .meta { font-size: 0.9rem; color: #555; margin-bottom: 16px; } .day-box { padding: 14px; border: 1px solid #ddd; border-radius: 8px; margin-bottom: 12px; display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; } .day-content { flex: 1; } .day-title { font-weight: 600; margin-bottom: 4px; } .day-desc { font-size: 0.9rem; color: #555; } .checkbox { width: 22px; height: 22px; border: 2px solid #222; border-radius: 4px; cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 0.9rem; flex-shrink: 0; } .checkbox.checked { background: #222; color: #fff; } .exercise-images { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; } .exercise-images img { width: 80px; height: 80px; object-fit: cover; border-radius: 6px; border: 1px solid #ddd; } .section-title { margin-top: 18px; margin-bottom: 8px; font-weight: 600; font-size: 0.95rem; } </style> </head> <body> <!-- START SCREEN --> <div class="container" id="startScreen"> <h1>Trainingsplan Generator (Multi-Sport & Triathlon)</h1> <p>Gib deine Daten ein und erhalte einen individuellen Trainingsplan mit Intervallen und Einheiten zum Abhaken.</p> <label>Sportart</label> <select id="sport"> <option value="">Bitte wählen</option> <option value="laufen">Laufen</option> <option value="rad">Radfahren</option> <option value="schwimmen">Schwimmen</option> <option value="kraft">Krafttraining</option> <option value="triathlon">Triathlon</option> </select> <label>Ziel</label> <select id="goal"> <option value="">Bitte wählen</option> <option value="wettkampf">Wettkampf</option> <option value="fitness">Allgemeine Fitness</option> <option value="abnehmen">Abnehmen</option> <option value="aufbau">Muskelaufbau</option> <option value="ausdauer">Ausdauer verbessern</option> </select> <label>Niveau</label> <select id="level"> <option value="">Bitte wählen</option> <option value="anfänger">Anfänger</option> <option value="fortgeschritten">Fortgeschritten</option> <option value="profi">Profi</option> </select> <label>Wettkampfstrecke</label> <select id="distance"> <option value="">Bitte zuerst Sportart wählen</option> </select> <small>Für Triathlon wird die Strecke zur Orientierung genutzt, Paces werden primär für Einzelsportarten berechnet.</small> <label>Wettkampfzeit (Endzeit)</label> <input type="text" id="raceTime" placeholder="z.B. 00:45:30 oder 45:30"> <small>Format: mm:ss oder hh:mm:ss</small> <label>Trainingstage pro Woche</label> <input type="number" id="days" min="1" max="7" placeholder="z.B. 4"> <button id="createPlanBtn">Plan erstellen</button> </div> <!-- PLAN SCREEN --> <div id="planScreen"> <h2>Dein individueller Trainingsplan</h2> <p class="meta" id="planMeta"></p> <div id="planList"></div> <button onclick="location.reload()">Neuen Plan erstellen</button> </div> <script> const sportSelect = document.getElementById("sport"); const distanceSelect = document.getElementById("distance"); const createPlanBtn = document.getElementById("createPlanBtn"); sportSelect.addEventListener("change", updateDistanceOptions); function updateDistanceOptions() { const sport = sportSelect.value; distanceSelect.innerHTML = ""; let options = []; if (sport === "laufen") { options = [ { value: "5", label: "5 km" }, { value: "10", label: "10 km" }, { value: "21.1", label: "Halbmarathon (21,1 km)" }, { value: "42.2", label: "Marathon (42,2 km)" } ]; } else if (sport === "rad") { options = [ { value: "20", label: "20 km" }, { value: "40", label: "40 km" }, { value: "90", label: "90 km" }, { value: "180", label: "180 km" } ]; } else if (sport === "schwimmen") { options = [ { value: "0.4", label: "400 m" }, { value: "0.75", label: "750 m" }, { value: "1.5", label: "1500 m" }, { value: "3.8", label: "3800 m" } ]; } else if (sport === "triathlon") { options = [ { value: "sprint", label: "Sprint" }, { value: "olympisch", label: "Olympisch" }, { value: "mittel", label: "Mitteldistanz" }, { value: "lang", label: "Langdistanz" } ]; } else if (sport === "kraft") { options = [ { value: "fullbody", label: "Ganzkörper-Session" } ]; } else { options = [{ value: "", label: "Bitte zuerst Sportart wählen" }]; } options.forEach(opt => { const o = document.createElement("option"); o.value = opt.value; o.textContent = opt.label; distanceSelect.appendChild(o); }); } function parseTimeToSeconds(timeStr) { const parts = timeStr.split(":").map(p => p.trim()); if (parts.length === 2) { const [m, s] = parts; return (parseInt(m, 10) || 0) * 60 + (parseInt(s, 10) || 0); } else if (parts.length === 3) { const [h, m, s] = parts; return (parseInt(h, 10) || 0) * 3600 + (parseInt(m, 10) || 0) * 60 + (parseInt(s, 10) || 0); } return NaN; } function formatPace(secondsPerKm) { const m = Math.floor(secondsPerKm / 60); const s = Math.round(secondsPerKm % 60); return `${m}:${s.toString().padStart(2, "0")} min/km`; } function formatSwimTempo(secondsPer100m) { const m = Math.floor(secondsPer100m / 60); const s = Math.round(secondsPer100m % 60); return `${m}:${s.toString().padStart(2, "0")} /100 m`; } function formatSpeedKmh(speed) { return `${speed.toFixed(1)} km/h`; } function getIntensityFactor(level, type) { // type: "interval" or "tempo" const base = { anfänger: { interval: 1.10, tempo: 1.05 }, fortgeschritten: { interval: 1.20, tempo: 1.10 }, profi: { interval: 1.30, tempo: 1.15 } }; const l = base[level] || base["fortgeschritten"]; return l[type] || 1.15; } function buildRunningSessions(level, goal, raceSeconds, distanceKm) { const paceRace = raceSeconds / distanceKm; // sec per km const intervalFactor = getIntensityFactor(level, "interval"); const tempoFactor = getIntensityFactor(level, "tempo"); const intervalPace = paceRace / intervalFactor; const tempoPace = paceRace / tempoFactor; const sessions = []; sessions.push({ title: "Intervall-Einheit (Laufen)", desc: `2×600 m @ ${formatPace(intervalPace)} (RPE 6–7), 2 min Trabpause. Fokus auf saubere Technik und kontrollierte Schnelligkeit.`, type: "interval" }); sessions.push({ title: "Tempodauerlauf", desc: `20–30 min @ ${formatPace(tempoPace)} (RPE 5–6). Gleichmäßiges Tempo, nicht voll, aber deutlich über lockerem Lauf.`, type: "tempo" }); sessions.push({ title: "Lockerer Dauerlauf", desc: "40–50 min locker (RPE 3–4). Kein Pace-Fokus, nur entspanntes Laufen zur Grundlage.", type: "easy" }); if (goal === "ausdauer" || goal === "wettkampf") { sessions.push({ title: "Langer Lauf", desc: "60–90 min ruhig (RPE 3–4). Fokus auf Umfang, keine Pace-Vorgabe.", type: "long" }); } return sessions; } function buildCyclingSessions(level, goal, raceSeconds, distanceKm) { const speedRace = (distanceKm / (raceSeconds / 3600)); // km/h const intervalFactor = getIntensityFactor(level, "interval"); const tempoFactor = getIntensityFactor(level, "tempo"); const intervalSpeed = speedRace * intervalFactor; const tempoSpeed = speedRace * tempoFactor; const sessions = []; sessions.push({ title: "Intervall-Einheit (Rad)", desc: `6×3 min @ ${formatSpeedKmh(intervalSpeed)} (RPE 7–8), 3 min locker dazwischen. Fokus auf hohe Leistung bei guter Kontrolle.`, type: "interval" }); sessions.push({ title: "Tempofahrt", desc: `30–40 min @ ${formatSpeedKmh(tempoSpeed)} (RPE 6). Gleichmäßige, zügige Fahrt.`, type: "tempo" }); sessions.push({ title: "Lockere Ausfahrt", desc: "60–90 min locker (RPE 3–4). Kein Geschwindigkeitsfokus, nur Zeit im Sattel.", type: "easy" }); return sessions; } function buildSwimSessions(level, goal, raceSeconds, distanceKm) { const distanceM = distanceKm * 1000; const tempoRacePer100 = raceSeconds / (distanceM / 100); const intervalFactor = getIntensityFactor(level, "interval"); const tempoFactor = getIntensityFactor(level, "tempo"); const intervalTempo = tempoRacePer100 / intervalFactor; const tempoTempo = tempoRacePer100 / tempoFactor; const sessions = []; sessions.push({ title: "Intervall-Einheit (Schwimmen)", desc: `8×100 m @ ${formatSwimTempo(intervalTempo)} (RPE 7), 20–30 s Pause. Fokus auf saubere Technik und konstantes Tempo.`, type: "interval" }); sessions.push({ title: "Temposerie", desc: `4×200 m @ ${formatSwimTempo(tempoTempo)} (RPE 6), 45–60 s Pause.`, type: "tempo" }); sessions.push({ title: "Lockeres Schwimmen", desc: "30–40 min lockeres Schwimmen, Technikfokus, keine Tempo-Vorgabe.", type: "easy" }); return sessions; } function buildStrengthSessions(goal, level) { const sessions = []; sessions.push({ title: "Ganzkörper-Krafttraining", desc: "3 Sätze Kniebeugen, Ausfallschritte, Rumpfstütz (Plank), Rudern. 8–12 Wiederholungen pro Satz, kontrollierte Ausführung.", type: "strength", images: [ "https://via.placeholder.com/80?text=Kniebeuge", "https://via.placeholder.com/80?text=Plank", "https://via.placeholder.com/80?text=Ausfallschritt" ] }); sessions.push({ title: "Core & Stabilität", desc: "3–4 Übungen für Rumpf und Hüftstabilität (z.B. Seitstütz, Bird-Dog, Glute Bridge). 2–3 Sätze pro Übung.", type: "strength", images: [ "https://via.placeholder.com/80?text=Seitst%C3%BCtz", "https://via.placeholder.com/80?text=Bridge" ] }); return sessions; } function buildTriathlonSessions(level, goal) { // Triathlon: Mix aus Laufen, Rad, Schwimmen, ohne exakte Pace-Berechnung const sessions = []; sessions.push({ title: "Koppeltraining (Rad + Lauf)", desc: "60 min Rad locker bis moderat, direkt danach 15–20 min lockerer Lauf. Fokus auf Umstellung vom Rad auf Lauf.", type: "brick" }); sessions.push({ title: "Intervall-Lauf (Triathlon)", desc: "3×1 km zügig (RPE 6–7), 3 min Trabpause. Kein exakter Pace-Fokus, aber deutlich schneller als Wettkampftempo.", type: "interval" }); sessions.push({ title: "Schwimmtechnik + Intervalle", desc: "20 min Technik (z.B. Abschlag, Einarmig), danach 6×100 m moderat zügig, 30 s Pause.", type: "swim" }); sessions.push({ title: "Langer Radtag", desc: "90–150 min ruhige bis moderate Ausfahrt (RPE 3–4). Fokus auf Umfang.", type: "bike" }); return sessions; } function buildPlan(sport, goal, level, raceSeconds, distanceValue, days) { let sessions = []; if (sport === "laufen") { sessions = buildRunningSessions(level, goal, raceSeconds, parseFloat(distanceValue)); } else if (sport === "rad") { sessions = buildCyclingSessions(level, goal, raceSeconds, parseFloat(distanceValue)); } else if (sport === "schwimmen") { sessions = buildSwimSessions(level, goal, raceSeconds, parseFloat(distanceValue)); } else if (sport === "kraft") { sessions = buildStrengthSessions(goal, level); } else if (sport === "triathlon") { sessions = buildTriathlonSessions(level, goal); } const plan = []; for (let i = 1; i <= days; i++) { const session = sessions[(i - 1) % sessions.length]; plan.push({ day: i, title: session.title, desc: session.desc, images: session.images || null }); } return plan; } createPlanBtn.addEventListener("click", () => { const sport = document.getElementById("sport").value; const goal = document.getElementById("goal").value; const level = document.getElementById("level").value; const distanceValue = document.getElementById("distance").value; const raceTimeStr = document.getElementById("raceTime").value.trim(); const days = parseInt(document.getElementById("days").value, 10); if (!sport || !goal || !level || !distanceValue || !raceTimeStr || isNaN(days) || days < 1 || days > 7) { alert("Bitte alle Felder korrekt ausfüllen (inkl. Wettkampfzeit und Trainingstage)."); return; } let raceSeconds = parseTimeToSeconds(raceTimeStr); if (isNaN(raceSeconds) || raceSeconds <= 0) { alert("Bitte eine gültige Wettkampfzeit im Format mm:ss oder hh:mm:ss eingeben."); return; } // Für Krafttraining ist Wettkampfzeit nicht relevant, aber wir nutzen sie trotzdem zur Konsistenz if (sport === "kraft") { raceSeconds = 1800; // Dummy } const plan = buildPlan(sport, goal, level, raceSeconds, distanceValue, days); document.getElementById("startScreen").style.display = "none"; const planScreen = document.getElementById("planScreen"); planScreen.style.display = "block"; const planMeta = document.getElementById("planMeta"); planMeta.textContent = `Sportart: ${sport}, Ziel: ${goal}, Niveau: ${level}, Trainingstage: ${days} pro Woche.`; const planList = document.getElementById("planList"); planList.innerHTML = ""; plan.forEach(item => { const box = document.createElement("div"); box.className = "day-box"; const content = document.createElement("div"); content.className = "day-content"; const title = document.createElement("div"); title.className = "day-title"; title.textContent = `Tag ${item.day}: ${item.title}`; const desc = document.createElement("div"); desc.className = "day-desc"; desc.textContent = item.desc; content.appendChild(title); content.appendChild(desc); if (item.images && item.images.length) { const imgWrap = document.createElement("div"); imgWrap.className = "exercise-images"; item.images.forEach(src => { const img = document.createElement("img"); img.src = src; img.alt = "Übung"; imgWrap.appendChild(img); }); content.appendChild(imgWrap); } const checkbox = document.createElement("div"); checkbox.className = "checkbox"; checkbox.onclick = () => checkbox.classList.toggle("checked"); box.appendChild(content); box.appendChild(checkbox); planList.appendChild(box); }); }); </script> </body> </html>
⬛ Konsole
0
▲
Umbenennen…
Löschen…
Dateinamen kopieren
URL kopieren
Als <img> einfügen
⚙ Projekt-Eigenschaften
📝 Info
📱 PWA
Dein Edit-Code
🔒 geheim halten!
–
Nur mit diesem Code kannst du dein Projekt bearbeiten. Schreib ihn auf!
✓ Kopiert!
Projekt-Titel
Dein Name
Klasse
In der Galerie veröffentlichen
⚠ Deine Startseite muss
index.html
heißen.
Galerie-Code
Unter diesem Code ist dein Projekt in der Galerie sichtbar.
Mach dein Projekt zur
Progressive Web App
— dann können Nutzer es auf dem Handy installieren und offline nutzen.
App-Name (aus Projekt-Titel)
Icon-Farbe
✓ PWA aktiv —
manifest.json und service-worker.js wurden angelegt. index.html wurde aktualisiert.