BlobCursor
react-bits/BlobCursor-JS-TWFreeComponent
Organic blob cursor that smoothly follows the pointer with inertia and elastic morphing.
Live preview
live · rendered by the registry
Rendered by @react-bits on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://www.reactbits.dev/r/BlobCursor-JS-TW.jsonSource
1'use client';23import { useRef, useEffect, useCallback } from 'react';4import gsap from 'gsap';56export default function BlobCursor({7 blobType = 'circle',8 fillColor = '#5227FF',9 trailCount = 3,10 sizes = [60, 125, 75],11 innerSizes = [20, 35, 25],12 innerColor = 'rgba(255,255,255,0.8)',13 opacities = [0.6, 0.6, 0.6],14 shadowColor = 'rgba(0,0,0,0.75)',15 shadowBlur = 5,16 shadowOffsetX = 10,17 shadowOffsetY = 10,18 filterId = 'blob',19 filterStdDeviation = 30,20 filterColorMatrixValues = '1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 35 -10',21 useFilter = true,22 fastDuration = 0.1,23 slowDuration = 0.5,24 fastEase = 'power3.out',25 slowEase = 'power1.out',26 zIndex = 10027}) {28 const containerRef = useRef(null);29 const blobsRef = useRef([]);3031 const updateOffset = useCallback(() => {32 if (!containerRef.current) return { left: 0, top: 0 };33 const rect = containerRef.current.getBoundingClientRect();34 return { left: rect.left, top: rect.top };35 }, []);3637 const handleMove = useCallback(38 e => {39 const { left, top } = updateOffset();40 const x = 'clientX' in e ? e.clientX : e.touches[0].clientX;41 const y = 'clientY' in e ? e.clientY : e.touches[0].clientY;4243 blobsRef.current.forEach((el, i) => {44 if (!el) return;45 const isLead = i === 0;46 gsap.to(el, {47 x: x - left,48 y: y - top,49 duration: isLead ? fastDuration : slowDuration,50 ease: isLead ? fastEase : slowEase51 });52 });53 },54 [updateOffset, fastDuration, slowDuration, fastEase, slowEase]55 );5657 useEffect(() => {58 const onResize = () => updateOffset();59 window.addEventListener('resize', onResize);60 return () => window.removeEventListener('resize', onResize);61 }, [updateOffset]);6263 return (64 <div65 ref={containerRef}66 onMouseMove={handleMove}67 onTouchMove={handleMove}68 className="relative top-0 left-0 w-full h-full"69 style={{ zIndex }}70 >71 {useFilter && (72 <svg className="absolute w-0 h-0">73 <filter id={filterId}>74 <feGaussianBlur in="SourceGraphic" result="blur" stdDeviation={filterStdDeviation} />75 <feColorMatrix in="blur" values={filterColorMatrixValues} />76 </filter>77 </svg>78 )}7980 <div81 className="pointer-events-none absolute inset-0 overflow-hidden select-none cursor-default"82 style={{ filter: useFilter ? `url(#${filterId})` : undefined }}83 >84// … truncated
What it pulls in
npm packages
Files it writes
More from @react-bits
All 556 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| AnimatedContentAnimatedContent-JS-CSS | @react-bits | Components | Free | 1 dep | |
| AnimatedContentAnimatedContent-JS-TW | @react-bits | Components | Free | 1 dep | |
| AnimatedContentAnimatedContent-TS-CSS | @react-bits | Components | Free | 1 dep | |
| AnimatedContentAnimatedContent-TS-TW | @react-bits | Components | Free | 1 dep | |
| AnimatedListAnimatedList-JS-CSS | @react-bits | Components | Free | 1 dep · 2 files | |
| AnimatedListAnimatedList-JS-TW | @react-bits | Components | Free | 1 dep | |
| AnimatedListAnimatedList-TS-CSS | @react-bits | Components | Free | 1 dep · 2 files | |
| AnimatedListAnimatedList-TS-TW | @react-bits | Components | Free | 1 dep |
