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>

