From 7dd6cb991d21b80a2dc950dd31cdb5871a58e0b3 Mon Sep 17 00:00:00 2001 From: Claude Code Date: Sun, 12 Apr 2026 19:34:52 +0200 Subject: [PATCH] refactor: Hero-Slider auf opacity-Stacking, Video pro Slide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - visibility:hidden aus Slide-States entfernt (brach Video-Playback) - #hero-video-container + Sonderfall-Logik für Slide 0 entfernt - Video in Slide 0 inline verschoben, generische Restart-Logik - Videos starten bei jedem Slide-Wechsel bei 0:00 (bewusste Verhaltensänderung gegenüber 9df30bc) - Autoplay-Intervall auf 15s vereinheitlicht (kein Video/Text-Sonderfall) - Hover-Pause des Sliders entfernt (stoppte Autoplay unerwartet) - Neue Videos in weiteren Slides erfordern jetzt nur HTML-Block + src Co-Authored-By: Claude Opus 4.6 (1M context) --- vorschau/css/style.css | 11 +++++------ vorschau/index.html | 11 +++++------ vorschau/js/app.js | 42 +++++++++++++++++++++++------------------- 3 files changed, 33 insertions(+), 31 deletions(-) diff --git a/vorschau/css/style.css b/vorschau/css/style.css index 2e23721..e486897 100644 --- a/vorschau/css/style.css +++ b/vorschau/css/style.css @@ -79,8 +79,8 @@ a { color:inherit; text-decoration:none; } .hero-tagline { font-size:1.05rem; font-weight:300; color:rgba(255,255,255,0.6); margin-top:8px; } .hero-slider { position:relative; } -.hero-slide { position:absolute; top:0; left:0; width:100%; opacity:0; transform:translateY(12px); transition:opacity 0.6s ease, transform 0.6s ease; pointer-events:none; visibility:hidden; } -.hero-slide.active { position:relative; opacity:1; transform:translateY(0); pointer-events:auto; visibility:visible; } +.hero-slide { position:absolute; top:0; left:0; width:100%; opacity:0; transform:translateY(12px); transition:opacity 0.6s ease, transform 0.6s ease; pointer-events:none; } +.hero-slide.active { position:relative; opacity:1; transform:translateY(0); pointer-events:auto; } .hero-slide.exiting { opacity:0; transform:translateY(-12px); transition:opacity 0.4s ease, transform 0.4s ease; } .hero-slide-inner { display:flex; gap:40px; align-items:flex-start; } @@ -104,10 +104,9 @@ a { color:inherit; text-decoration:none; } .hero-arrow { width:36px; height:36px; border-radius:50%; border:1px solid rgba(255,255,255,0.3); background:transparent; color:var(--white); font-size:1rem; cursor:pointer; display:flex; align-items:center; justify-content:center; transition:all 0.2s; } .hero-arrow:hover { border-color:var(--gold); color:var(--gold); } -/* ==================== HERO VIDEO CONTAINER ==================== */ -.hero-video-container { width:100%; border-radius:var(--radius-lg); overflow:hidden; margin-bottom:16px; transition:opacity 0.6s ease, max-height 0.6s ease; max-height:700px; } -.hero-video-container video { display:block; width:100%; height:auto; } -.hero-video-container.hidden { opacity:0; max-height:0; margin-bottom:0; pointer-events:none; } +/* ==================== HERO SLIDE VIDEO ==================== */ +.hero-slide-video { width:100%; border-radius:var(--radius-lg); overflow:hidden; margin-bottom:16px; } +.hero-slide-video video { display:block; width:100%; height:auto; } .hero-slide-bottom { } /* ==================== BUTTONS ==================== */ diff --git a/vorschau/index.html b/vorschau/index.html index 87da8e4..bdd5f4d 100644 --- a/vorschau/index.html +++ b/vorschau/index.html @@ -87,15 +87,14 @@

KI-gestützte Echtzeit-Lagebilder aus offenen Quellen, vollautomatisch.

-
- -
-
+
+ +

Live-Beispiel: Der Iran-Konflikt wird mit über 14.900 Artikeln aus 375 Quellen kontinuierlich überwacht.

diff --git a/vorschau/js/app.js b/vorschau/js/app.js index 97a3977..db22b0e 100644 --- a/vorschau/js/app.js +++ b/vorschau/js/app.js @@ -46,12 +46,20 @@ var heroDots = document.querySelectorAll('.hero-dot'); var heroCurrentSlide = 0; var heroTimer = null; - var HERO_INTERVAL = 8000; - var HERO_INTERVAL_VIDEO = 15000; + var HERO_INTERVAL = 15000; var heroIsTransitioning = false; - function heroGetInterval() { - return heroCurrentSlide === 0 ? HERO_INTERVAL_VIDEO : HERO_INTERVAL; + function heroPlaySlideVideo(slide) { + var v = slide && slide.querySelector('video'); + if (!v) return; + try { v.currentTime = 0; } catch (err) { /* ignore */ } + var p = v.play(); + if (p && typeof p.catch === 'function') p.catch(function () { /* autoplay blocked */ }); + } + + function heroPauseSlideVideo(slide) { + var v = slide && slide.querySelector('video'); + if (v) v.pause(); } function heroGoTo(index) { @@ -63,23 +71,19 @@ heroSlides[oldIndex].classList.remove('active'); if (heroDots[oldIndex]) heroDots[oldIndex].classList.remove('active'); - var vc = document.getElementById('hero-video-container'); - if (vc) { - vc.classList.toggle('hidden', index !== 0); - var vid = vc.querySelector('video'); - if (vid) { - if (index === 0) vid.play(); - else vid.pause(); - } - } + // Altes Video sofort pausieren, damit es während des Fade-Outs nicht mehr läuft + heroPauseSlideVideo(heroSlides[oldIndex]); setTimeout(function () { heroSlides[oldIndex].classList.remove('exiting'); heroCurrentSlide = index; heroSlides[heroCurrentSlide].classList.add('active'); if (heroDots[heroCurrentSlide]) heroDots[heroCurrentSlide].classList.add('active'); - heroIsTransitioning = false; + // Neues Video von Anfang starten, sobald der Slide sichtbar wird + heroPlaySlideVideo(heroSlides[heroCurrentSlide]); + + heroIsTransitioning = false; }, 400); } @@ -95,8 +99,8 @@ heroStopAutoplay(); heroTimer = setTimeout(function tick() { heroNext(); - heroTimer = setTimeout(tick, heroGetInterval()); - }, heroGetInterval()); + heroTimer = setTimeout(tick, HERO_INTERVAL); + }, HERO_INTERVAL); } function heroStopAutoplay() { @@ -117,9 +121,6 @@ var heroSlider = document.querySelector('.hero-slider'); if (heroSlider) { - heroSlider.addEventListener('mouseenter', heroStopAutoplay); - heroSlider.addEventListener('mouseleave', heroStartAutoplay); - var heroTouchStartX = 0; heroSlider.addEventListener('touchstart', function (e) { heroTouchStartX = e.changedTouches[0].screenX; @@ -141,6 +142,9 @@ if (heroSlides.length > 1) heroStartAutoplay(); + // Initialer Video-Start für Slide 0 (ersetzt das weggefallene autoplay-Attribut) + if (heroSlides.length) heroPlaySlideVideo(heroSlides[0]); + /* ==================== MAP STATE ==================== */ var mapInstance = null; var markerLayer = null;