← Blurr Motion gallery-marquee-scrub-brutalist
Categorie galleries Tier 1 Techniek #16 Deps gsap
// MARQUEE_SCRUB · v1 VELOCITY_CAPPED
STRATEGIE ONTWERP MOTION GROWTH BRANDING STRATEGIE ONTWERP MOTION GROWTH BRANDING
SCRUB: 1.5s CAP: 1.6×
1. Mechanisme — kopieer 1-op-1, geen styling-keuzes
// Mechanisme: gallery-marquee-scrub-brutalist
// Scrub-tied marquee met capped velocity (ease-out coupling, scrub:1.5)
import gsap from "https://esm.sh/[email protected]";
import { ScrollTrigger } from "https://esm.sh/[email protected]/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger);
const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
if (!reduce) {
  document.querySelectorAll(".bm-track").forEach((track) => {
    gsap.to(track, {
      xPercent: -50,
      ease: "none",
      scrollTrigger: {
        trigger: track.closest(".bm-stage"),
        start: "top bottom",
        end: "bottom top",
        scrub: 1.5,
      }
    });
  });
  // Velocity → cap met ease-out (max boost 1.6x, smoothed)
  const tracks = document.querySelectorAll(".bm-track");
  ScrollTrigger.create({
    onUpdate: (self) => {
      const v = Math.min(Math.abs(self.getVelocity()) / 2000, 1);
      const eased = 1 + (1 - Math.pow(1 - v, 3)) * 0.6; // ease-out cubic, cap 1.6
      tracks.forEach((t) => gsap.to(t, { timeScale: eased, duration: .4, overwrite: "auto" }));
    }
  });
}
2. Skeleton — DOM + class-namen, mag herschikken
<!-- Skeleton: gallery-marquee-scrub-brutalist -->
<section class="bm-stage">
  <header class="bm-head">
    <span class="bm-tag">// MARQUEE_SCRUB · v1</span>
    <span class="bm-tag">VELOCITY_CAPPED</span>
  </header>
  <div class="bm-strip">
    <div class="bm-track">
      <span>STRATEGIE</span><span class="bm-dot">●</span>
      <span>ONTWERP</span><span class="bm-dot">●</span>
      <span class="bm-hot">MOTION</span><span class="bm-dot">●</span>
      <span>GROWTH</span><span class="bm-dot">●</span>
      <span>BRANDING</span><span class="bm-dot">●</span>
      <!-- duplicate for seamless loop -->
      <span>STRATEGIE</span><span class="bm-dot">●</span>
      <span>ONTWERP</span><span class="bm-dot">●</span>
      <span class="bm-hot">MOTION</span><span class="bm-dot">●</span>
      <span>GROWTH</span><span class="bm-dot">●</span>
      <span>BRANDING</span><span class="bm-dot">●</span>
    </div>
  </div>
</section>
3. Styling-template — verplicht eigen invulling per merk
/* Styling: gallery-marquee-scrub-brutalist — 2px borders, mono caps, hot-spot */
.bm-stage{
  --bg:#F4F1EB; --ink:#0A0A0A; --hot:#FF4A1C;
  background:var(--bg); color:var(--ink);
  padding:clamp(2rem,5vw,4rem) 0;
  border-top:2px solid var(--ink); border-bottom:2px solid var(--ink);
}
.bm-head{ display:flex; justify-content:space-between; padding:0 clamp(1.5rem,4vw,3rem) 1.5rem;
  font-family:"JetBrains Mono",monospace; font-size:.72rem; letter-spacing:.2em; text-transform:uppercase; }
.bm-strip{ overflow:hidden; border-top:2px solid var(--ink); border-bottom:2px solid var(--ink); padding:1.2rem 0; }
.bm-track{ display:flex; gap:2.5rem; white-space:nowrap; will-change:transform;
  font-family:"JetBrains Mono",monospace; font-weight:500;
  font-size:clamp(2rem,6vw,4.5rem); letter-spacing:.04em; text-transform:uppercase; }
.bm-track .bm-dot{ color:var(--ink); align-self:center; font-size:.6em; }
.bm-track .bm-hot{ color:var(--hot); }