Fondo de rejilla con haces de luz
Rejilla técnica con haces que recorren las líneas como corriente en un circuito; solo CSS y con pausa.
Datos en movimiento
Código completo
Es exactamente el archivo que se descarga. Cópialo a tu proyecto y úsalo.
"use client";
import { useState, type CSSProperties, type ReactNode } from "react";
/** Fondo de rejilla técnica con haces de luz que recorren las líneas, al estilo de un plano de circuitos. Solo CSS, con botón de pausa. React + TypeScript, sin dependencias. */
export type FondoHacesProps = {
color?: string;
children?: ReactNode;
className?: string;
style?: CSSProperties;
};
const CSS = `
.gcfha-root { box-sizing: border-box; position: relative; isolation: isolate; container-type: inline-size; width: 100%; min-height: 480px; overflow: hidden; display: grid; place-items: center; color: #e6f0ff; background: radial-gradient(80% 60% at 50% 0%, #0e1c3d, #05080f 75%); font: 500 16px/1.5 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif; }
.gcfha-root *, .gcfha-root *::before, .gcfha-root *::after { box-sizing: border-box; }
.gcfha-root :focus-visible { outline: 2px solid #7fb2ff; outline-offset: 3px; }
.gcfha-root[data-paused="true"] .gcfha-beam { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) { .gcfha-beam { animation: none !important; opacity: .4; } }
.gcfha-grid { position: absolute; inset: 0; z-index: -2; background-image: linear-gradient(rgba(120, 170, 255, .14) 1px, transparent 1px), linear-gradient(90deg, rgba(120, 170, 255, .14) 1px, transparent 1px); background-size: 56px 56px; -webkit-mask: radial-gradient(ellipse at 50% 40%, #000 25%, transparent 75%); mask: radial-gradient(ellipse at 50% 40%, #000 25%, transparent 75%); }
.gcfha-beam { position: absolute; z-index: -1; border-radius: 99px; background: linear-gradient(90deg, transparent, var(--gcfha-c, #5fa0ff), #fff, transparent); filter: drop-shadow(0 0 6px var(--gcfha-c, #5fa0ff)); will-change: transform; }
.gcfha-h { height: 2px; width: 140px; left: 0; top: var(--p); animation: gcfha-h var(--t) linear var(--d) infinite; }
.gcfha-v { width: 2px; height: 140px; top: 0; left: var(--p); background: linear-gradient(180deg, transparent, var(--gcfha-c, #5fa0ff), #fff, transparent); animation: gcfha-v var(--t) linear var(--d) infinite; }
.gcfha-pause { position: absolute; right: 14px; bottom: 14px; z-index: 3; display: inline-flex; align-items: center; gap: 6px; min-height: 36px; padding: 0 12px; border: 1px solid #2a3a63; border-radius: 999px; background: rgba(8, 14, 30, .7); color: #cfe0ff; font: 600 12px/1 ui-sans-serif, system-ui, sans-serif; cursor: pointer; }
.gcfha-pause:hover { border-color: #5a74b8; }
@keyframes gcfha-h { from { transform: translateX(-160px); } to { transform: translateX(110cqi); } }
@keyframes gcfha-v { from { transform: translateY(-160px); } to { transform: translateY(1200px); } }`;
const H = [112, 224, 336, 56, 280];
const V = [168, 392, 616, 112, 504, 728];
export function FondoHaces({ color = "#5fa0ff", children, className = "", style }: FondoHacesProps) {
const [paused, setPaused] = useState(false);
return (
<section className={`gcfha-root ${className}`} style={{ "--gcfha-c": color, ...style } as CSSProperties} data-paused={paused}>
<style>{CSS}</style>
<div className="gcfha-grid" aria-hidden="true" />
{H.map((p, i) => (
<span key={`h${i}`} className="gcfha-beam gcfha-h" aria-hidden="true" style={{ "--p": `${p}px`, "--t": `${5 + (i % 3) * 1.7}s`, "--d": `${-i * 1.3}s` } as CSSProperties} />
))}
{V.map((p, i) => (
<span key={`v${i}`} className="gcfha-beam gcfha-v" aria-hidden="true" style={{ "--p": `${p}px`, "--t": `${6 + (i % 3) * 1.4}s`, "--d": `${-i * 1.1}s` } as CSSProperties} />
))}
{children}
<button className="gcfha-pause" type="button" aria-pressed={paused} onClick={() => setPaused((value) => !value)}>
<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">{paused ? <path d="M7 4v16l13-8z" /> : <path d="M6 4h4v16H6zM14 4h4v16h-4z" />}</svg>
{paused ? "Reanudar" : "Pausar"} fondo
</button>
</section>
);
}
Úsalo en tu proyecto
Instálalo con la CLI de shadcn.
npx shadcn@latest add https://www.gassierconsulting.com/r/fondo-hacesEjemplo de uso de Fondo de rejilla con haces de luz
Después de copiar fondo-haces.tsx a tu proyecto, impórtalo y colócalo donde lo necesites.
import { FondoHaces } from "./fondo-haces";
export default function Ejemplo() {
return <FondoHaces color="Ejemplo">Contenido</FondoHaces>;
}Propiedades de FondoHaces
FondoHaces acepta 4 propiedades: todas son opcionales y tienen un valor por defecto, así que funciona sin configurar nada.
| Propiedad | Tipo | Descripción |
|---|---|---|
color? | string | Opcional. |
children? | ReactNode | Opcional. |
className? | string | Opcional. |
style? | CSSProperties | Opcional. |
Personaliza Fondo de rejilla con haces de luz con variables CSS
Define estas variables en el contenedor o en tu hoja de estilos para cambiar los colores sin tocar el componente. Si no las defines, se usa el valor por defecto.
| Variable | Valor por defecto |
|---|---|
--gcfha-c | #5fa0ff |
Accesibilidad y rendimiento
El archivo tiene 51 líneas (4 KB) y define 2 animaciones con @keyframes. Esto es lo que hace Fondo de rejilla con haces de luz por quien lo usa:
- Detecta prefers-reduced-motion y baja o quita el movimiento cuando la persona lo pide.
- Muestra un anillo de foco visible al navegar con teclado (:focus-visible).
- Expone su estado a tecnologías de apoyo con atributos aria-*.
- Es un componente de cliente de Next.js: incluye la directiva "use client".