diff --git a/README.md b/README.md index 0706b23..cf03480 100644 --- a/README.md +++ b/README.md @@ -1,52 +1,204 @@ -# 🎓 Projekt FH – Eingabeprüfung & Wörterbuch +Super — hier ist die README.md **mit rohem Markdown** (also mit `#`, `*`, etc.), zum Kopieren: -## ✨ Funktionalität +```markdown +# Escape-Pad -Dieses Projekt besteht aus **zwei Seiten**: - -1. **Hinweis-Abfrage (Startseite):** - Hier kann man Wörter oder Sätze eingeben. Diese Eingabe wird mit den hinterlegten Daten im lokalen Speicher abgeglichen. - → Wird ein passender Eintrag gefunden, wird die zugehörige Ausgabe (Text, Zahl oder Sonderzeichen) angezeigt. - -2. **Datenpflege:** - Auf dieser Seite können neue Paare (Eingabe ↔ Ausgabe) eingetragen und gespeichert werden. +Interaktives Zahlen-Pad über einem Hintergrundbild (Indiana-Jones-Style). +Vier Ziffern lassen sich über „Münz“-Klickflächen erhöhen/verringern. +Ein Schlüssel-Button prüft den Code. Bei korrekter Eingabe wird der Pad-Inhalt geleert und eine frei definierbare Nachricht im Stil der Ziffern angezeigt. Code & Nachricht sind per Tastenkürzel änderbar und werden in `localStorage` gespeichert. --- -### 🔁 Navigation +## Features -- Zwischen den beiden Seiten wird per **Tastenkombination `Strg + Ä`** umgeschaltet. -- Beim Start der Anwendung wird standardmäßig die **Hinweis-Abfrage** angezeigt. +- Vollbild-Layout (nutzt gesamten Viewport; F11 für echten Vollbildmodus) +- Unsichtbare, responsive Klickflächen über den Münzen +- Schlüssel-Bild als „Öffnen“-Button +- Erfolgstext ersetzt den gesamten Pad-Inhalt +- Code & Nachricht per Tastenkürzel setzen (persistiert via `localStorage`) +- „Indiana-Jones“-Ziffernstile (graviert **oder** gestempelt) +- Barrierefrei: versteckter Text für Screenreader, `role="status"` --- -### ⌨️ Eingabeinteraktion +## Projektstruktur -- In den Eingabefeldern kann die Eingabe durch **Drücken der Enter-Taste** bestätigt werden. -- Alternativ steht jeweils ein **Button zur Bestätigung** zur Verfügung. +``` + +/projektordner +├─ index.html +├─ style.css +├─ script.js +├─ back\_image\_new\.jpg # Hintergrundbild +└─ key.png # Schlüssel-Button (PNG, transparent) + +```` + +> Passe Dateinamen bei Bedarf in `index.html`/`style.css` an. --- -### 🖥️ Vollbildmodus +## Schnellstart -Um die Anwendung im **Vollbild** zu nutzen, kann wie gewohnt die Taste **`F11`** gedrückt werden (Browser-Funktion). +1. `back_image_new.jpg` und `key.png` neben `index.html` ablegen. +2. `index.html` im Browser öffnen. +3. F11 → Vollbild. +4. Münzen ↑/↓ klicken, Code einstellen, Schlüssel anklicken. --- -## 🚀 Starten +## Tastenkürzel -Einfach einen **Doppelklick auf `index.html`** ausführen. -Die Anwendung öffnet sich im Standardbrowser und ist sofort einsatzbereit. +| Aktion | Windows/Linux | macOS | Hinweis | +|------------------------|-------------------------|-----------------------|---------| +| Nachricht setzen | **Strg + Ä** / **Strg + M** | **⌘ + Ä** / **⌘ + M** | Prompt mit aktuellem Text | +| Code setzen (4 Ziffern)| **Strg + Ö** / **Strg + K** | **⌘ + Ö** / **⌘ + K** | Akzeptiert `4279` oder `4,2,7,9` | + +- Gespeichert unter `localStorage`-Schlüsseln: + - `escape_message` (Nachricht) + - `escape_code` (Array der 4 Ziffern) +- Zurücksetzen: Seite neu laden **und** Site-Daten/LocalStorage löschen, oder neue Werte per Shortcut setzen. --- -## 🔐 Sicherheit & Hinweis +## Konfiguration -Da es sich um eine **einfache, lokale Anwendung** handelt: +### 1) Position & Größen (`style.css`, im `:root`) -- wurden keine besonderen Sicherheitsmaßnahmen implementiert, -- ist der komplette Quellcode offen einsehbar und lokal speicherbar. +```css +:root{ + --pad-left: 12%; /* Abstand vom linken Bildrand */ + --pad-top: 22%; /* Abstand von oben */ + --pad-w: 50%; /* Breite des aktiven Bereichs */ + --pad-h: 54%; /* Höhe des aktiven Bereichs */ -Bitte beachten: Die Daten werden **im `localStorage` des Browsers** abgelegt und können dort manuell eingesehen oder gelöscht werden. + --coin: 13.5%; /* Durchmesser der Münz-Klickflächen relativ zum Pad */ + --key-size: 26%; /* Breite des Schlüssel-Bildes relativ zum Pad */ + --digit-size: clamp(24px, 6.2vw, 82px); /* Basisschriftgröße der Ziffern */ +} +```` + +> Diese Variablen an dein Hintergrundbild anpassen, bis die Klickflächen exakt auf den Münzen liegen. + +### 2) Defaults (`script.js`) + +```js +const DEFAULT_CODE = [4, 2, 7, 9]; +let code = JSON.parse(localStorage.getItem("escape_code") || "null") || DEFAULT_CODE; +let solvedText = localStorage.getItem("escape_message") || "GEHEIMNIS GEÖFFNET"; +``` --- + +## Styling der Ziffern (Indy-Look) + +Binde **eine** der Fonts in `index.html` (vor `style.css`) ein und nutze die zugehörige `.digit`-Regel in `style.css`. + +**A) Graviert / antik (Cinzel):** + +```html + +``` + +```css +.digit{ + font: 900 var(--digit-size)/1 "Cinzel", Georgia, serif; + letter-spacing:.06em; + color:#3a2616; + -webkit-text-stroke:1px rgba(0,0,0,.18); + text-shadow: + 0 1px 0 rgba(250,228,180,.65), + 0 -1px 0 rgba(0,0,0,.20), + 0 2px 2px rgba(0,0,0,.30), + 0 0 8px rgba(110,80,40,.20); + pointer-events:none; + transform: translateY(4%); + /* optional: mix-blend-mode: multiply; */ +} +``` + +**B) Gestempelt / Pulp (Special Elite):** + +```html + +``` + +```css +.digit{ + font: 800 var(--digit-size)/1 "Special Elite","Courier New",monospace; + letter-spacing:.04em; + color:#2d1f12; + text-shadow: + 0 1px 0 rgba(255,230,180,.45), + 0 2px 2px rgba(0,0,0,.35); + filter: contrast(1.05) sepia(.25); + pointer-events:none; + transform: translateY(4%); +} +``` + +> Der Erfolgstext nutzt `.digit` erneut und wird über `.solvedText` größer skaliert. + +--- + +## Technische Hinweise + +* **Vollbild:** `.escape` nutzt `width: 100vw; height: 100vh;`. Hintergrundbild füllt per `object-fit: cover`. +* **Responsiv:** Prozentbasierte Positionen/Größen; Klickflächen skalieren mit. +* **Events:** Münz-Klicks werden delegiert über `#pad` behandelt; Schlüssel-Button hat `id="openBtn"`. +* **Erfolg:** Bei korrektem Code wird `#pad` geleert und eine `.solvedText.digit`-Nachricht eingesetzt (siehe CSS-Klasse `.pad--cleared`). + +--- + +## Barrierefreiheit + +* Schlüssel-Button enthält visuell versteckten Text (`.visually-hidden`) für Screenreader. +* Erfolgstext hat `role="status"` und `aria-live="polite"`. + +--- + +## Troubleshooting + +* **Klickflächen „unsichtbar“ / Höhe 0:** + Stelle sicher, dass `.escape { height: 100vh; }` gesetzt ist und `.overlay`, `.pad` prozentuale Größen davon ableiten. +* **Schlüssel-Button als graues Rechteck oder links verschoben:** + Alte Button-Styles überschreiben. In `style.css` sicherstellen: + + ```css + .open{ appearance:none; -webkit-appearance:none; background:transparent; border:0; padding:0; } + .open img{ position:static; display:block; width:var(--key-size); height:auto; } + ``` + + Prüfe, ob es globale `img`-Regeln gibt (z. B. `position:absolute;`) – diese dürfen **nicht** auf den Schlüssel wirken. +* **Bildpfade prüfen:** + `back_image_new.jpg` und `key.png` müssen erreichbar sein (gleicher Ordner wie `index.html` oder Pfade anpassen). +* **Cache leeren:** + Harte Aktualisierung (Ctrl/Cmd + Shift + R). + +--- + +## Erweiterungen (Ideen) + +* Klick-/Öffnen-Soundeffekte +* Mehr Ziffernstellen (Grid-Spalten erhöhen) +* Touch-Gesten (Wischen ↑/↓) +* Alternative „Öffnen“-Interaktion (z. B. Doppelklick) + +--- + +## Lizenz / Assets + +* **Google Fonts** (Cinzel, Special Elite): SIL Open Font License – Nutzung in Webprojekten erlaubt. +* **Eigene Bilder** (`back_image_new.jpg`, `key.png`): Bitte Rechteinhaberschaft sicherstellen. + +--- + +## Support + +Feintuning gewünscht (exakte `--pad-*`-Werte, Button-Größe, Farbnuancen)? +Kurze Info oder Screenshot schicken – ich passe die Parameter punktgenau an. + +``` + +Oder direkt herunterladen: **[Download README.md](sandbox:/mnt/data/README.md)** ✅ +``` diff --git a/script.js b/script.js index dbc401f..1f01a75 100644 --- a/script.js +++ b/script.js @@ -1,48 +1,132 @@ -// Startwerte -const digits = [1, 2, 3, 4]; +// ================== Konfiguration / State ================== +const DEFAULT_CODE = [4, 2, 7, 9]; +let code = JSON.parse(localStorage.getItem("escape_code") || "null") || DEFAULT_CODE; +let solvedText = localStorage.getItem("escape_message") || "GEHEIMNIS GEÖFFNET"; -// Richtige Kombination -const code = [4, 2, 7, 9]; // <- anpassen! +const pad = document.getElementById("pad"); -const dEls = digits.map((_, i) => document.getElementById('d' + i)); -const pad = document.getElementById('pad'); -const openBtn = document.getElementById('openBtn'); -const success = document.getElementById('success'); +// Merke dir das Original-HTML, damit wir es nach einem "Clear" wiederherstellen können +const padTemplate = pad.innerHTML; -const render = () => digits.forEach((v, i) => dEls[i].textContent = v); +// Startwerte der 4 Stellen (0–9) +let digits = [1, 2, 3, 4]; -// Klicks auf Münzen -pad.addEventListener('click', (ev) => { - const btn = ev.target.closest('.coin'); +// Elemente-Cache für die Ziffern +let dEls = []; +function cacheDigitEls() { + dEls = [0, 1, 2, 3].map((i) => document.getElementById("d" + i)); +} +cacheDigitEls(); + +// ================== Rendering & UI-Aufbau ================== +const render = () => digits.forEach((v, i) => dEls[i] && (dEls[i].textContent = v)); + +function wireOpenButton() { + const btn = document.getElementById("openBtn"); if (!btn) return; + btn.addEventListener("click", onOpenClick); +} +wireOpenButton(); + +// Delegierter Klick-Handler für die Münzen (↑/↓) +pad.addEventListener("click", (ev) => { + const btn = ev.target.closest(".coin"); + if (!btn || !pad.contains(btn)) return; const idx = +btn.dataset.idx; const dir = btn.dataset.dir; - if (dir === 'up') digits[idx] = (digits[idx] + 1) % 10; - if (dir === 'down') digits[idx] = (digits[idx] + 9) % 10; - + if (dir === "up") digits[idx] = (digits[idx] + 1) % 10; + if (dir === "down") digits[idx] = (digits[idx] + 9) % 10; // -1 modulo 10 render(); }); -// Öffnen-Button -openBtn.addEventListener('click', () => { +function onOpenClick() { const ok = digits.every((v, i) => v === code[i]); - if (ok) { - // Inhalt des Pads ersetzen: alles raus, Nachricht rein - pad.classList.remove('pad--shake'); - pad.classList.add('pad--cleared'); - pad.innerHTML = ` -