bend-button-follower
pixel-perfect/bend-button-followerFreeBlock
A rounded pill button with text that smoothly chases the cursor and warps with an air-friction bend on a WebGL plane.
Install it
npx shadcn@latest add https://www.pixel-perfect.space/r/bend-button-follower.jsonSource
1"use client";23/**4 * A rounded button that smoothly trails the cursor, settling just to the bottom-right of it.5 */67import { useEffect, useRef } from "react";89const LABEL = "HOVER ME";10const GAP = 16; // how far below-right of the cursor the button settles11const lerp = (a: number, b: number, t: number) => a + (b - a) * t;1213const Page = () => {14 const containerRef = useRef<HTMLDivElement>(null);15 const btnRef = useRef<HTMLDivElement>(null);1617 useEffect(() => {18 const container = containerRef.current;19 const btn = btnRef.current;20 if (!container || !btn) return;2122 const target = { x: 0, y: 0 }; // cursor + offset23 const state = { x: 0, y: 0 }; // where the button actually is (lags behind)24 let inside = false;25 let raf = 0;2627 const onMove = (e: PointerEvent) => {28 const r = container.getBoundingClientRect();29 inside =30 e.clientX >= r.left &&31 e.clientX <= r.right &&32 e.clientY >= r.top &&33 e.clientY <= r.bottom;34 if (inside) {35 target.x = e.clientX - r.left + GAP;36 target.y = e.clientY - r.top + GAP;37 }38 };3940 const tick = () => {41 state.x = lerp(state.x, target.x, 0.12);42 state.y = lerp(state.y, target.y, 0.12);43 btn.style.transform = `translate(${state.x}px, ${state.y}px)`;44 btn.style.opacity = inside ? "1" : "0";45 raf = requestAnimationFrame(tick);46 };4748 window.addEventListener("pointermove", onMove);49 raf = requestAnimationFrame(tick);50 return () => {51 window.removeEventListener("pointermove", onMove);52 cancelAnimationFrame(raf);53 };54 }, []);5556 return (57 <div ref={containerRef} className="absolute inset-0 overflow-hidden">58 <div59 ref={btnRef}60 className="pointer-events-none absolute left-0 top-0 whitespace-nowrap rounded-full bg-foreground px-8 py-4 text-base font-semibold tracking-wide text-background opacity-0 shadow-lg transition-opacity"61 >62 {LABEL}63 </div>64 </div>65 );66};6768export default Page;
Files it writes
More from pixel-perfect
All 332 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| 3d-button3d-button | pixel-perfect | Blocks | Free | 2 deps | |
| abhinav-bento-buttonabhinav-bento-button | pixel-perfect | Blocks | Free | no deps | |
| accordion-carouselaccordion-carousel | pixel-perfect | Blocks | Free | 1 dep | |
| accordion-foldaccordion-fold | pixel-perfect | Blocks | Free | 1 dep | |
| activity-wheel-motionactivity-wheel-motion | pixel-perfect | Blocks | Free | 2 deps | |
| animated-textureanimated-texture | pixel-perfect | Blocks | Free | 1 dep | |
| aperture-mask-revealaperture-mask-reveal | pixel-perfect | Blocks | Free | 1 dep | |
| aurora-curtainaurora-curtain | pixel-perfect | Blocks | Free | no deps |
