/* ===================================================================== DIE BILDSCHAU (25.09.2026) ===================================================================== Filipe: „wenn man bilder aufmacht, will ich dass die in der mitte sind. beim hochformat soll links der husky sein und rechts der hase und beim querformat soll oben dogfather und unten team dogi stehen da wo platz ist. es soll richtig geil gemacht werden alles … ich will nicht dahin geschmissen sondern was richtig geiles mit einem geilen hintergrund." --------------------------------------------------------------------- WAS VORHER PASSIERTE Ein Klick auf ein Foto oeffnete die Datei selbst in einem neuen Tab. Was man dann sah, war nicht unsere Seite, sondern die eingebaute Bildanzeige des Browsers: schwarzer Grund, Bild oben links in der Ecke, Dateiname in der Titelleiste. Auf Filipes Bildschirmfoto nimmt das Foto die linke Haelfte ein, rechts sind 1200 px Schwarz. Das ist kein Fehler im Browser -- er zeigt eine Datei, und eine Datei hat keine Gestaltung. Wer Gestaltung will, muss eine SEITE zeigen. --------------------------------------------------------------------- WARUM EINE SCHAU IN DER SEITE UND KEIN ZWEITER TAB Ein zweiter Tab braucht eine eigene Seite, eine eigene Anmeldung und einen eigenen Weg zurueck. Die Schau liegt UEBER dem Chat: Man ist mit Escape wieder da, wo man war, und das Gespraech laeuft im Hintergrund weiter. DER WEG IN DEN TAB BLEIBT TROTZDEM. Das Foto haengt weiterhin an einem echten Verweis mit `target="_blank"` -- mittlere Maustaste, „In neuem Tab oeffnen" und Herunterladen funktionieren wie vorher. Abgefangen wird nur der GEWOEHNLICHE Klick. Ein Verweis, der kein Verweis mehr ist, nimmt Leuten Wege weg, die sie seit Jahren kennen. --------------------------------------------------------------------- WARUM `` UND KEIN EIGENES DIV `showModal()` bringt drei Dinge mit, die man sonst von Hand baut und dabei vergisst: Escape schliesst, der Tastaturfokus bleibt drin, und alles dahinter ist fuer Vorleseprogramme stumm. Drei eigene Loesungen waeren drei Gelegenheiten fuer einen Fehler. --------------------------------------------------------------------- DIE BEGLEITER HOCHFORMAT: Husky links, Hase rechts. Dort ist der Platz -- ein hohes Foto laesst links und rechts je ein Viertel des Bildschirms frei. QUERFORMAT: „DogFather" oben, „Team Dogi" unten. Dort ist der Platz -- ein breites Foto laesst oben und unten Streifen frei. SIE ERSCHEINEN NUR, WENN WIRKLICH PLATZ IST. Gemessen wird nicht die Fensterbreite, sondern der Rest neben dem Bild: Ein hohes Foto auf einem Telefon fuellt den Schirm, und ein Husky, der darueberliegt, waere keine Zierde, sondern ein Hindernis. SIE SIND LEISE. `aria-hidden` -- ein Vorleseprogramm soll nicht „Grafik Husky" sagen, wenn jemand ein Foto ansehen will. Und sie liegen HINTER dem Bild, nie darauf. ===================================================================== */ (function () { 'use strict'; var schau = null; // das , einmal gebaut und wiederverwendet var teile = null; // { bild, name, tab, husky, hase, oben, unten } var zurueck = null; // wohin der Fokus nach dem Schliessen gehoert function el(art, klasse, text) { var e = document.createElement(art); if (klasse) e.className = klasse; if (text != null) e.textContent = text; return e; } function bauen() { if (schau) return; schau = document.createElement('dialog'); schau.className = 'bildschau'; schau.setAttribute('aria-label', 'Bild ansehen'); /* DER HINTERGRUND IST EIN EIGENES STUECK und nicht der Grund des Dialogs: Er soll sich unabhaengig vom Inhalt bewegen duerfen (Verlauf, Schleier, Koernung), ohne dass der Inhalt etwas davon erbt. */ var grund = el('div', 'bildschau__grund'); grund.setAttribute('aria-hidden', 'true'); schau.appendChild(grund); /* Die Begleiter liegen HINTER dem Bild -- eigene Ebene, damit das Bild in jedem Fall obenauf ist. */ var husky = el('img', 'bildschau__figur bildschau__figur--links'); husky.src = 'assets/img/schau-husky.webp'; husky.alt = ''; husky.setAttribute('aria-hidden', 'true'); husky.loading = 'lazy'; husky.decoding = 'async'; var hase = el('img', 'bildschau__figur bildschau__figur--rechts'); hase.src = 'assets/img/schau-hase.webp'; hase.alt = ''; hase.setAttribute('aria-hidden', 'true'); hase.loading = 'lazy'; hase.decoding = 'async'; schau.appendChild(husky); schau.appendChild(hase); /* Die zwei Schriftzuege fuers Querformat. */ var oben = el('div', 'bildschau__wort bildschau__wort--oben'); oben.setAttribute('aria-hidden', 'true'); var zeichen = el('img', 'bildschau__zeichen'); zeichen.src = 'assets/img/marke-husky.webp'; zeichen.alt = ''; oben.appendChild(zeichen); oben.appendChild(el('span', 'bildschau__wort-text', 'DogFather')); var unten = el('div', 'bildschau__wort bildschau__wort--unten'); unten.setAttribute('aria-hidden', 'true'); unten.appendChild(el('span', 'bildschau__wort-text', 'Team Dogi')); schau.appendChild(oben); schau.appendChild(unten); var buehne = el('div', 'bildschau__buehne'); var bild = el('img', 'bildschau__bild'); bild.alt = ''; buehne.appendChild(bild); schau.appendChild(buehne); /* Die Leiste steht OBEN und nicht ueber dem Bild: Sie soll erreichbar sein, ohne etwas zu verdecken. */ var leiste = el('div', 'bildschau__leiste'); var name = el('span', 'bildschau__name'); var tab = el('a', 'bildschau__knopf', 'Im Tab öffnen'); tab.target = '_blank'; tab.rel = 'noopener noreferrer'; var zu = el('button', 'bildschau__knopf bildschau__zu'); zu.type = 'button'; zu.setAttribute('aria-label', 'Bild schließen'); zu.title = 'Schließen (Esc)'; zu.textContent = '✕'; zu.addEventListener('click', function () { schau.close(); }); leiste.appendChild(name); leiste.appendChild(tab); leiste.appendChild(zu); schau.appendChild(leiste); /* EIN KLICK NEBEN DAS BILD SCHLIESST. Das erwartet jeder, der schon einmal ein Foto angesehen hat. Ein Klick AUF das Bild nicht -- sonst schliesst es sich, waehrend man hineinzoomt. */ schau.addEventListener('click', function (e) { if (e.target === schau || e.target === grund || e.target === buehne) schau.close(); }); schau.addEventListener('close', function () { /* Die Quelle loesen: Ein grosses Foto im Speicher zu halten, nachdem niemand es mehr ansieht, ist Last ohne Zweck. */ teile.bild.removeAttribute('src'); if (zurueck && document.contains(zurueck)) { try { zurueck.focus(); } catch (f) { /* egal */ } } zurueck = null; }); document.body.appendChild(schau); teile = { bild: bild, name: name, tab: tab, husky: husky, hase: hase, oben: oben, unten: unten }; } /** Hoch, quer oder fast quadratisch -- und ist ueberhaupt Platz? * * GEMESSEN WIRD DER REST NEBEN DEM BILD, nicht die Fensterbreite. * Eine Schwelle wie „ab 1100 px zeigen" waere eine Rechnung von * gestern: Sie stimmt fuer ein 3:4-Foto und ist bei einem 9:16-Foto * auf demselben Schirm falsch. Dieses Haus ist an festen Breiten * schon dreimal hereingefallen. */ function lageBestimmen(b, h) { if (!(b > 0 && h > 0)) return 'keine'; var fb = window.innerWidth, fh = window.innerHeight; /* So gross wird das Bild: es passt in 92 % Breite und 82 % Hoehe. */ var masz = Math.min(fb * 0.92 / b, (fh * 0.82) / h); var zb = b * masz, zh = h * masz; var restSeite = (fb - zb) / 2; var restOben = (fh - zh) / 2; if (h > b * 1.05) { /* Eine Figur braucht rund 170 px, damit sie eine Figur ist und kein Streifen. Weniger, und sie steht besser gar nicht da. */ return restSeite >= 170 ? 'hoch' : 'keine'; } if (b > h * 1.05) { /* Ein Schriftzug braucht rund 70 px Luft -- darunter klebt er am Bildrand und sieht aus wie ein Versehen. */ return restOben >= 70 ? 'quer' : 'keine'; } return restOben >= 70 ? 'quer' : 'keine'; } function lageSetzen() { if (!schau || !schau.open) return; var b = teile.bild.naturalWidth, h = teile.bild.naturalHeight; schau.dataset.lage = lageBestimmen(b, h); } /** Ein Bild gross ansehen. * @param {{weg:string,name:string}} a das Bild * @param {Element} [woher] wohin der Fokus zurueckgeht */ function zeigen(a, woher) { if (!a || !a.weg) return; bauen(); zurueck = woher || document.activeElement; teile.bild.src = a.weg; teile.bild.alt = a.name || 'Foto'; teile.name.textContent = a.name || ''; teile.tab.href = a.weg; schau.dataset.lage = 'keine'; /* ERST WENN DAS BILD DA IST, steht sein Format fest. Vorher sind naturalWidth und naturalHeight null -- und „null zu null" waere weder hoch noch quer. Liegt es schon im Zwischenspeicher, ist `complete` sofort wahr und die Zeile darunter greift. */ teile.bild.onload = lageSetzen; if (teile.bild.complete) lageSetzen(); if (!schau.open) schau.showModal(); } /* Dreht jemand das Telefon oder zieht das Fenster kleiner, aendert sich der Platz -- und damit die Antwort auf „passt eine Figur daneben". */ window.addEventListener('resize', lageSetzen); window.Bildschau = { zeigen: zeigen }; })();