Ir al contenido
Evaluar mi proyecto
Componentes · FondosDisponible

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.

fondo-haces.tsx51 líneas
Descargar
"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.

terminal.sh1 líneas
npx shadcn@latest add https://www.gassierconsulting.com/r/fondo-haces

Ejemplo 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.

ejemplo.tsx5 líneas
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.

PropiedadTipoDescripción
color?stringOpcional.
children?ReactNodeOpcional.
className?stringOpcional.
style?CSSPropertiesOpcional.

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.

VariableValor 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".
Licencia
MIT
Dependencias
React >=18
Compatibilidad
React 18 y 19 · Next.js (componente de cliente)