{
 "$schema": "../../schema.json",
 "schema": "fundus/1",
 "id": "clip-path-bild-reveal",
 "name": "Bild-Reveal per Clip-Path/Maske",
 "name_en": "Clip-path / mask image reveal on scroll",
 "kurz": "Bilder öffnen sich wie eine Blende: die Maske wächst, das Bild darin zoomt gegenläufig zurück. Tiefe ohne 3D.",
 "kategorie": "Scroll & Section-Animationen",
 "kategorie_slug": "scroll",
 "kategorie_nr": 5,
 "bau_chat": "C2",
 "prioritaet": "A",
 "trendstatus": "etabliert",
 "belegstatus": "belegt",
 "website_belege": 4,
 "stimmung": [
  "ruhig",
  "editorial",
  "luxuriös",
  "filmisch"
 ],
 "stimmung_roh": [
  "editorial",
  "luxuriös",
  "filmisch",
  "ruhig"
 ],
 "technik": [
  "css",
  "scroll-driven-css",
  "gsap",
  "scrolltrigger",
  "svg"
 ],
 "technik_gruppen": [
  "css",
  "gsap",
  "canvas"
 ],
 "leistungskosten": "niedrig",
 "steckbrief": {
  "beschreibung": "1) Bilder starten beschnitten: als schmaler Schlitz in der Mitte, als Vorhang von unten oder als kleine Kapsel. 2) Beim Scrollen öffnet sich die Maske auf volle Größe. 3) Gleichzeitig zoomt das Bild darin von 1,25 auf 1 zurück, diese Gegenbewegung erzeugt Tiefe. 4) Entweder an den Scroll gekoppelt (die Maske folgt dem Daumen) oder einmalig beim Eintritt, mit langer, stark ausklingender Kurve.",
  "warum_es_wirkt": "Wie das Öffnen einer Blende oder eines Vorhangs: gerichteter und hochwertiger als ein Einblenden. Das Bild entsteht, statt nur aufzutauchen. clip-path ist auf ausgezeichneten Seiten das Reveal-Werkzeug Nummer eins (Messung: Lando Norris 130 Elemente, Obys 40).",
  "wann_einsetzen": "Hero- und Projektbilder, Editorial-Strecken, Fallstudien, Galerien mit wenigen großen Bildern.",
  "wann_nicht": "Bei Logos, kleinen Vorschaubildern und Icons. Wenn viele Bilder gleichzeitig im Bild stehen, wird es unruhig: dann gestaffelt oder gar nicht.",
  "varianten": [
   "Schlitz aus der Mitte (inset symmetrisch)",
   "Vorhang von unten/links (inset einseitig)",
   "Abgerundete Kapsel wächst zum Rechteck (inset(... round 999px) → round 0)",
   "Polygon-Diagonale / Wipe",
   "SVG-Maske mit Form (Kreis, Logo-Silhouette)",
   "Gestaffeltes Raster: Kacheln öffnen nacheinander"
  ],
  "umsetzung": "Rahmen mit overflow: hidden, darauf clip-path; das Bild darin bekommt scale. Gekoppelt rein in CSS: .rahmen { animation: oeffnen linear both; animation-timeline: view(); animation-range: entry 10% cover 48% } und @keyframes oeffnen { from { clip-path: var(--start) } to { clip-path: var(--ende) } }. Das in @supports (animation-timeline: view()) setzen, sonst bleibt das Bild offen. Einmalig: IntersectionObserver setzt bei 33 % Sichtbarkeit eine Klasse, clip-path und scale laufen per transition 1,6 s expo.out. Mit GSAP: gsap.fromTo(el, { clipPath: 'inset(100% 0% 0% 0%)' }, { clipPath: 'inset(0% 0% 0% 0%)', duration: 1.6, ease: 'expo.out', scrollTrigger: { trigger: el, start: 'top 80%' } }).\n\nFallstrick: Start- und Endform müssen gleich aufgebaut sein, sonst wird nicht interpoliert. inset mit round braucht round auf beiden Seiten, Prozentwerte überall.",
  "mobil": "Funktioniert unverändert. Bereich früher beginnen lassen (entry 10 %), damit Bilder auf kurzen Bildschirmen nicht halb verdeckt stehen; Hochformat-Ausschnitt nutzen.",
  "reduzierte_bewegung": "Bild sofort ganz zeigen, höchstens 200–300 ms einblenden.",
  "barrierefreiheit": "Alt-Text bleibt unverändert. Das Bild darf nie verdeckt bleiben, wenn die Animation nicht läuft: Startzustand nur innerhalb von @supports bzw. per JavaScript-Klasse setzen."
 },
 "messwerte": {
  "easing": "expo.out (Cuberto), expo.inOut (Rejouice, Monavon), power2.inOut (OFF+BRAND)",
  "dauer_ms": "2500 (Cuberto), 1800 (Rejouice), 1150 (Monavon), 1500 (OFF+BRAND)",
  "stagger_ms": "80–120 bei Rastern",
  "distanz": "inset(5% 10% round 2rem) → 0, scale .9 → 1 (Cuberto)",
  "sonstiges": "Gegenbewegung innen: scale 1.2 → 1 und rotate 30° → 0 (Rejouice)",
  "herkunft": "beobachtet",
  "quelle": "https://cuberto.com/_astro/index.astro_astro_type_script_index_0_lang.XzcFPccV.js?dpl=dpl_9QJjpNzTFmS7yqLWqVJudUB2bNRP"
 },
 "kurve": {
  "bezier": [
   0.16,
   1,
   0.3,
   1
  ],
  "css": "cubic-bezier(0.16, 1, 0.3, 1)",
  "name": "expo.out",
  "dauer_ms": 1600
 },
 "gesehen_bei": [
  {
   "seite": "scroll-driven-animations.style – Image Reveal Effects",
   "url": "https://scroll-driven-animations.style/demos/image-reveal/css/",
   "auszeichnung": "",
   "beobachtung": "opacity 0 + clip-path: inset(45% 20% 45% 20%) → inset(0); animation-range: entry 25% cover 50%.",
   "art": "demo"
  },
  {
   "seite": "Zentry",
   "url": "https://zentry.com",
   "auszeichnung": "Awwwards SOTD + Developer Award (Animations/Transitions 8,20), Datum auf Awwwards-Seite nicht angezeigt",
   "beobachtung": "Aus Erinnerung (unsicher): Hero-Video in einem Polygon-Clip-Path-Rahmen, der sich beim Scrollen zum Vollbild öffnet; statischer Abruf zeigte keinen Beleg.",
   "art": "website-ungeprueft",
   "browser_gemessen": true
  },
  {
   "seite": "Olivier Larose – Mask Section Transition",
   "url": "https://blog.olivierlarose.com/tutorials/mask-section-transition",
   "auszeichnung": "",
   "beobachtung": "SVG-Masken-Übergang, inspiriert von axelvanhessche.com (Tutorial-Inhalt gesperrt, nur Beschreibung gelesen).",
   "art": "artikel"
  },
  {
   "seite": "Cuberto",
   "url": "https://cuberto.com/",
   "auszeichnung": "",
   "beobachtung": "Live geprüft (index…XzcFPccV.js): Medien beim Eintreten clipPath inset(5% 10% round 2rem) + scale .9 → inset(0% 0% round 2rem) + scale 1, expo.out 2.5s, Fade 1s.",
   "art": "website",
   "browser_gemessen": true
  },
  {
   "seite": "OFF+BRAND",
   "url": "https://www.itsoffbrand.com/",
   "auszeichnung": "",
   "beobachtung": "Live geprüft (ob.2026.index.23.js): [case-hero-img] von clipPath inset(0% 0% 100% 0%) und x 10em auf inset(0) und x 0, 1.5s power2.inOut, Verzögerung 1.5s.",
   "art": "website",
   "browser_gemessen": true
  },
  {
   "seite": "Rejouice",
   "url": "https://www.rejouice.com/",
   "auszeichnung": "",
   "beobachtung": "Live geprüft (BdSAQIjB.js): Video-Rahmen clipPath inset(50%) + rotate -30° → inset(0%) + rotate 0, Video innen rotate 30° + scale 1.2 → 0 / 1, expo.inOut 1.8s.",
   "art": "website"
  },
  {
   "seite": "Thomas Monavon",
   "url": "https://www.thomasmonavon.com/",
   "auszeichnung": "",
   "beobachtung": "Live geprüft (CiM0B-8B.js): Projektmedien clipPath → inset(0%) expo.inOut 1.15s, Innenbild scale → 1 power4.inOut 1s.",
   "art": "website"
  }
 ],
 "tutorials": [
  {
   "titel": "Image Reveal (CSS)",
   "url": "https://scroll-driven-animations.style/demos/image-reveal/css/"
  },
  {
   "titel": "Scroll-triggered Animations – Karten-Unclip-Beispiel",
   "url": "https://developer.chrome.com/blog/scroll-triggered-animations"
  }
 ],
 "kombinierbar_mit": [
  "split-mask-reveal",
  "mehrschicht-parallax",
  "stapelkarten"
 ],
 "urls": {
  "detail": "https://cecodesign.de/lab/fundus/scroll/clip-path-bild-reveal/",
  "meta": "https://cecodesign.de/lab/fundus/scroll/clip-path-bild-reveal/meta.json",
  "demo": "https://cecodesign.de/lab/fundus/scroll/clip-path-bild-reveal/demo"
 },
 "herkunft": {
  "quelldateien": [
   "scroll.json",
   "patch-belege-3.json"
  ],
  "pruefnotizen": [
   "patch-belege-3.json: Vier Produktionsbelege."
  ]
 },
 "bau": {
  "status": "fertig",
  "kurz": "Bilder öffnen sich wie eine Blende: die Maske wächst, das Bild darin zoomt gegenläufig zurück. Tiefe ohne 3D.",
  "demo": true,
  "abhaengigkeiten": [],
  "werte": {
   "easing": "gekoppelt: linear (Scroll ist die Zeit) · einmalig: expo.out = cubic-bezier(0.16, 1, 0.3, 1)",
   "dauer_ms": "einmalig: Maske 1600, Bild 1800",
   "bereich": "animation-range: entry 10% cover 48% (Maske), entry 0% cover 55% (Bild)",
   "distanz": "Schlitz inset(45% 20%) · Vorhang inset(100% 0 0 0) · Kapsel inset(30% 32% round 999px) → round 14px",
   "bild": "scale 1,25 → 1",
   "schwelle": "einmalig: 33 % sichtbar"
  },
  "ausloeser": "scroll",
  "touch": "Unverändert; auf schmalen Bildschirmen Hochformat 4:5. Der Bereich beginnt früh (entry 10 %), damit nichts halb verdeckt stehen bleibt.",
  "reduziert": "Keine Maske, kein Zoom: das Bild ist ganz da und blendet beim Eintritt in 250 ms ein.",
  "korrekturen": {
   "beschreibung": "1) Bilder starten beschnitten: als schmaler Schlitz in der Mitte, als Vorhang von unten oder als kleine Kapsel. 2) Beim Scrollen öffnet sich die Maske auf volle Größe. 3) Gleichzeitig zoomt das Bild darin von 1,25 auf 1 zurück, diese Gegenbewegung erzeugt Tiefe. 4) Entweder an den Scroll gekoppelt (die Maske folgt dem Daumen) oder einmalig beim Eintritt, mit langer, stark ausklingender Kurve.",
   "warum_es_wirkt": "Wie das Öffnen einer Blende oder eines Vorhangs: gerichteter und hochwertiger als ein Einblenden. Das Bild entsteht, statt nur aufzutauchen. clip-path ist auf ausgezeichneten Seiten das Reveal-Werkzeug Nummer eins (Messung: Lando Norris 130 Elemente, Obys 40).",
   "wann_einsetzen": "Hero- und Projektbilder, Editorial-Strecken, Fallstudien, Galerien mit wenigen großen Bildern.",
   "wann_nicht": "Bei Logos, kleinen Vorschaubildern und Icons. Wenn viele Bilder gleichzeitig im Bild stehen, wird es unruhig: dann gestaffelt oder gar nicht.",
   "umsetzung": "Rahmen mit overflow: hidden, darauf clip-path; das Bild darin bekommt scale. Gekoppelt rein in CSS: .rahmen { animation: oeffnen linear both; animation-timeline: view(); animation-range: entry 10% cover 48% } und @keyframes oeffnen { from { clip-path: var(--start) } to { clip-path: var(--ende) } }. Das in @supports (animation-timeline: view()) setzen, sonst bleibt das Bild offen. Einmalig: IntersectionObserver setzt bei 33 % Sichtbarkeit eine Klasse, clip-path und scale laufen per transition 1,6 s expo.out. Mit GSAP: gsap.fromTo(el, { clipPath: 'inset(100% 0% 0% 0%)' }, { clipPath: 'inset(0% 0% 0% 0%)', duration: 1.6, ease: 'expo.out', scrollTrigger: { trigger: el, start: 'top 80%' } }).\n\nFallstrick: Start- und Endform müssen gleich aufgebaut sein, sonst wird nicht interpoliert. inset mit round braucht round auf beiden Seiten, Prozentwerte überall.",
   "mobil": "Funktioniert unverändert. Bereich früher beginnen lassen (entry 10 %), damit Bilder auf kurzen Bildschirmen nicht halb verdeckt stehen; Hochformat-Ausschnitt nutzen.",
   "reduzierte_bewegung": "Bild sofort ganz zeigen, höchstens 200–300 ms einblenden.",
   "barrierefreiheit": "Alt-Text bleibt unverändert. Das Bild darf nie verdeckt bleiben, wenn die Animation nicht läuft: Startzustand nur innerhalb von @supports bzw. per JavaScript-Klasse setzen."
  },
  "geprueft": "31.10.2026",
  "notiz": "Pilot aus Chat B. Scroll-gekoppelt nur in Browsern mit animation-timeline (Chrome/Edge, Safari 26); sonst automatisch einmalig. Bilder 01.11.2026: eigene Bilder statt Portfolio."
 }
}
