Tarjeta holográfica con inclinación
Se inclina en 3D hacia el puntero y su brillo cambia de color con el ángulo.
Código completo
Es exactamente el archivo que se descarga. Cópialo a tu proyecto y úsalo.
"use client";
/**
* Tarjeta con inclinación 3D que sigue al puntero y una capa holográfica que cambia de color con el ángulo.
* Solo con ratón: en pantallas táctiles y con movimiento reducido se queda quieta.
*
* <HoloTiltCard style={{ width: 320, height: 200 }}>
* <h3>Pase anual</h3>
* </HoloTiltCard>
*/
import { useRef, type CSSProperties, type HTMLAttributes, type PointerEvent } from "react";
export type HoloTiltCardProps = HTMLAttributes<HTMLDivElement> & {
/** Inclinación máxima en grados. */
maxTilt?: number;
};
const CSS = `
.gch-scene { perspective: 900px; display: inline-block; }
.gch-card { --gch-rx: 0deg; --gch-ry: 0deg; --gch-px: 50%; --gch-py: 50%; --gch-o: .3; position: relative; box-sizing: border-box; min-width: 260px; min-height: 160px; padding: 24px; overflow: hidden; border: 1px solid rgba(255, 255, 255, .16); border-radius: 22px; color: #f4f2ff;
background: radial-gradient(120% 90% at 0% 0%, #2b2559 0%, transparent 60%), linear-gradient(160deg, #15122e, #0b0a1b);
box-shadow: 0 30px 60px -20px rgba(8, 5, 40, .7), 0 0 0 1px rgba(0, 0, 0, .4);
transform: rotateX(var(--gch-rx)) rotateY(var(--gch-ry)); transform-style: preserve-3d; transition: transform .7s cubic-bezier(.16, 1, .3, 1), box-shadow .3s; will-change: transform; font-family: inherit; }
.gch-card[data-live="true"] { transition: transform .08s linear, box-shadow .3s; box-shadow: 0 40px 70px -22px rgba(8, 5, 40, .85), 0 0 0 1px rgba(0, 0, 0, .4); }
.gch-card::before, .gch-card::after { content: ""; position: absolute; inset: 0; pointer-events: none; border-radius: inherit; opacity: var(--gch-o); transition: opacity .35s; }
.gch-card::before { mix-blend-mode: color-dodge;
background: repeating-linear-gradient(115deg, rgba(255, 70, 190, .55) 0, rgba(70, 230, 255, .55) 9%, rgba(255, 235, 90, .5) 18%, rgba(130, 255, 160, .5) 27%, rgba(255, 70, 190, .55) 36%) calc(var(--gch-px) * -1.4) 0 / 220% 220%; }
.gch-card::after { background: radial-gradient(circle at var(--gch-px) var(--gch-py), rgba(255, 255, 255, .5), transparent 46%); mix-blend-mode: soft-light; }
.gch-card > * { position: relative; transform: translateZ(24px); }
@media (hover: none), (prefers-reduced-motion: reduce) { .gch-card { transform: none !important; transition: none; } .gch-card::before, .gch-card::after { opacity: .35; } }
`;
export function HoloTiltCard({ maxTilt = 14, className, style, onPointerMove, onPointerLeave, children, ...props }: HoloTiltCardProps) {
const ref = useRef<HTMLDivElement>(null);
function move(event: PointerEvent<HTMLDivElement>) {
const card = ref.current;
if (card && event.pointerType !== "touch") {
const box = card.getBoundingClientRect();
const x = (event.clientX - box.left) / box.width;
const y = (event.clientY - box.top) / box.height;
card.dataset.live = "true";
card.style.setProperty("--gch-ry", `${((x - 0.5) * 2 * maxTilt).toFixed(2)}deg`);
card.style.setProperty("--gch-rx", `${((0.5 - y) * 2 * maxTilt).toFixed(2)}deg`);
card.style.setProperty("--gch-px", `${(x * 100).toFixed(1)}%`);
card.style.setProperty("--gch-py", `${(y * 100).toFixed(1)}%`);
card.style.setProperty("--gch-o", "1");
}
onPointerMove?.(event);
}
function leave(event: PointerEvent<HTMLDivElement>) {
const card = ref.current;
if (card) {
card.dataset.live = "false";
["--gch-rx", "--gch-ry", "--gch-o"].forEach((name) => card.style.removeProperty(name));
card.style.setProperty("--gch-px", "50%");
card.style.setProperty("--gch-py", "50%");
}
onPointerLeave?.(event);
}
return (
<>
<style>{CSS}</style>
<div className="gch-scene">
<div ref={ref} {...props} className={["gch-card", className].filter(Boolean).join(" ")} style={style as CSSProperties} onPointerMove={move} onPointerLeave={leave}>
{children}
</div>
</div>
</>
);
}
Úsalo en tu proyecto
Instálalo con la CLI de shadcn.
npx shadcn@latest add https://www.gassierconsulting.com/r/tarjeta-holograficaEjemplo de uso de Tarjeta holográfica con inclinación
Después de copiar holo-tilt-card.tsx a tu proyecto, impórtalo y colócalo donde lo necesites.
import { HoloTiltCard } from "./holo-tilt-card";
export default function Ejemplo() {
return <HoloTiltCard />;
}Accesibilidad y rendimiento
El archivo tiene 75 líneas (4 KB) y no necesita @keyframes. Esto es lo que hace Tarjeta holográfica con inclinación por quien lo usa:
- Detecta prefers-reduced-motion y baja o quita el movimiento cuando la persona lo pide.
- Reacciona al puntero con eventos pointer (ratón, lápiz y táctil).
- Es un componente de cliente de Next.js: incluye la directiva "use client".
Acerca del producto
Una tarjeta que se inclina en perspectiva siguiendo al puntero, con una capa holográfica de arcoíris que se desplaza con el ángulo y un reflejo de luz. El contenido flota delante de la tarjeta. Con pantallas táctiles o movimiento reducido se queda quieta.
Incluye
Un solo archivo React + TypeScript, con los estilos dentro. No usa Tailwind ni bibliotecas externas.
- Inclinación máxima configurable (maxTilt)
- Capa holográfica con color-dodge y reflejo suave
- Contenido con profundidad (translateZ)
- Sin dependencias ni librerías de animación
Cómo usarlo
Dale tamaño con style o className y pon tu contenido dentro. Funciona mejor sobre fondos oscuros.