bike-bear-logobike-bear-logobike-bear-logobike-bear-logo
✕
Published by bikebear on March 31, 2026
Categories
  • GSAP
  • DateMarch 31, 2026
EVERY DANCER COUNTS EVERY DANCER COUNTS

HTML

<!-- Instance 1 -->
<div class="marquee-wrapper">
  <div class="stage-blur-left"></div>
  <div class="stage-blur-right"></div>
  <div class="stage" aria-label="Marquee: Every Dancer Counts">
    <div class="marquee-track">
      <span class="marquee-text"><span class="p1">EVERY</span> <span class="p2">DANCER</span> <span class="p3">COUNTS</span> <span class="dot"></span></span>
      <span class="marquee-text"><span class="p1">EVERY</span> <span class="p2">DANCER</span> <span class="p3">COUNTS</span> <span class="dot"></span></span>
    </div>
  </div>
</div>

CSS

    .speed-indicator {
      position: fixed;
      top: 24px; right: 28px;
      display: flex;
      flex-direction: column;
      align-items: flex-end;
      gap: 6px;
      z-index: 100;
    }

    .speed-label {
      font-family: 'Bebas Neue', sans-serif;
      font-size: 0.65rem;
      letter-spacing: 0.3em;
      color: #444;
      text-transform: uppercase;
    }

/*     .speed-bar-track {
      width: 90px;
      height: 4px;
      background: #1e1e1e;
      border-radius: 2px;
      overflow: hidden;
    } */

/*     .speed-bar-fill {
      height: 100%;
      width: 5%;
      background: linear-gradient(90deg, #b8860b, #ffd700);
      border-radius: 2px;
      box-shadow: 0 0 6px rgba(255, 200, 50, 0.3);
    } */

    .speed-value {
      font-family: 'Bebas Neue', sans-serif;
      font-size: 0.7rem;
      letter-spacing: 0.15em;
      color: #ffd700;
      opacity: 0.5;
    }

    .scroll-hint {
      position: fixed;
      bottom: 28px;
      left: 50%;
      transform: translateX(-50%);
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 6px;
    }

    .scroll-hint span {
      font-family: 'Playfair Display', serif;
      font-style: italic;
      font-size: 0.7rem;
      letter-spacing: 0.3em;
      color: #444;
    }

    .scroll-arrow {
      width: 16px; height: 24px;
      border: 1.5px solid #333;
      border-radius: 8px;
      position: relative;
    }

    .scroll-arrow::after {
      content: '';
      position: absolute;
      top: 4px; left: 50%;
      transform: translateX(-50%);
      width: 3px; height: 6px;
/*       background: #ffd700; */
      border-radius: 2px;
      animation: scroll-dot 1.4s ease-in-out infinite;
    }

    @keyframes scroll-dot {
      0%   { top: 4px; opacity: 1; }
      80%  { top: 12px; opacity: 0; }
      100% { top: 4px; opacity: 0; }
    }

    .wrapper {
      width: 100%;
      position: relative;
    }

    .stage {
      width: 100%;
/*       padding: 12px 0;
      background: linear-gradient(180deg, #111 0%, #1a1a1a 50%, #111 100%);
      border-top: 2px solid #c9a227;
      border-bottom: 2px solid #c9a227;
      box-shadow: 0 0 40px rgba(201, 162, 39, 0.3), inset 0 0 60px rgba(0,0,0,0.5); */
      overflow: visible;
      position: relative;
	  transform: rotate(-6deg);
    }

/*     .stage::after {
      content: '';
      position: absolute;
      inset: 0;
      background: repeating-linear-gradient(
        0deg, transparent, transparent 3px,
        rgba(0,0,0,0.08) 3px, rgba(0,0,0,0.08) 4px
      );
      pointer-events: none;
    } */

    .stage-blur-left,
    .stage-blur-right {
      position: absolute;
      top: 0; bottom: 0;
      width: 80px;
      z-index: 2;
      pointer-events: none;
      opacity: 0;
    }

/*     .stage-blur-left  { left: 0;  background: linear-gradient(90deg,  #111, transparent); }
    .stage-blur-right { right: 0; background: linear-gradient(-90deg, #111, transparent); } */

    /* Marquee is now driven fully by GSAP — no CSS animation */
    .marquee-track {
      display: flex;
      width: max-content;
      will-change: transform;
    }

    .marquee-text {
      white-space: nowrap;
      font-family: "nickel-gothic-variable", sans-serif !important;
/*       font-size: clamp(3rem, 8vw, 6rem); */
	  font-size: 14.583vw;
      letter-spacing: 0.12em;
      padding: 0 3rem;
      background: #227EFF;
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
      background-clip: text;
	  line-height: 1;
/*       filter: drop-shadow(0 0 12px rgba(255, 200, 50, 0.5)); */
    }

.marquee-text .blue {
  background: #0069FF;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  padding: 0 20px;
}

