html
<div class="confetti left-confetti">
<div class="ribbon red"></div>
</div>
<div class="confetti right-confetti">
<div class="ribbon blue"></div>
</div>
js
<script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.6.0/dist/confetti.browser.min.js"></script>
<script>
window.addEventListener('load', function () {
confetti({
particleCount: 150,
spread: 90,
origin: { x: 0, y: 0.7 },
colors: ['#ff2a2d', '#00c3f3', '#ffcc00']
});
confetti({
particleCount: 150,
spread: 90,
origin: { x: 1, y: 0.7 },
colors: ['#ff2a2d', '#00c3f3', '#ffcc00']
});
setInterval(() => {
confetti({
particleCount: 20,
angle: Math.random() * 360,
spread: 50,
origin: { x: Math.random(), y: 0 },
colors: ['#ff2a2d', '#00c3f3', '#ffcc00'],
ticks: 50
});
}, 1000);
});
</script>
css
.confetti {
position: fixed;
top: 20%;
width: 100px;
height: 100px;
pointer-events: none;
z-index: 9999;
animation: floatUp 6s infinite ease-in-out;
}
.left-confetti {
left: -50px;
}
.right-confetti {
right: -50px;
}
.ribbon {
width: 30px;
height: 100px;
position: absolute;
top: 20px;
left: 50%;
transform: translateX(-50%);
border-radius: 4px;
background: linear-gradient(45deg, #fff, #ccc);
animation: ribbonFlap 2s infinite ease-in-out;
}
.ribbon.red {
background: linear-gradient(45deg, #ff2a2d, #cc2222);
}
.ribbon.blue {
background: linear-gradient(45deg, #007AFF, #005EDD);
}
@keyframes floatUp {
0%,
100% {
transform: translateY(0);
}
50% {
transform: translateY(-20px);
}
}
@keyframes ribbonFlap {
0%,
100% {
transform: translateX(-50%) rotate(-5deg);
}
50% {
transform: translateX(-50%) rotate(5deg);
}
}