Efecto de partículas de código flotante en el fondo
El efecto de partículas de código flotando en el fondo es una forma sutil pero poderosa de darle personalidad a tu sitio web, especialmente si eres desarrollador.
🎮 Pruébalo en vivo
Aquí puedes experimentar con las diferentes configuraciones del componente:
Demo interactiva
Deja vacío para usar los valores por defecto
#505050
🛠️ Cómo usar el componente
Simplemente importa y usa CodeParticles con las props que necesites:
---
import CodeParticles from '@/components/CodeParticles.astro'
---
<!-- Configuración por defecto -->
<CodeParticles />
<!-- Personalizado -->
<CodeParticles
opacity={0.3}
animationDuration={5}
particleCount={30}
distribution='full'
color='#ff000050'
customSnippets={['React', 'Vue', 'Angular', 'Svelte', 'Astro']}
/>
Props disponibles
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
opacity | number | 0.2 | Opacidad de las partículas (0-1) |
animationDuration | number | 2 | Duración de la animación en segundos |
particleCount | number | 20 | Número de partículas a generar |
distribution | 'margins' | 'full' | 'margins' | Distribución de partículas |
color | string | '#505050' | Color de las partículas |
customSnippets | string[] | Ver descripción | Array de snippets personalizados |
💻 El código del componente
Aquí está la implementación completa:
---
interface Props {
opacity?: number
animationDuration?: number
particleCount?: number
distribution?: 'margins' | 'full'
color?: string
}
const {
opacity = 0.2,
animationDuration = 2,
particleCount = 20,
distribution = 'margins',
color = '#50505090'
} = Astro.props
---
<div class='code-background' aria-hidden='true'></div>
<style>
.code-background {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 0;
pointer-events: none;
overflow: hidden;
}
@keyframes float {
0% {
transform: translateY(0) rotate(0deg);
}
100% {
transform: translateY(-20%) rotate(2deg);
}
}
</style>
<script define:vars={{ opacity, animationDuration, particleCount, distribution, color }}>
const codeBackground = document.querySelector('.code-background')
if (codeBackground) {
const codeSnippets = [
'{ }',
'[ ]',
'( )',
'=>',
'const',
'let',
'function',
'<div>',
'</>',
'import',
'export'
]
const generateParticles = () => {
codeBackground.innerHTML = ''
const viewportWidth = window.innerWidth
const viewportHeight = window.innerHeight
for (let i = 0; i < particleCount; i++) {
const particle = document.createElement('div')
particle.textContent = codeSnippets[Math.floor(Math.random() * codeSnippets.length)]
particle.style.position = 'fixed'
particle.style.fontSize = Math.random() * 15 + 12 + 'px'
particle.style.opacity = String(opacity)
particle.style.fontFamily = 'Courier New, monospace'
particle.style.color = color
particle.style.animation = `float ${animationDuration}s linear infinite alternate`
particle.style.pointerEvents = 'none'
if (distribution === 'full') {
particle.style.left = Math.random() * viewportWidth + 'px'
particle.style.top = Math.random() * viewportHeight + 'px'
} else {
const zone = Math.floor(Math.random() * 3)
if (zone === 0) {
particle.style.left = Math.random() * viewportWidth + 'px'
particle.style.top = Math.random() * (viewportHeight * 0.25) + 'px'
} else if (zone === 1) {
particle.style.left = Math.random() * (viewportWidth * 0.15) + 'px'
particle.style.top = Math.random() * viewportHeight + 'px'
} else {
particle.style.left =
viewportWidth * 0.85 + Math.random() * (viewportWidth * 0.15) + 'px'
particle.style.top = Math.random() * viewportHeight + 'px'
}
}
codeBackground.appendChild(particle)
}
}
generateParticles()
let resizeTimeout
window.addEventListener('resize', () => {
clearTimeout(resizeTimeout)
resizeTimeout = setTimeout(generateParticles, 250)
})
}
</script>
✨ Por qué funciona
- Basado en viewport: Usa
position: fixedy calcula posiciones conwindow.innerWidth/Height - Responsive: Se regenera automáticamente al redimensionar la ventana
- No distrae: Las partículas están en los márgenes o donde tú elijas
- Configurable: Todas las props son opcionales con valores sensatos por defecto
- Performance:
pointer-events: noneasegura que no interfiera con la interacción
¡Gracias por leer!