.marquee-text .black {
  background: #192A47;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  padding: 0 20px;
}

.marquee-text .white {
	background: #FFFFFF;
	-webkit-background-clip: text;
	-webkit-text-fill-color: transparent;
	background-clip: text;
	padding: 0 20px;
}

.marquee-text span {
      font-family: "nickel-gothic-variable", sans-serif !important;
    }

/*     .marquee-text .dot {
      display: inline-block;
      width: 10px; height: 10px;
      background: #ffd700;
      border-radius: 50%;
      margin: 0 1.5rem;
      vertical-align: middle;
      -webkit-text-fill-color: initial;
      filter: none;
      box-shadow: 0 0 8px #ffd700;
    } */

    .label {
      font-family: 'Playfair Display', serif;
      font-style: italic;
      font-size: 0.8rem;
      letter-spacing: 0.35em;
      color: #555;
      text-transform: uppercase;
      margin-bottom: 18px;
    }

.marquee-wrapper.move-up {
    margin-top: -50px;
}

JS

<script>
jQuery(document).ready(function($) {
  gsap.registerPlugin();

  function initMarquee(wrapper) {
    const BASE_SPEED = 120;
    const MAX_SPEED  = 1400;
    const BOOST      = 50;
    const DECAY_TIME = 1.0;

    const direction  = wrapper.dataset.direction || 'left';
    const track      = wrapper.querySelector('.marquee-track');
    const speedBar   = wrapper.querySelector('.speedBar');
    const speedValue = wrapper.querySelector('.speedValue');
    const blurLeft   = wrapper.querySelector('.stage-blur-left');
    const blurRight  = wrapper.querySelector('.stage-blur-right');
    const scrollHint = wrapper.querySelector('.scrollHint');

    let currentSpeed = BASE_SPEED;
    let lastTime     = null;
    let hasScrolled  = false;
    let lastTouchY   = null;
    let decayTween   = null;

    const trackHalf  = track.scrollWidth / 2;
    let xPos         = direction === 'right' ? -trackHalf : 0;

    gsap.ticker.add((time) => {
      if (lastTime === null) { lastTime = time; return; }
      const delta = time - lastTime;
      lastTime = time;

      xPos += (direction === 'right' ? 1 : -1) * currentSpeed * delta;

      if (direction === 'right' && xPos >= 0)                  xPos = -trackHalf;
      if (direction === 'left'  && Math.abs(xPos) >= trackHalf) xPos = 0;

      gsap.set(track, { x: xPos });
    });

    function updateUI(speed) {
      const mult = speed / BASE_SPEED;
      const pct  = Math.min(100, ((speed - BASE_SPEED) / (MAX_SPEED - BASE_SPEED)) * 100);
      if (speedBar) gsap.to(speedBar, { width: Math.max(5, pct) + '%', duration: 0.2, ease: 'power1.out' });
      if (speedValue) {
        gsap.to(speedValue, { opacity: Math.min(1, 0.4 + pct / 120), duration: 0.2 });
        speedValue.textContent = mult.toFixed(1) + 'x';
      }
      const blurOpacity = Math.min(1, (mult - 2) / 4);
      if (blurLeft && blurRight) {
        gsap.to([blurLeft, blurRight], { opacity: Math.max(0, blurOpacity), duration: 0.3 });
      }
    }

    function boost(amount) {
      if (!hasScrolled) {
        hasScrolled = true;
        if (scrollHint) gsap.to(scrollHint, { opacity: 0, duration: 0.6, ease: 'power1.out' });
      }
      if (decayTween) decayTween.kill();
      currentSpeed = Math.min(MAX_SPEED, currentSpeed + amount);
      updateUI(currentSpeed);
      decayTween = gsap.to({ speed: currentSpeed }, {
        speed:    BASE_SPEED,
        duration: DECAY_TIME,
        ease:     'power2.out',
        onUpdate: function() {
          currentSpeed = this.targets()[0].speed;
          updateUI(currentSpeed);
        }
      });
    }

    return { boost };
  }

  const instances = [];
  document.querySelectorAll('.marquee-wrapper').forEach(wrapper => {
    instances.push(initMarquee(wrapper));
  });

  window.addEventListener('wheel', () => {
    instances.forEach(i => i.boost(50));
  }, { passive: true });

  let lastTouchY = null;
  window.addEventListener('touchstart', (e) => {
    lastTouchY = e.touches[0].clientY;
  }, { passive: true });
  window.addEventListener('touchmove', (e) => {
    if (lastTouchY === null) return;
    const delta = Math.abs(e.touches[0].clientY - lastTouchY);
    lastTouchY = e.touches[0].clientY;
    if (delta > 2) instances.forEach(i => i.boost(delta * 4));
  }, { passive: true });

});
	</script>
© 2026 Betheme by Muffin group | All Rights Reserved | Powered by WordPress