最新
动画Fade In On Scroll
Content that fades and rises into place as it enters the viewport.
#scroll#reveal#fade
6 个框架中级
A button that bursts confetti particles from its center on click.
<!-- Particles are absolutely positioned inside this wrapper - never the document. -->
<style>
@keyframes confetti {
0% { transform: translate(0, 0) rotate(0deg); opacity: 1; }
100% { transform: translate(var(--dx), var(--dy)) rotate(var(--rot)); opacity: 0; }
}
</style>
<div class="confetti relative inline-flex">
<span class="confetti-origin pointer-events-none absolute left-1/2 top-0 h-0 w-0"></span>
<button type="button" class="confetti-btn relative rounded-lg bg-gray-900 px-5 py-2.5 text-sm font-semibold text-white hover:bg-gray-700 dark:bg-white dark:text-gray-900 dark:hover:bg-gray-200">
Celebrate
</button>
</div>
<script>
(function () {
var wrap = document.querySelector('.confetti');
if (!wrap) return;
var origin = wrap.querySelector('.confetti-origin');
var btn = wrap.querySelector('.confetti-btn');
var colors = ['#6366f1', '#ec4899', '#f59e0b', '#10b981', '#3b82f6'];
btn.addEventListener('click', function () {
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
for (var i = 0; i < 24; i++) {
var a = Math.random() * Math.PI * 2, d = 50 + Math.random() * 80;
var p = document.createElement('span');
p.style.cssText =
'position:absolute;width:8px;height:8px;border-radius:2px;background:' + colors[i % colors.length] +
';--dx:' + Math.cos(a) * d + 'px;--dy:' + (Math.sin(a) * d - 30) + 'px;--rot:' +
(Math.random() * 720 - 360) + 'deg;animation:confetti 900ms ease-out forwards';
origin.appendChild(p);
}
setTimeout(function () { origin.innerHTML = ''; }, 1000);
});
})();
</script>| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
label | string | 'Celebrate' | 加载时朗读的无障碍标签。 |
particleCount | number | 24 | Particle count |
className | string | '' | 合并到根元素上的额外类名。 |
Set `particleCount` and recolor the particles. The burst is scoped to the component wrapper and a reduced-motion click is a no-op.