/** * Video-Hero Trial — nur auf Home: Header → Hero → Video → Inhalt. * Handy + Tablet: kein Video. Nur Desktop/Laptop. Unterseiten: kein Video. */ (function () { "use strict"; var VER = "20260710fix3"; var ENABLED = true; var mqNoVideo = window.matchMedia("(max-width: 1024px)"); var prefetched = {}; var homeObserver = null; var lastSlide = ""; var restartTimer = 0; var restartPending = false; var initialRevealDone = false; var heroReadyForVideo = false; var enterAt = 0; var WORLD_MAP = { general: "multiversum", nexora: "nexora", vertex: "professional", freiraum: "freiraum", }; var MV_NAV_FALLBACK = [ { id: "home", label: "Home" }, { id: "projects", label: "Projekte" }, { id: "leistungen", label: "Leistungen" }, { id: "about", label: "Über mich" }, { id: "contact", label: "Kontakt" }, { id: "offerte", label: "Offerte" }, ]; var WORLDS = { multiversum: { label: "Multiversum", poster: "assets/videos/multiversum-poster.jpg", src: "assets/videos/multiversum-hero.mp4", }, nexora: { label: "Nexora", poster: "assets/videos/nexora-poster.jpg", src: "assets/videos/nexora-hero.mp4", }, professional: { label: "Professional", poster: "assets/videos/professional-poster.jpg", src: "assets/videos/professional-hero.mp4", }, freiraum: { label: "Freiraum", poster: "assets/videos/freiraum-poster.jpg", src: "assets/videos/freiraum-hero.mp4", }, }; function isEmbedded() { try { return window.parent !== window; } catch (e) { return true; } } var frameLive = !isEmbedded(); var frameVisible = !isEmbedded(); var gotWorldSignal = false; function isParentActiveFrame() { if (!isEmbedded()) return true; try { var parentFrames = window.parent.document.querySelectorAll(".mv4-frame"); for (var i = 0; i < parentFrames.length; i++) { if (parentFrames[i].contentWindow === window && parentFrames[i].classList.contains("is-active")) { return true; } } } catch (e) {} return false; } function tryEmbeddedInitialReveal() { if (!isEmbedded() || gotWorldSignal || isVideoHidden()) return; if (!isParentActiveFrame()) return; frameLive = true; frameVisible = true; mountVideoHero(); } function isVideoHidden() { return mqNoVideo.matches; } function pickVideoSrc(worldKey) { var w = WORLDS[worldKey]; return w ? w.src : ""; } function isHomeActive() { var slideHome = document.getElementById("slide-home"); if (!slideHome) return false; if (slideHome.classList.contains("active")) return true; var current = document.body.getAttribute("data-current-slide"); return !current || current === "home"; } function canPlayVideo() { if (frameLive && frameVisible && isHomeActive() && !isVideoHidden()) { try { if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return false; } catch (e) {} return true; } return false; } function getHomeInner() { var slideHome = document.getElementById("slide-home"); return slideHome && slideHome.querySelector(".slide-inner"); } function prefetchVideo(worldKey) { if (!frameLive || !heroReadyForVideo) return; var src = pickVideoSrc(worldKey); if (!src || prefetched[src]) return; prefetched[src] = true; var link = document.createElement("link"); link.rel = "preload"; link.as = "video"; link.href = src; link.type = "video/mp4"; document.head.appendChild(link); } function removeVideoHero() { var hero = document.getElementById("alWorldVideoHero"); if (hero) hero.remove(); document.body.removeAttribute("data-welten-video-hero"); } function getVideoEl() { var section = document.getElementById("alWorldVideoHero"); return section && section.querySelector("video"); } function resetVideoEl(video) { if (!video) return; try { video.pause(); video.currentTime = 0; } catch (e) {} } function pauseVideoHero() { resetVideoEl(getVideoEl()); } function markVideoReady(section, video) { if (!section || !video) return; section.classList.add("is-video-ready"); video.style.opacity = "1"; } function isVideoPlaying(video) { if (!video) return false; return !video.paused && !video.ended && video.readyState > 2 && video.currentTime > 0.12; } function restartAndPlay(force) { if (!canPlayVideo()) { pauseVideoHero(); return; } var section = document.getElementById("alWorldVideoHero"); var video = section && section.querySelector("video"); if (!video) return; if (!force && isVideoPlaying(video) && section.classList.contains("is-video-ready")) { return; } if (!force && restartPending) return; restartPending = true; if (restartTimer) window.clearTimeout(restartTimer); restartTimer = window.setTimeout(function () { restartPending = false; restartTimer = 0; restartAndPlayNow(); }, force ? 0 : 120); } function restartAndPlayNow() { if (!canPlayVideo()) { pauseVideoHero(); return; } var section = document.getElementById("alWorldVideoHero"); var video = section && section.querySelector("video"); if (!video) return; if (isVideoPlaying(video) && section.classList.contains("is-video-ready")) { return; } var needsHardReset = !video.getAttribute("src") || video.error; if (!video.getAttribute("src")) { var worldKey = WORLD_MAP[document.body.getAttribute("data-world") || ""]; var src = pickVideoSrc(worldKey); if (src) video.setAttribute("src", src); } if (needsHardReset) { section.classList.remove("is-video-ready"); video.style.opacity = "0"; resetVideoEl(video); } video.preload = "auto"; video.muted = true; video.volume = 0; var started = false; function tryPlay() { if (started || !canPlayVideo()) return; started = true; if (needsHardReset) resetVideoEl(video); video.muted = true; video.volume = 0; var promise = video.play(); if (promise && typeof promise.then === "function") { promise .then(function () { markVideoReady(section, video); }) .catch(function (err) { started = false; try { section.classList.add("is-poster-fallback"); section.classList.remove("is-video-ready"); video.style.opacity = "0"; } catch (eVis) {} if (typeof console !== "undefined" && console.warn) { console.warn("[welten-video-hero] Autoplay blocked or failed", err); } }); } else { markVideoReady(section, video); } } if (video.readyState >= 2) { tryPlay(); return; } video.addEventListener("canplay", tryPlay, { once: true }); if (needsHardReset) { try { video.load(); } catch (eLoad) {} } window.setTimeout(function () { if (!started && video.readyState >= 2) tryPlay(); }, 400); } function getMvNavItems() { var items = []; document.querySelectorAll(".experience-step[data-go]").forEach(function (btn) { var id = btn.getAttribute("data-go"); if (!id) return; items.push({ id: id, label: btn.getAttribute("data-label") || btn.textContent.trim(), }); }); return items.length ? items : MV_NAV_FALLBACK; } function navigateChapter(id) { if (!id) return; var step = document.querySelector('.experience-step[data-go="' + id + '"]'); if (step) { step.click(); return; } if (window.WeltenSiteIA && typeof window.WeltenSiteIA.navigateToChapter === "function") { window.WeltenSiteIA.navigateToChapter(id); return; } var link = document.querySelector('.menu-links a[data-go="' + id + '"]'); if (link) link.click(); } function syncMvVideoChromeNav() { var section = document.getElementById("alWorldVideoHero"); if (!section || !section.classList.contains("al-world-video-hero--multiversum")) return; var current = document.body.getAttribute("data-current-slide") || "home"; section.querySelectorAll(".mv-static-hero__nav-btn[data-go]").forEach(function (btn) { var on = btn.getAttribute("data-go") === current; btn.classList.toggle("is-active", on); btn.setAttribute("aria-current", on ? "page" : "false"); }); } function bindMvVideoChromeNav(section) { if (!section || section.getAttribute("data-mv-chrome-bound") === "1") return; section.setAttribute("data-mv-chrome-bound", "1"); section.querySelectorAll(".mv-static-hero__nav-btn[data-go]").forEach(function (btn) { btn.addEventListener("click", function (e) { e.preventDefault(); e.stopPropagation(); navigateChapter(btn.getAttribute("data-go")); }); }); syncMvVideoChromeNav(); } function buildMvVideoChromeHtml() { var navHtml = getMvNavItems() .map(function (item) { return ( '" ); }) .join(""); var inShell = document.documentElement.classList.contains("mv-in-shell") || document.documentElement.classList.contains("welten-live-shell"); /* Im Shell bereits .site-header — kein zweites MULTIVERSUM-Title-Banner */ var brandHtml = inShell ? "" : '

Alex Lamberti · Portfolio

' + '

MULTIVERSUM

'; return ( '
' + '
' + brandHtml + '
" ); } function ensureMvVideoChrome(section, worldKey) { if (!section || worldKey !== "multiversum") return; if (section.querySelector(".al-world-video-hero__chrome")) { bindMvVideoChromeNav(section); syncMvVideoChromeNav(); return; } section.classList.add("al-world-video-hero--with-chrome"); var media = section.querySelector(".al-world-video-hero__media"); if (!media) return; var wrap = document.createElement("div"); wrap.innerHTML = buildMvVideoChromeHtml(); var chrome = wrap.firstElementChild; section.insertBefore(chrome, media); bindMvVideoChromeNav(section); } function refreshWorldHeroNav(worldKey) { if (!worldKey || worldKey === "multiversum") return; window.setTimeout(function () { if (worldKey === "nexora") { if (window.NexoraOrbitUI && typeof window.NexoraOrbitUI.init === "function") { window.NexoraOrbitUI.init(); } else { try { document.dispatchEvent(new CustomEvent("welten-nexora-orbit-init")); } catch (eOrbit) {} } if (window.NexoraOrbitUI && typeof window.NexoraOrbitUI.snapToChapter === "function") { window.NexoraOrbitUI.snapToChapter( document.body.getAttribute("data-current-slide") || "home" ); } } if (window.WeltenDesktopChapterHero && typeof window.WeltenDesktopChapterHero.refresh === "function") { window.WeltenDesktopChapterHero.refresh(); } }, 80); } function signalVideoHeroMounted(worldKey) { try { document.dispatchEvent( new CustomEvent("welten-video-hero-mounted", { detail: { worldKey: worldKey || "" } }) ); } catch (eMounted) {} try { if (window.parent && window.parent !== window && !window.__mvHeroReadySent) { window.__mvHeroReadySent = true; window.parent.postMessage({ type: "mv-hero-ready" }, "*"); } } catch (eReady) {} refreshWorldHeroNav(worldKey); } function applyMultiversumVideoFit(section) { if (!section || !section.classList.contains("al-world-video-hero--multiversum")) return; var media = section.querySelector(".al-world-video-hero__media"); var video = section.querySelector("video"); if (media) { media.style.overflow = "visible"; media.style.backgroundSize = "contain"; } if (video) { video.style.objectFit = "contain"; video.style.objectPosition = "center center"; video.style.width = "100%"; video.style.height = "auto"; video.style.maxHeight = "clamp(780px, calc((109svh - var(--header-h, 90px) * 0.35) * 1.3), 1200px)"; } } function buildHero(worldKey) { var w = WORLDS[worldKey]; var src = pickVideoSrc(worldKey); var deferSrc = !heroReadyForVideo; var section = document.createElement("section"); section.id = "alWorldVideoHero"; section.className = "al-world-video-hero al-world-video-hero--" + worldKey + " al-world-video-hero--video-only"; section.setAttribute("aria-label", w.label + " Video"); section.innerHTML = (worldKey === "multiversum" ? buildMvVideoChromeHtml() : "") + '
' + '
"; if (worldKey === "multiversum") { section.classList.add("al-world-video-hero--with-chrome"); bindMvVideoChromeNav(section); } applyMultiversumVideoFit(section); var video = section.querySelector("video"); if (video) { video.style.opacity = "0"; video.muted = true; video.defaultMuted = true; video.volume = 0; video.setAttribute("muted", ""); video.setAttribute("webkit-playsinline", ""); video.playsInline = true; video.addEventListener( "playing", function () { markVideoReady(section, video); }, false ); } return section; } function getHeroAnchor() { var homeInner = getHomeInner(); if (!homeInner) return null; return ( homeInner.querySelector("#mvParallaxHero") || homeInner.querySelector("#mvStaticHero") || homeInner.querySelector("#dnaStage") || homeInner.querySelector(".home-hero-experience") ); } function isVideoRelocated(videoHero) { return !!( videoHero && (videoHero.classList.contains("welten-desktop-relocated-hero") || videoHero.classList.contains("is-subpage-hero")) ); } function ensureVideoAfterHero() { var videoHero = document.getElementById("alWorldVideoHero"); var homeInner = getHomeInner(); var anchor = getHeroAnchor(); if (!videoHero || !homeInner) return; /* Unterseiten: Hero wird von chapter-hero relocated — nicht zurück nach Home ziehen */ if (!isHomeActive() || isVideoRelocated(videoHero)) return; if (anchor) { if (anchor.nextElementSibling !== videoHero) { if (anchor.nextSibling) { homeInner.insertBefore(videoHero, anchor.nextSibling); } else { homeInner.appendChild(videoHero); } } return; } if (homeInner.firstElementChild !== videoHero) { homeInner.insertBefore(videoHero, homeInner.firstChild); } } function resetHomeScroll() { var slideHome = document.getElementById("slide-home"); if (!slideHome || !isHomeActive()) return; if (slideHome.scrollTop > 4) slideHome.scrollTop = 0; } function watchHomeInner() { var homeInner = getHomeInner(); if (!homeInner || homeObserver) return; try { homeObserver = new MutationObserver(function () { var videoHero = document.getElementById("alWorldVideoHero"); if (!videoHero) { if (isHomeActive()) mountVideoHero(); return; } if (isHomeActive() && !isVideoRelocated(videoHero)) { ensureVideoAfterHero(); } }); homeObserver.observe(homeInner, { childList: true }); } catch (e) {} } function mountVideoHero() { if (!ENABLED) return; if (isVideoHidden()) { pauseVideoHero(); removeVideoHero(); return; } if (!frameLive) { pauseVideoHero(); return; } var worldKey = WORLD_MAP[document.body.getAttribute("data-world") || ""]; if (!worldKey) return; prefetchVideo(worldKey); var homeInner = getHomeInner(); if (!homeInner) return; var videoHero = document.getElementById("alWorldVideoHero"); /* Bereits fertig gemountet: nur soft sync, kein Remount → kein Header-Flash */ if ( videoHero && videoHero.getAttribute("data-mounted-world") === worldKey && videoHero.querySelector("video") ) { ensureMvVideoChrome(videoHero, worldKey); applyMultiversumVideoFit(videoHero); syncMvVideoChromeNav(); if (canPlayVideo() && !isVideoPlaying(videoHero.querySelector("video"))) { restartAndPlay(); } else if (!canPlayVideo()) { pauseVideoHero(); } return; } document.body.setAttribute("data-welten-video-hero", "1"); if (!videoHero) { videoHero = buildHero(worldKey); var anchor = getHeroAnchor(); if (anchor && anchor.parentNode === homeInner) { if (anchor.nextSibling) { homeInner.insertBefore(videoHero, anchor.nextSibling); } else { homeInner.appendChild(videoHero); } } else { homeInner.appendChild(videoHero); } } else { ensureVideoAfterHero(); var keepRelocated = isVideoRelocated(videoHero); var keepChrome = videoHero.classList.contains("al-world-video-hero--with-chrome"); videoHero.classList.add( "al-world-video-hero", "al-world-video-hero--" + worldKey, "al-world-video-hero--video-only" ); /* className nicht komplett ersetzen — Relocate-/Chrome-Flags behalten */ Array.prototype.slice.call(videoHero.classList).forEach(function (cls) { if ( cls.indexOf("al-world-video-hero") === 0 || cls === "welten-desktop-relocated-hero" || cls === "is-subpage-hero" ) { return; } videoHero.classList.remove(cls); }); if (keepRelocated) { videoHero.classList.add("welten-desktop-relocated-hero", "is-subpage-hero"); } if (keepChrome || worldKey === "multiversum") { videoHero.classList.add("al-world-video-hero--with-chrome"); } ensureMvVideoChrome(videoHero, worldKey); applyMultiversumVideoFit(videoHero); var video = videoHero.querySelector("video"); var nextSrc = pickVideoSrc(worldKey); if (video && nextSrc && video.getAttribute("src") !== nextSrc) { resetVideoEl(video); video.setAttribute("src", nextSrc); video.setAttribute("poster", WORLDS[worldKey].poster); try { video.load(); } catch (eLoad) {} } } if (videoHero) videoHero.setAttribute("data-mounted-world", worldKey); watchHomeInner(); resetHomeScroll(); syncMvVideoChromeNav(); if (canPlayVideo() && !isVideoPlaying(videoHero && videoHero.querySelector("video"))) { restartAndPlay(); } else if (!canPlayVideo()) { pauseVideoHero(); } signalVideoHeroMounted(worldKey); } function onViewportChange() { if (isVideoHidden()) { pauseVideoHero(); removeVideoHero(); return; } mountVideoHero(); } function onSlideChange() { var slide = document.body.getAttribute("data-current-slide") || "home"; if (slide === lastSlide) return; lastSlide = slide; var videoHero = document.getElementById("alWorldVideoHero"); if (!videoHero) return; if (isHomeActive() && !isVideoRelocated(videoHero)) { ensureVideoAfterHero(); } syncMvVideoChromeNav(); if (canPlayVideo()) { resetHomeScroll(); restartAndPlay(slide === "home"); } else { pauseVideoHero(); } if (window.WeltenDesktopChapterHero && typeof window.WeltenDesktopChapterHero.refresh === "function") { window.WeltenDesktopChapterHero.refresh(); } } function onWorldEnter() { gotWorldSignal = true; frameLive = true; frameVisible = false; enterAt = Date.now(); mountVideoHero(); } function onWorldReveal() { gotWorldSignal = true; frameLive = true; frameVisible = true; heroReadyForVideo = true; mountVideoHero(); if (!isVideoPlaying(getVideoEl())) { restartAndPlay(true); } } function onWorldPause() { gotWorldSignal = true; frameLive = false; frameVisible = false; pauseVideoHero(); } function boot() { lastSlide = document.body.getAttribute("data-current-slide") || "home"; if (frameLive) { var worldKey = WORLD_MAP[document.body.getAttribute("data-world") || ""]; if (worldKey) prefetchVideo(worldKey); } onViewportChange(); } function bootOnce() { if (initialRevealDone) return; initialRevealDone = true; heroReadyForVideo = !isEmbedded(); boot(); setTimeout(tryEmbeddedInitialReveal, 200); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", bootOnce); } else { bootOnce(); } window.addEventListener("load", function () { if (!initialRevealDone) bootOnce(); }); if (mqNoVideo.addEventListener) { mqNoVideo.addEventListener("change", onViewportChange); } else if (mqNoVideo.addListener) { mqNoVideo.addListener(onViewportChange); } window.addEventListener("orientationchange", function () { setTimeout(onViewportChange, 120); }); document.addEventListener("welten-chapter-change", function () { setTimeout(onSlideChange, 30); }); window.addEventListener("message", function (e) { if (!e.data) return; if (e.data.type === "portfolio-world-enter") { onWorldEnter(); return; } if (e.data.type === "portfolio-world-reveal") { onWorldReveal(); return; } if (e.data.type === "mv-hero-ready") { heroReadyForVideo = true; mountVideoHero(); return; } if (e.data.type === "portfolio-effects") { setTimeout(tryEmbeddedInitialReveal, 40); return; } if (e.data.type === "portfolio-world-pause" || e.data.type === "portfolio-cleanup-transition") { onWorldPause(); } }); try { lastSlide = document.body.getAttribute("data-current-slide") || "home"; new MutationObserver(function () { onSlideChange(); }).observe(document.body, { attributes: true, attributeFilter: ["data-current-slide"], }); } catch (e) {} document.addEventListener("mv-hero-ready", function () { heroReadyForVideo = true; mountVideoHero(); }); try { var videoHeroClassBound = false; new MutationObserver(function () { if (videoHeroClassBound) return; if ( document.body.getAttribute("data-world") === "general" && (document.body.classList.contains("mv-home-ready") || document.querySelector("#mvParallaxHero.is-boot-painted")) ) { videoHeroClassBound = true; heroReadyForVideo = true; mountVideoHero(); } }).observe(document.body, { attributes: true, attributeFilter: ["class"], }); } catch (e2) {} window.WeltenVideoHero = { version: VER, remount: boot, prefetch: prefetchVideo, ensureOnTop: ensureVideoAfterHero, restart: restartAndPlay, getOffset: function () { return 0; }, }; })();