All checks were successful
continuous-integration/drone/push Build is passing
126 lines
3.9 KiB
JavaScript
126 lines
3.9 KiB
JavaScript
// Version 4: Extended Loop with Smooth Transitions
|
|
// Creates a much longer animation cycle that loops smoothly without harsh resets
|
|
const staggerVisualizerEl = document.querySelector('.stagger-visualizer');
|
|
const fragment = document.createDocumentFragment();
|
|
const grid = [12, 6];
|
|
const col = grid[0];
|
|
const row = grid[1];
|
|
const numberOfElements = col * row;
|
|
|
|
for (let i = 0; i < numberOfElements; i++) {
|
|
let div = document.createElement('div');
|
|
div.className = 'part';
|
|
div.dataset.index = i;
|
|
fragment.appendChild(div);
|
|
}
|
|
|
|
staggerVisualizerEl.appendChild(fragment);
|
|
|
|
// Extended animation cycle - 20 seconds total, much longer so loop is less jarring
|
|
const staggersAnimation = anime.createTimeline({
|
|
easing: 'easeInOutSine',
|
|
loop: true,
|
|
autoplay: false
|
|
});
|
|
|
|
staggersAnimation
|
|
// Initial expansion phase
|
|
.add('.part', {
|
|
translateX: anime.stagger('-.15rem', { grid: grid, from: 'center', axis: 'x' }),
|
|
translateY: anime.stagger('-.15rem', { grid: grid, from: 'center', axis: 'y' }),
|
|
scale: 0.5,
|
|
duration: 300,
|
|
easing: 'easeOutQuad',
|
|
delay: anime.stagger(60, { grid: grid, from: 'center' })
|
|
}, 0)
|
|
|
|
// Chaotic burst phase
|
|
.add('.part', {
|
|
translateX: (el, i) => anime.utils.random(-10, 10),
|
|
translateY: (el, i) => anime.utils.random(-10, 10),
|
|
scale: (el) => anime.utils.random(0.7, 1.3),
|
|
rotate: (el) => anime.utils.random(-120, 120),
|
|
duration: 800,
|
|
easing: 'easeOutQuad',
|
|
delay: anime.stagger(80, { grid: grid, from: 'center' })
|
|
})
|
|
|
|
// Floating drift phase 1
|
|
.add('.part', {
|
|
translateY: (el, i) => anime.utils.random(-6, 6),
|
|
rotate: (el) => anime.utils.random(-60, 60),
|
|
duration: 2000,
|
|
easing: 'easeInOutSine',
|
|
delay: (el, i) => i * 20 + anime.utils.random(-200, 200)
|
|
})
|
|
|
|
// Gentle swirl inward
|
|
.add('.part', {
|
|
translateX: (el, i) => anime.utils.random(-5, 5),
|
|
translateY: (el, i) => anime.utils.random(-5, 5),
|
|
rotate: (el) => anime.utils.random(-45, 45),
|
|
duration: 1500,
|
|
easing: 'easeInOutQuad',
|
|
delay: anime.stagger(50, { grid: grid, from: 'center' })
|
|
})
|
|
|
|
// Floating drift phase 2 - different direction
|
|
.add('.part', {
|
|
translateY: (el, i) => anime.utils.random(-8, 8),
|
|
rotate: (el) => anime.utils.random(-30, 30),
|
|
duration: 2200,
|
|
easing: 'easeInOutSine',
|
|
delay: (el, i) => i * 22 + anime.utils.random(-150, 150)
|
|
})
|
|
|
|
// Slow convergence
|
|
.add('.part', {
|
|
translateX: (el) => anime.utils.random(-2, 2),
|
|
translateY: (el) => anime.utils.random(-2, 2),
|
|
rotate: (el) => anime.utils.random(-15, 15),
|
|
duration: 1800,
|
|
easing: 'easeInOutQuad',
|
|
delay: anime.stagger(60, { grid: grid, from: 'center' })
|
|
})
|
|
|
|
// Gentle return to center with subtle movement
|
|
.add('.part', {
|
|
translateX: (el) => {
|
|
const index = parseInt(el.dataset.index);
|
|
return anime.utils.random(-1, 1);
|
|
},
|
|
translateY: (el) => {
|
|
const index = parseInt(el.dataset.index);
|
|
return anime.utils.random(-1, 1);
|
|
},
|
|
rotate: 0,
|
|
scale: 1,
|
|
opacity: 1,
|
|
duration: 2500,
|
|
easing: 'easeOutQuad',
|
|
delay: anime.stagger(50, { grid: grid, from: 'center' })
|
|
})
|
|
|
|
// Long rest phase with breathing effect
|
|
.add('.part', {
|
|
scale: (el) => anime.utils.random(0.95, 1.05),
|
|
opacity: (el) => anime.utils.random(0.8, 1),
|
|
duration: 3000,
|
|
easing: 'easeInOutSine',
|
|
delay: (el, i) => i * 15
|
|
})
|
|
|
|
// Return to perfect rest
|
|
.add('.part', {
|
|
translateX: 0,
|
|
translateY: 0,
|
|
rotate: 0,
|
|
scale: 1,
|
|
opacity: 1,
|
|
duration: 1500,
|
|
easing: 'easeOutQuad',
|
|
delay: anime.stagger(40, { grid: grid, from: 'center' })
|
|
});
|
|
|
|
staggersAnimation.play();
|