[{"data":1,"prerenderedAt":206},["ShallowReactive",2],{"DefaultLayoutnl":3,"language-blog-slug-gebruik-scroll-gedreven-animaties-voor-betere-transities-i18n-slugs":132,"language-blog-slug-nl-gebruik-scroll-gedreven-animaties-voor-betere-transities":139},{"app":4,"menu":31,"footer":66},{"githubUrl":5,"youtubeUrl":6,"linkedinUrl":7,"phoneNumber":8,"emailAddress":9,"legal":10,"addresses":20},"https:\u002F\u002Fgithub.com\u002Fvoorhoede\u002F","https:\u002F\u002Fwww.youtube.com\u002Fchannel\u002FUCzHuhQVYFRixtQN2-swcuGg","https:\u002F\u002Fwww.linkedin.com\u002Fcompany\u002Fde-voorhoede","+31 20 2610 954","post@voorhoede.nl",[11,14,17],{"title":12,"value":13},"KvK","56017235",{"title":15,"value":16},"BTW","NL851944620B01",{"title":18,"value":19},"IBAN","NL14TRIO0320142078",[21,26],{"address":22,"city":23,"googleMapsLink":24,"postalCode":25},"Koivistokade 70","Amsterdam","https:\u002F\u002Fwww.google.com\u002Fmaps\u002Fplace\u002FDe+Voorhoede+%7C+Front-end+Development\u002F@52.396847,4.8700823,17z\u002Fdata=!3m1!4b1!4m5!3m4!1s0x47c5e21d502d2d59:0xbf570944a96ebf45!8m2!3d52.347647!4d4.8502154","1013 BB",{"address":27,"city":28,"googleMapsLink":29,"postalCode":30},"Koornmarkt 22","Delft","https:\u002F\u002Fwww.google.nl\u002Fmaps\u002Fplace\u002FKoornmarkt+22,+2611+EG+Delft\u002F@52.0093477,4.3573054,17z\u002F","2611 EG",{"title":32,"callToActions":33,"links":39},"Site Menu",[34],{"id":35,"title":36,"link":37},"163140903","Contact",{"__typename":38},"ContactRecord",[40,46,51,56,61],{"id":41,"title":42,"link":43},"163140909","Impact",{"__typename":44,"slug":45},"PageRecord","impact",{"id":47,"title":48,"link":49},"163140910","Services",{"__typename":50},"ServiceOverviewRecord",{"id":52,"title":53,"link":54},"163140911","Cases",{"__typename":55},"CaseOverviewRecord",{"id":57,"title":58,"link":59},"163140913","Over ons",{"__typename":44,"slug":60},"about-us",{"id":62,"title":63,"link":64},"NnUFs73_Saa8XE_jYZFHcw","Werken bij",{"__typename":44,"slug":65},"work-at",{"links":67,"copyrightTitle":93,"copyrightLabel":94,"copyrightLink":95,"privacyTitle":96,"privacyLabel":97,"privacyLink":98,"certificatesGrid":99},[68,71,74,77,82,85,88],{"id":69,"title":42,"link":70},"144185271",{"__typename":44,"slug":45},{"id":72,"title":48,"link":73},"144185272",{"__typename":50},{"id":75,"title":53,"link":76},"144185273",{"__typename":55},{"id":78,"title":79,"link":80},"144185274","Blog",{"__typename":81},"BlogPostOverviewRecord",{"id":83,"title":58,"link":84},"144185275",{"__typename":44,"slug":60},{"id":86,"title":36,"link":87},"144185276",{"__typename":38},{"id":89,"title":90,"link":91},"144185277","FAQ",{"__typename":44,"slug":92},"faq","Creative Commons licentie en disclaimer","CC BY 4.0","https:\u002F\u002Fcreativecommons.org\u002Flicenses\u002Fby\u002F4.0\u002F","PDF bestand van De Voorhoede privacy statement","Privacy statement","https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1763455427-vh-isms-007-privacy-statement-de-voorhoede-nl.pdf",[100,112,122],{"id":101,"image":102,"link":107},"Xq4bBfg_TZ6Fkjax9mkbLQ",{"url":103,"alt":104,"width":105,"height":106},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1687353463-b-corp-logo-black-rgb.png",null,404,680,{"__typename":108,"id":109,"title":110,"url":111},"ExternalLinkRecord","fGW1ak8XQYaYDLkBSyncog","B Corp","https:\u002F\u002Fwww.bcorporation.net\u002Fen-us\u002Ffind-a-b-corp\u002Fcompany\u002Fde-voorhoede\u002F",{"id":113,"image":114,"link":118},"c5mCXRTiSraRIB25fw1p7Q",{"url":115,"alt":104,"width":116,"height":117},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1687353461-dda-boxlogo-black.png",627,480,{"__typename":108,"id":119,"title":120,"url":121},"P6Jh7B0cTv2cKyNEeKVWVQ","Dutch Digital Agencies","https:\u002F\u002Fdutchdigitalagencies.com\u002Fleden\u002Fde-voorhoede\u002F",{"id":123,"image":124,"link":127},"MT5SCyNxSTSr_v5eeATMZw",{"url":125,"alt":104,"width":126,"height":126},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1775730283-dnv.png",518,{"id":128,"title":129,"link":130},"BRtNB5HnT5i-7HkA8IYzBw","DIV",{"__typename":44,"slug":131},"impact\u002Fdigitale-producten-privacy-by-design",[133,136],{"locale":134,"value":135},"en","better-transitions-with-scroll-driven-animations",{"locale":137,"value":138},"nl","gebruik-scroll-gedreven-animaties-voor-betere-transities",{"page":140},{"slug":138,"i18nSlugs":141,"social":144,"title":145,"subtitle":79,"isArchived":149,"headerIllustration":150,"date":154,"authors":155,"introTitle":164,"items":165,"pivots":202,"relatedBlogPosts":203,"tags":204,"onMountedScript":205,"onUnmountedScript":169},[142,143],{"locale":134,"value":135},{"locale":137,"value":138},{"title":145,"description":146,"image":147},"Gebruik scroll-gedreven animaties voor betere transities","Verbeter overgangen met CSS scroll-gedreven animaties—geen JavaScript nodig! Creëer vloeiende, interactieve effecten met native CSS.",{"url":148},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1724412268-linkedin-blog-11.jpg",false,{"url":151,"alt":104,"width":152,"height":153},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1724401982-filmstrip.svg",688,542,"2025-01-10T13:42:00.261+01:00",[156],{"name":157,"lastName":158,"slug":159,"image":160},"Jurgen","Beliën","jurgen",{"url":161,"alt":104,"width":162,"height":163},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1721036030-jurgen-edit.jpg",2341,3069,"De nieuwe CSS scroll-gedreven animaties API maakt meer gedetailleerde en interactieve overgangen mogelijk.",[166,171,175,179,182,187,190,193,196,199],{"__typename":167,"id":168,"title":169,"body":170},"TextSectionRecord","NGMeKlM_TWmhBRImXb4k1w","","\u003Cp>CSS scroll-gedreven animaties zijn een nieuwe manier om animaties te defini&euml;ren die niet gebonden zijn aan tijd. In plaats van een specifieke duur te declareren, gebruik je een functie die een positie koppelt aan een specifieke frame in de animatie. Dit maakt het eenvoudiger om scroll-gedreven animaties toe te voegen, zoals het parallax-effect. Maar het kan ook andere overgangen makkelijker toepasbaar maken, zelfs wanneer er geen directe relatie is tussen de animatiepositie en de gebruikersinteractie.\u003C\u002Fp>",{"__typename":167,"id":172,"title":173,"body":174},"YqNA8qXHRIeyLAjqGZmxEg","Transities vs Animaties","\u003Cp>Wanneer we werken met interactieve elementen, denken we vaak in termen van verschillende toestanden, waarbij animaties meestal de overgang van de ene toestand naar de andere vormen. Niet verrassend worden deze vaak gerealiseerd door de CSS-\u003Ccode>transition\u003C\u002Fcode>-eigenschap toe te voegen aan de initi&euml;le toestand. Dit in contrast met daadwerkelijke animaties, gedefinieerd met \u003Ccode>@keyframes\u003C\u002Fcode>, waarbij er een standaard toestand is en de animatie over een bepaalde duur meerdere gedefinieerde toestanden doorloopt. Met de nieuwe eigenschappen wordt de tijdlijn een functie van gebruikersinteractie. De tijdlijn wordt in feite \u003Cstrong>gekoppeld aan de interactie\u003C\u002Fstrong>:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Bij \u003Ccode>scroll()\u003C\u002Fcode> komt het eerste frame overeen met de startpositie van de scroll en het laatste frame met de eindpositie.\u003C\u002Fli>\n\u003Cli>Bij \u003Ccode>view()\u003C\u002Fcode> wordt de animatie gekoppeld aan de zichtbaarheid van het element. Het eerste keyframe start wanneer het element in beeld komt, en het laatste keyframe wordt bereikt wanneer de tegenoverliggende rand van het element uit de scrollcontainer verdwijnt.\u003C\u002Fli>\n\u003C\u002Ful>",{"__typename":167,"id":176,"title":177,"body":178},"VGT1IhyaR_eHIwieAkYQGA","Voorbeeld: Een scrollbare slideshow","\u003Cp data-start=\"0\" data-end=\"325\">Stel je een horizontale lijst met afbeeldingen voor, waarbij alle afbeeldingen behalve degene die in beeld is, in grijstinten worden weergegeven. Zonder scroll-gedreven animaties zou je kunnen zeggen dat de slides ofwel een actieve of een inactieve toestand hebben&mdash;de eerste in full-color, de tweede in grijstinten.\u003C\u002Fp>\n\u003Cp data-start=\"327\" data-end=\"653\">Wanneer een slide volledig zichtbaar is, zou de toestand actief moeten zijn, anders inactief. De meest voor de hand liggende oplossing zou zijn om twee klassen te cre&euml;ren en een \u003Ccode>IntersectionObserver\u003C\u002Fcode> toe te voegen met een callback die de klassen wisselt zodra een slide het zichtbare gebied binnenkomt of verlaat.\u003C\u002Fp>\n\u003Cp data-start=\"655\" data-end=\"713\" data-is-last-node=\"\">Probeer horizontaal te scrollen in het volgende voorbeeld:\u003C\u002Fp>\n\u003Cfigure>\u003Cexample-intersection-observer-kvppleqg style=\"display: block; max-width: 100%; aspect-ratio: 1.4; background-repeat: no-repeat; background-position: top center; background-size: contain; background-image: url('https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1724404161-2024-voorhoede-browser.svg');\">\n\u003Cp slot=\"unsupported\" class=\"example__unsupported\" style=\"padding: 20% 5% 0%; text-align: center;\">Helaas, je browser heeft geen ondersteuning voor de technologie die in deze demo gebruikt wordt.\u003C\u002Fp>\n\u003Cspan class=\"example__slide\" hidden=\"\"> \u003Cimg src=\"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1724404160-2024-voorhoede-slide-cross.svg\" \u002F> \u003C\u002Fspan> \u003Cspan class=\"example__slide\" hidden=\"\"> \u003Cimg src=\"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1724404160-2024-voorhoede-slide-cross.svg\" \u002F> \u003C\u002Fspan> \u003Cspan class=\"example__slide\" hidden=\"\"> \u003Cimg src=\"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1724404160-2024-voorhoede-slide-cross.svg\" \u002F> \u003C\u002Fspan> \u003C\u002Fexample-intersection-observer-kvppleqg>\u003C\u002Ffigure>",{"__typename":167,"id":180,"title":169,"body":181},"QofyFm7STd2ayg1vLVtXhA","\u003Cp>Bekijk nu hetzelfde gedrag met een scroll-gedreven animatie met \u003Ccode inline=\"\">animation-timeline: view()\u003C\u002Fcode>. In plaats van twee toestanden kun je een slide zien als een animatie, die start wanneer de slide in de viewport komt en eindigt wanneer de slide het frame verlaat. Dit betekent dat het midden van de animatie het moment is waarop de slide zich in het centrum van het frame bevindt, de impliciete actieve toestand.\u003C\u002Fp>\n\u003Cp>Dit wordt duidelijker als we twee aparte animaties maken met een gedeelde duur, &eacute;&eacute;n genaamd \u003Ccode>move\u003C\u002Fcode> en &eacute;&eacute;n genaamd \u003Ccode>highlight\u003C\u002Fcode>. We kunnen de eerste gebruiken om het scrollgedrag na te bootsen en de tweede om de overgang te regelen:\u003C\u002Fp>\n\u003Cfigure>\u003Cexample-highlight-animation-kvppleqg style=\"display: block; max-width: 100%; aspect-ratio: 1.4; background-repeat: no-repeat; background-position: top center; background-size: contain; background-image: url('https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1724404161-2024-voorhoede-browser.svg');\">\n\u003Cp slot=\"unsupported\" class=\"example__unsupported\" style=\"padding: 20% 5% 0%; text-align: center;\">Helaas, je browser heeft geen ondersteuning voor de technologie die in deze demo gebruikt wordt.\u003C\u002Fp>\n\u003Cspan class=\"example__slide\" hidden=\"\"> \u003Cimg src=\"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1724404160-2024-voorhoede-slide-cross.svg\" \u002F> \u003C\u002Fspan> \u003C\u002Fexample-highlight-animation-kvppleqg>\u003C\u002Ffigure>",{"__typename":183,"id":184,"language":185,"body":186},"CodeBlockRecord","YfDzC0uTTeOoY1ivOCKLHw","css",".example__slide {\n  animation-name:  move, highlight;\n  animation-duration: 5s;\n  animation-iteration-count: infinite;\n  animation-timing-function: ease-in-out;\n  animation-diretion: alternate;\n}\n\n@keyframes move {\n  0% {\n    transform: translateX(130%);\n  }\n  100% {\n    transform: translateX(-110%);\n  }\n}\n\n@keyframes highlight {\n  0% {\n    background-color: transparent;\n  }\n  50% {\n    background-color: blue;\n  }\n  100% {\n    background-color: transparent;\n  }\n}\n",{"__typename":167,"id":188,"title":169,"body":189},"SllnTcu_Qhy-BxuZkHxYVg","\u003Cp>In plaats van deze animatie te zien als een functie van tijd, beschouw deze als een functie van de scrollpositie van de container en dus als een functie van de positie van de slide. Dit betekent dat we de \u003Ccode>move\u003C\u002Fcode>-animatie kunnen verwijderen en de \u003Ccode>animation-timeline\u003C\u002Fcode> kunnen defini&euml;ren als een functie van de \u003Ccode>view\u003C\u002Fcode>. Als je een op Chromium-gebaseerde browser gebruikt, kun je horizontaal scrollen in het volgende voorbeeld om het in actie te zien.\u003C\u002Fp>\n\u003Cfigure>\u003Cexample-scroll-animation-kvppleqg style=\"display: block; max-width: 100%; aspect-ratio: 1.4; background-repeat: no-repeat; background-position: top center; background-size: contain; background-image: url('https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1724404161-2024-voorhoede-browser.svg');\">\n\u003Cp slot=\"unsupported\" class=\"example__unsupported\" style=\"padding: 20% 5% 0%; text-align: center;\">Helaas, je browser heeft geen ondersteuning voor de technologie die in deze demo gebruikt wordt.\u003C\u002Fp>\n\u003Cspan class=\"example__slide\" hidden=\"\"> \u003Cimg src=\"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1724404160-2024-voorhoede-slide-cross.svg\" \u002F> \u003C\u002Fspan> \u003Cspan class=\"example__slide\" hidden=\"\"> \u003Cimg src=\"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1724404160-2024-voorhoede-slide-cross.svg\" \u002F> \u003C\u002Fspan> \u003Cspan class=\"example__slide\" hidden=\"\"> \u003Cimg src=\"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1724404160-2024-voorhoede-slide-cross.svg\" \u002F> \u003C\u002Fspan> \u003C\u002Fexample-scroll-animation-kvppleqg>\u003C\u002Ffigure>",{"__typename":183,"id":191,"language":185,"body":192},"Q33IXUdHRTSiStTR6H39wA",".example__slide {\n  animation-timeline: view(x);\n  animation-name: highlight;\n}\n",{"__typename":167,"id":194,"title":169,"body":195},"SDAmhhZjRhub5yZ7TKphhg","\u003Cp>Verdere aanpassingen kunnen worden gemaakt door verschillende offsets op te geven voor waar de \u003Ccode>animation-timeline\u003C\u002Fcode> moet beginnen of eindigen, zodat het hoogtepunt samenvalt met het rustpunt van de slide. In het volgende voorbeeld zorgen de offsets ervoor dat de triggering viewbox een inset heeft, zodat gedeeltelijk zichtbare slides de animatie pas starten wanneer ze de inset-grens overschrijden. Voor het eerste kind is een uitzondering nodig om de linkerzijde van de viewbox uit te lijnen met de zichtbare rand van de container.\u003C\u002Fp>\n\u003Cfigure>\u003Cexample-scroll-animation-2-kvppleqg style=\"display: block; max-width: 100%; aspect-ratio: 1.4; background-repeat: no-repeat; background-position: top center; background-size: contain; background-image: url('https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1724404161-2024-voorhoede-browser.svg');\">\n\u003Cp slot=\"unsupported\" class=\"example__unsupported\" style=\"padding: 20% 5% 0%; text-align: center;\">Helaas, je browser heeft geen ondersteuning voor de technologie die in deze demo gebruikt wordt.\u003C\u002Fp>\n\u003Cspan class=\"example__slide\" hidden=\"\"> \u003Cimg src=\"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1724404160-2024-voorhoede-slide-cross.svg\" \u002F> \u003C\u002Fspan> \u003Cspan class=\"example__slide\" hidden=\"\"> \u003Cimg src=\"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1724404160-2024-voorhoede-slide-cross.svg\" \u002F> \u003C\u002Fspan> \u003Cspan class=\"example__slide\" hidden=\"\"> \u003Cimg src=\"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1724404160-2024-voorhoede-slide-cross.svg\" \u002F> \u003C\u002Fspan> \u003C\u002Fexample-scroll-animation-2-kvppleqg>\u003C\u002Ffigure>",{"__typename":183,"id":197,"language":185,"body":198},"IF9PWpGFQvWSqj7x5NJMXw",".example__slide:first-child {\n  animation-timeline: view(x 0 var(--offset));\n}  \n.example__slide:last-child {\n  animation-timeline: view(x var(--offset) 0);\n}\n",{"__typename":167,"id":200,"title":169,"body":201},"URdGTKVkSaSh3E36joW9AQ","\u003Cp>Hoewel dit gedrag niet per se gekoppeld hoeft te zijn aan scrollinteractie, zorgt dit wel voor een beknoptere implementatie en maakt het complexere, meerstaps animaties als overgangen mogelijk. En niet te vergeten, met het extra voordeel dat het zonder JavaScript werkt! Voorlopig wordt dit alleen ondersteund in Chromium-gebaseerde browsers, maar ondersteuning voor Firefox en Safari is onderweg.\u003C\u002Fp>",[],[],[],"const css = `\n        :host {\n          --slide-width: 80%;\n          --background-inset: 1%;\n          padding-top: 15%;\n          z-index: 10;\n        }\n        .example__frame {\n          display: flex;\n          overflow-x: scroll;\n          scroll-snap-type: x mandatory;\n          scroll-behavior: smooth;\n          box-sizing: border-box;\n          margin-bottom: 1rem;\n          padding: 0 5%;\n        }\n        .example__slide {\n          display: block;\n          scroll-snap-align: center;\n          flex-shrink: 0;\n          width: var(--slide-width);\n          margin-bottom: calc((100% - var(--slide-width))\u002F2);\n          transition: background-color .25s;\n          background-clip: content-box;\n          line-height: 0;\n          padding: var(--background-inset);\n          z-index: 0;\n          background-color: transparent;\n          border-radius: 4px;\n          overflow: hidden;\n        }\n        .example__slide img {\n          margin: calc(var(--background-inset) * -1);\n          margin-bottom: calc(var(--background-inset-bottom) * -1);\n          width: calc(100% + var(--background-inset) * 2);\n          height: auto;\n        }\n        .example__slide.active {\n          background-color: blue;\n        }\n      `;\n\nconst moveKeyframes = `\n        @keyframes move {\n          0% {\n            transform: translateX(130%);\n          }\n          100% {\n            transform: translateX(-110%);\n          }\n        }\n      `;\n\nconst highlightKeyframes = `\n        @keyframes highlight {\n          0% {\n            background-color: transparent;\n          }\n          50% {\n\n          background-color: blue;\n          }\n          100% {\n            background-color: transparent;\n          }\n        }\n      `;\n\nclass ExampleKvppleqg extends HTMLElement {\n  constructor(styles = \"\") {\n    super();\n\n    const shadowRoot = this.attachShadow({\n      mode: \"open\",\n    });\n\n    shadowRoot.innerHTML = `\n            \u003Cstyle>${css}${styles}\u003C\u002Fstyle>\n            \u003Cslot name=\"unsupported\">\u003C\u002Fslot>\n            \u003Cslot hidden>\u003C\u002Fslot>\n            \u003Cdiv class=\"example__frame\">\n              \u003C!-- will copy slot content here -->\n            \u003C\u002Fdiv>\n          `;\n  }\n\n  connectedCallback() {\n    this.unsupported = this.shadowRoot.querySelector(\"slot[name=unsupported]\");\n    this.enhance();\n  }\n\n  enhance() {\n    const slotContent = this.shadowRoot\n      .querySelector(\"slot:not([name])\")\n      .assignedNodes();\n    const frame = this.shadowRoot.querySelector(\".example__frame\");\n\n    slotContent.forEach((content) => {\n      content.removeAttribute?.(\"hidden\", \"\");\n      frame.append(content);\n    });\n    this.hideUnsupported();\n    console.log(`${this.localName} enhanced`);\n  }\n\n  hideUnsupported() {\n    this.unsupported.setAttribute(\"hidden\", \"\");\n  }\n\n  showUnsupported() {\n    this.unsupported.removeAttribute(\"hidden\");\n  }\n\n  disconnectedCallback() {}\n}\n\nclass ExampleIntersectionObserverKvppleqg extends ExampleKvppleqg {\n  constructor() {\n    super();\n    this.observer = ('IntersectionObserver' in window)\n      ? new IntersectionObserver(this.handleIntersect, {\n        root: this.shadowRoot.querySelector(\".example__frame\"),\n        threshold: 1,\n      })\n      : undefined;\n  }\n  connectedCallback() {\n    if (this.observer) {\n      super.connectedCallback();\n      for (const slide of this.shadowRoot.querySelectorAll(\".example__slide\")) {\n        this.observer.observe(slide);\n      }\n    }\n  }\n  disconnectedCallback() {\n    super.disconnectedCallback();\n    this.observer?.disconnect();\n  }\n  handleIntersect(entries) {\n    entries.forEach((entry) => {\n      if (entry.isIntersecting) {\n        entry.target.classList.add(\"active\");\n      } else {\n        entry.target.classList.remove(\"active\");\n      }\n    });\n  }\n}\n\nif (!customElements.get(\"example-intersection-observer-kvppleqg\")) {\n  customElements.define(\n    \"example-intersection-observer-kvppleqg\",\n    ExampleIntersectionObserverKvppleqg,\n  );\n}\n\nclass ExampleHighlightAnimationKvppleqg extends ExampleKvppleqg {\n  constructor() {\n    super(`\n            .example__frame {\n              overflow-x: hidden;\n              scroll-snap-type: none;\n            }\n            .example__slide {\n              scroll-snap-align: none;\n              animation-name: move, highlight;\n              animation-duration: 5s;\n              animation-iteration-count: infinite;\n              animation-timing-function: ease-in-out;\n              animation-direction: alternate;\n            }\n            ${moveKeyframes}\n            ${highlightKeyframes}\n          `);\n  }\n}\n\nif (!customElements.get(\"example-highlight-animation-kvppleqg\")) {\n  customElements.define(\n    \"example-highlight-animation-kvppleqg\",\n    ExampleHighlightAnimationKvppleqg,\n  );\n}\n\nclass ExampleScrollAnimationKvppleqg extends ExampleKvppleqg {\n  constructor() {\n    super(`\n            .example__slide {\n              animation-name: highlight;\n              animation-timeline: view(x);\n            }\n            ${highlightKeyframes}\n          `);\n  }\n  connectedCallback() {\n    if (window.CSS.supports('animation-timeline', 'view(x)')) {\n      super.connectedCallback();\n    }\n  }\n}\n\nif (!customElements.get(\"example-scroll-animation-kvppleqg\")) {\n  customElements.define(\n    \"example-scroll-animation-kvppleqg\",\n    ExampleScrollAnimationKvppleqg,\n  );\n}\n\nclass ExampleScrollAnimation2Kvppleqg extends ExampleKvppleqg {\n  constructor() {\n    super(`\n            .example__slide {\n              --slide-width: 80%;\n              --animation-margin: calc(100% - var(--slide-width));\n              animation-name: highlight;\n              \u002F* animation starts ands ends 20% from left and right edge *\u002F\n              animation-timeline: view(x var(--animation-margin));\n            }\n\n            .example__slide:first-child:not(:last-child) {\n              \u002F* animation starts and ends at the left edge *\u002F\n              animation-timeline: view(x 0 var(--animation-margin));\n            }\n\n            ${highlightKeyframes}\n          `);\n  }\n  \n  connectedCallback() {\n    if (window.CSS.supports('animation-timeline', 'view(x)')) {\n      super.connectedCallback();\n    }\n  }\n}\n\nif (!customElements.get(\"example-scroll-animation-2-kvppleqg\")) {\n  customElements.define(\n    \"example-scroll-animation-2-kvppleqg\",\n    ExampleScrollAnimation2Kvppleqg,\n  );\n}\n",1776256147578]