Made with anime.js v4 (https://animejs.com)
A Pen by Julian Garnier on CodePen.
| <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" /> |
Made with anime.js v4 (https://animejs.com)
A Pen by Julian Garnier on CodePen.