Skip to content

Instantly share code, notes, and snippets.

@teneburu
Created June 4, 2025 14:26
Show Gist options
  • Save teneburu/87aca08f5d12fd722cc12bbbe940edf1 to your computer and use it in GitHub Desktop.
Save teneburu/87aca08f5d12fd722cc12bbbe940edf1 to your computer and use it in GitHub Desktop.
Timeline seemless loop
<div id="wrapper"></div>
import { createTimeline, utils, stagger } from 'https://esm.sh/animejs';
const wrapperEl = document.querySelector('#wrapper');
const numberOfEls = 500;
const loopDuration = 6000;
const animDuration = loopDuration * .2;
const delay = loopDuration / numberOfEls;
let tl = createTimeline({
defaults: {
ease: 'inOutSine',
loopDelay: (loopDuration * .2) - animDuration,
duration: animDuration
},
})
.add(wrapperEl, {
rotate: -360,
loop: true,
duration: 24000,
ease: 'linear',
})
function createEl(i) {
let el = document.createElement('div');
const strength = utils.round(+stagger([0, 1], {
ease: 'inOutSine',
reversed: true,
from: 'center',
})(el, i, numberOfEls), 100);
const hue = utils.round(360 / numberOfEls * i, 2);
const bgColor = 'hsl('+hue+',40%,60%)';
const rotate = (360 / numberOfEls) * i;
const translateY = '-100%';
const scale = 1;
el.classList.add('el');
utils.set(el, { backgroundColor: bgColor, rotate, translateY, scale });
tl.add(el, {
backgroundColor: [
{to: 'hsl('+hue+','+(40+(20*strength))+'%,'+(60+(20*strength))+'%)'},
{to: bgColor}
],
rotate: [
{to: rotate+(10*strength)},
{to: rotate}
],
translateY: [
{to: '-100' - (10 * strength) + '%'},
{to: translateY}
],
scale: [
{to: [scale, scale+(.25*strength)]},
{to: scale}
],
loop: -1,
}, delay * i);
wrapperEl.appendChild(el);
};
for (let i = 0; i < numberOfEls; i++) createEl(i);
tl.seek(10000);
body {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
position: absolute;
overflow: hidden;
width: 100%;
height: 100%;
}
#wrapper {
position: relative;
display: flex;
align-items: center;
flex-wrap: wrap;
width: 1px;
height: 100vh;
}
#wrapper:before,
#wrapper:after {
content: '';
position: absolute;
top: 50%;
left: 50%;
display: block;
transform: translate(-50%, -50%);
border: 1px solid #FFF;
border-radius: 50%;
}
#wrapper::before {
width: 13vh;
height: 13vh;
}
#wrapper::after {
width: 18vh;
height: 18vh;
}
.el {
position: absolute;
opacity: 1;
width: 12px;
height: 26vh;
top: 50%;
left: 50%;
margin-left: -6px;
margin-top: -13vh;
transform-origin: 50% 50%;
background: white;
}
<link href="https://codepen.io/juliangarnier/pen/ByaMBKr/31455c4a32d8ef013c00f904985e6268" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment