Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save kazzohikaru/462144c19957bc45a364fd097eecc61b to your computer and use it in GitHub Desktop.

Select an option

Save kazzohikaru/462144c19957bc45a364fd097eecc61b to your computer and use it in GitHub Desktop.
GSAP Looping Marquee Timeline and Reverse

GSAP Looping Marquee Timeline and Reverse

Looping marquee built with GSAP Timeline using custom directions and reverse playing.

A Pen by Patrick F. Mayer on CodePen.

License.

<div class="marquee" aria-label="You spin me right round baby right round">
<div class="marquee__text" aria-hidden="true">
<div id="marquee-first-line" class="marquee__line">
<div class="marquee__sentence">You spin me right round baby right round</div>
<div class="marquee__sentence">You spin me right round baby right round</div>
<div class="marquee__sentence">You spin me right round baby right round</div>
</div>
<div id="marquee-second-line" class="marquee__line">
<div class="marquee__sentence">You spin me right round baby right round</div>
<div class="marquee__sentence">You spin me right round baby right round</div>
<div class="marquee__sentence">You spin me right round baby right round</div>
</div>
<div id="marquee-third-line" class="marquee__line">
<div class="marquee__sentence">You spin me right round baby right round</div>
<div class="marquee__sentence">You spin me right round baby right round</div>
<div class="marquee__sentence">You spin me right round baby right round</div>
</div>
</div>
<a href="https://youtu.be/PGNiXGX2nLU?t=59" target="_blank">
<img
id="maquee-image"
class="marquee__image"
src="https://assets.freedommayer.com/codepen/right-round.gif"
/>
</a>
</div>
const configs = {
duration: 30,
ease: 'none',
};
const lines = {
first: {
direction: 'right',
element: document.querySelector('#marquee-first-line'),
},
second: {
direction: 'left',
element: document.querySelector('#marquee-second-line'),
},
third: {
direction: 'right',
element: document.querySelector('#marquee-third-line'),
},
};
let timeline = gsap.timeline();
let sentenceWidth = document.querySelector('.marquee__sentence').clientWidth;
// Init timeline and register events.
function init() {
setTimeline();
const marqueeImage = document.querySelector('#maquee-image');
marqueeImage.addEventListener('mouseenter', flipDirection);
marqueeImage.addEventListener('mouseout', flipDirection);
window.addEventListener('resize', handleResize);
}
// Add marquee animations to timeline.
function setTimeline() {
timeline
.add(createMarquee(lines.first.element, lines.first.direction), 0)
.add(createMarquee(lines.second.element, lines.second.direction), 0)
.add(createMarquee(lines.third.element, lines.third.direction), 0);
}
// Create single marquee animation.
function createMarquee(element, direction) {
const distance = sentenceWidth * 2;
return gsap.timeline()
.to(element, {
...configs,
x: direction === 'left' ? distance : -distance,
onComplete() {
timeline.play(0);
},
onReverseComplete() {
timeline.reverse(0);
},
},
);
}
// Reverse the timeline direction.
function flipDirection() {
timeline.reversed(!timeline.reversed());
}
// Reset timeline on resize.
function handleResize() {
sentenceWidth = document.querySelector('.marquee__sentence').clientWidth;
timeline.seek(0);
timeline.clear();
setTimeline();
}
init();
<script src="https://unpkg.co/gsap@3/dist/gsap.min.js"></script>
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@800&display=swap');
.marquee {
font-size: clamp(4rem, 4.5vw, 9rem);
font-weight: 800;
line-height: 1.25;
position: relative;
text-transform: uppercase;
user-select: none;
width: 100%;
}
.marquee__text {
overflow: hidden;
pointer-events: none;
}
.marquee__line {
display: flex;
position: relative;
&:nth-child(2) {
justify-content: flex-end;
z-index: 1;
}
}
.marquee__sentence {
padding-right: 30px;
white-space: nowrap;
}
.marquee__image {
border-radius: 12px;
height: 120%;
left: 0;
margin: 0 auto;
position: absolute;
right: 0;
top: -10%;
}
html, body {
background-color: #0b0b0b;
color: #ede1ff;
font-family: 'Open Sans', Arial;
}
body {
align-items: center;
display: flex;
justify-content: center;
min-height: 100vh;
}
* {
box-sizing: border-box;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment