← Blurr Motion cta-marquee-velocity-gallery
Categorie cta Tier 1 Techniek #16 Deps gsap
Make it beautiful Make it move Make it last Make it beautiful Make it move Make it last
Begin a project →
1. Mechanisme — kopieer 1-op-1, geen styling-keuzes
// Mechanisme: cta-marquee-velocity-gallery (techniek #16)
// Canvas-painted pastel gradient als achtergrond (geen externe URLs).
// Infinite x-translate via gsap.to(track,{x:()=>-track.scrollWidth/2}). Loop-iteration cyclet kleur-classes.
// Scroll-velocity hijack: timeScale = clamp(|dy|*0.06+1, 1, 4) met decay.
import gsap from 'https://esm.sh/[email protected]';
const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
const root = document.querySelector('.gal-cta');
const cv = root.querySelector('canvas.gal-bg');
const ctx = cv.getContext('2d');
function paint() {
  cv.width = cv.offsetWidth; cv.height = cv.offsetHeight;
  const g = ctx.createLinearGradient(0, 0, cv.width, cv.height);
  g.addColorStop(0, '#FCD9C2'); g.addColorStop(.5, '#F4C2D7'); g.addColorStop(1, '#C9D9F0');
  ctx.fillStyle = g; ctx.fillRect(0, 0, cv.width, cv.height);
}
paint(); window.addEventListener('resize', paint);
const track = root.querySelector('.gal-marquee-track');
if (!reduce) {
  const tw = gsap.to(track, { x: () => -track.scrollWidth/2, duration: 28, ease:'none', repeat:-1, onRepeat:()=>{
    track.dataset.cycle = ((+track.dataset.cycle||0)+1)%3;
  }});
  let last = window.scrollY, target = 1;
  window.addEventListener('scroll', () => {
    const v = Math.abs(window.scrollY - last);
    target = Math.min(4, v*0.06+1); last = window.scrollY;
  }, { passive:true });
  gsap.ticker.add(() => {
    const cur = tw.timeScale();
    tw.timeScale(cur + (target-cur)*0.08);
    target += (1-target)*0.04;
  });
}
2. Skeleton — DOM + class-namen, mag herschikken
<!-- Skeleton: cta-marquee-velocity-gallery -->
<section class="gal-cta">
  <canvas class="gal-bg"></canvas>
  <div class="gal-marquee-viewport">
    <div class="gal-marquee-track">
      <span class="gal-item">Make it beautiful</span>
      <em class="gal-sep">/</em>
      <span class="gal-item">Make it move</span>
    </div>
  </div>
  <div class="gal-collage">
    <figure class="gal-card a"></figure>
    <figure class="gal-card b"></figure>
    <figure class="gal-card c"></figure>
  </div>
  <a class="gal-btn" href="#">Begin a project</a>
</section>
3. Styling-template — verplicht eigen invulling per merk
/* Styling: cta-marquee-velocity-gallery */
:root { --block-bg:#FCF6EE; --block-fg:#1F1A14; --block-accent:#E08A57; }
.gal-cta { position:relative; overflow:hidden; }
canvas.gal-bg { position:absolute; inset:-4rem; width:calc(100% + 8rem); height:calc(100% + 8rem); filter:blur(40px) saturate(1.1); z-index:0; }
.gal-marquee-viewport { position:relative; z-index:2; overflow:hidden; }
.gal-marquee-track { display:inline-flex; gap:3rem; white-space:nowrap; will-change:transform; font-family:'Fraunces', serif; }
.gal-item { font-size:clamp(2.5rem, 7vw, 6rem); font-weight:300; font-style:italic; color:#1F1A14; }
.gal-collage figure { box-shadow:0 30px 60px -20px rgba(31,26,20,.25); border-radius:6px; }