<div class='animation-example'>
<div class='set-1'>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
</div>
<div class='set-2'>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
<div class='block'></div>
</div>
<div class='dots'>
<div class='dot -active'></div>
<div class='dot'></div>
<div class='dot'></div>
<div class='dot'></div>
<div class='dot'></div>
</div>
</div>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
@size: 5vmin;
.animation-example {
position: relative;
height: 100vh;
width: 100vw;
overflow: hidden;
> .set-1 {
height: @size * 12;
width: @size * 12;
position: absolute;
top: 50%;
left: 0%;
transform: translateX(20%) translateY(-50%) rotate(45deg) scale(1);
}
> .set-1 > .block {
display: inline-block;
position: relative;
float: left;
height: @size;
width: @size;
margin: @size;
background: #EA638C;
}
> .set-2 {
height: @size * 12;
width: @size * 12;
position: absolute;
top: 50%;
left: 150%;
transform: translateX(-50%) translateY(-50%) rotate(0) scale(0);
}
> .set-2 > .block {
display: inline-block;
position: relative;
float: left;
height: @size;
width: @size;
margin: @size;
background: #FFFFFF;
}
> .dots {
position: absolute;
bottom: 32px;
left: 50%;
transform: translateX(-50%);
width: 100%;
text-align: center;
}
> .dots > .dot {
position: relative;
display: inline-block;
margin: 0 16px;
height: 16px;
width: 16px;
border-radius: 50%;
background: #000000;
}
> .dots > .dot::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
height: 10px;
width: 10px;
border-radius: 50%;
transform: translateX(-50%) translateY(-50%);
background: #FFFFFF;
opacity: 0;
transition: opacity .5s ease-in-out;
transition-delay: .3s;
}
> .dots > .dot.-active::after {
opacity: 1;
}
}
View Compiled
// 1. Get elements
const example = document.querySelector('.animation-example');
const set1 = example.querySelector('.set-1');
const set2 = example.querySelector('.set-2');
const blocks1 = set1.querySelectorAll('.block');
const blocks2 = set2.querySelectorAll('.block');
const dots = example.querySelectorAll('.dot');
// 2. Set the states
const states = [
// #1
{
randomRotateMod: 0,
example: {
background: 'rgb(255,255,255)'
},
set1: {
top: '50%',
left: '0%',
translateX: '20%',
translateY: '-50%',
rotate: '45deg',
scale: '1'
},
set2: {
top: '50%',
left: '150%',
translateX: '-50%',
translateY: '-50%',
rotate: '0deg',
scale: '0'
},
blocks1: {
scale: '0.5'
},
blocks2: {
scale: '1'
}
},
// #2
{
randomRotateMod: 1,
example: {
background: 'rgb(255,255,255)'
},
set1: {
top: '50%',
left: '50%',
translateX: '40%',
translateY: '100%',
rotate: '90deg',
scale: '15'
},
set2: {
top: '50%',
left: '50%',
translateX: '-50%',
translateY: '-50%',
rotate: '-90deg',
scale: '0'
},
blocks1: {
scale: '2.5'
},
blocks2: {
scale: '0.1'
}
},
// #3
{
randomRotateMod: 1,
example: {
background: 'rgb(255,255,255)'
},
set1: {
top: '50%',
left: '50%',
translateX: '-50%',
translateY: '-50%',
rotate: '120deg',
scale: '5.0'
},
set2: {
top: '50%',
left: '50%',
translateX: '-50%',
translateY: '-50%',
rotate: '-45deg',
scale: '5.5'
},
blocks1: {
scale: '2.5'
},
blocks2: {
scale: '0.1'
}
},
// #4
{
randomRotateMod: 0,
example: {
background: 'rgb(234,99,140)'
},
set1: {
top: '50%',
left: '50%',
translateX: '-50%',
translateY: '-50%',
rotate: '270deg',
scale: '5.0'
},
set2: {
top: '50%',
left: '50%',
translateX: '-50%',
translateY: '-50%',
rotate: '-180deg',
scale: '1.7'
},
blocks1: {
scale: '4'
},
blocks2: {
scale: '1.02'
}
},
// #5
{
randomRotateMod: 5,
example: {
background: 'rgb(255,255,255)'
},
set1: {
top: '50%',
left: '50%',
translateX: '-50%',
translateY: '-50%',
rotate: '180deg',
scale: '1.2'
},
set2: {
top: '50%',
left: '50%',
translateX: '-50%',
translateY: '-50%',
rotate: '-180deg',
scale: '2'
},
blocks1: {
scale: '2.1'
},
blocks2: {
scale: '0'
}
}
];
// 3. Init the first state
anime({
targets: example,
backgroundColor: states[0].example.background,
duration: 0
});
anime({
targets: set1,
top: states[0].set1.top,
left: states[0].set1.left,
translateX: states[0].set1.translateX,
translateY: states[0].set1.translateY,
rotate: states[0].set1.rotate,
scale: states[0].set1.scale,
duration: 0
});
anime({
targets: set2,
top: states[0].set2.top,
left: states[0].set2.left,
translateX: states[0].set2.translateX,
translateY: states[0].set2.translateY,
rotate: states[0].set2.rotate,
scale: states[0].set2.scale,
duration: 0
});
for (block of blocks1) {
anime({
targets: block,
scale: states[0].blocks1.scale,
rotate: `${(Math.random() * 30 - 15) * states[0].randomRotateMod}deg`,
duration: 0
});
}
for (block of blocks2) {
anime({
targets: block,
scale: states[0].blocks2.scale,
rotate: `${(Math.random() * 30 - 15) * states[0].randomRotateMod}deg`,
duration: 0
});
}
// 4. Set interval or change the states manually
let currentStateIndex = 0;
setInterval(() => {
const nextStateIndex = (currentStateIndex + 1) % states.length;
anime({
targets: example,
backgroundColor: states[nextStateIndex].example.background,
duration: 1000,
easing: 'easeInOutQuint'
});
anime({
targets: set1,
top: states[nextStateIndex].set1.top,
left: states[nextStateIndex].set1.left,
translateX: states[nextStateIndex].set1.translateX,
translateY: states[nextStateIndex].set1.translateY,
rotate: states[nextStateIndex].set1.rotate,
scale: states[nextStateIndex].set1.scale,
duration: 1000,
easing: 'easeInOutQuint'
});
anime({
targets: set2,
top: states[nextStateIndex].set2.top,
left: states[nextStateIndex].set2.left,
translateX: states[nextStateIndex].set2.translateX,
translateY: states[nextStateIndex].set2.translateY,
rotate: states[nextStateIndex].set2.rotate,
scale: states[nextStateIndex].set2.scale,
duration: 1000,
easing: 'easeInOutQuint'
});
for (block of blocks1) {
anime({
targets: block,
scale: states[nextStateIndex].blocks1.scale,
rotate: `${(Math.random() * 30 - 15) * states[nextStateIndex].randomRotateMod}deg`,
duration: 1000,
easing: 'easeInOutQuint'
});
}
for (block of blocks2) {
anime({
targets: block,
scale: states[nextStateIndex].blocks2.scale,
rotate: `${(Math.random() * 30 - 15) * states[nextStateIndex].randomRotateMod}deg`,
duration: 1000,
easing: 'easeInOutQuint'
});
}
for (let i = 0; i < states.length; i++) {
if (i <= nextStateIndex) {
dots[i].classList.add('-active');
} else {
dots[i].classList.remove('-active');
}
}
currentStateIndex = nextStateIndex;
}, 2000);
View Compiled
This Pen doesn't use any external CSS resources.