AnimatedCursors.tsx 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import { motion } from 'framer-motion'
  2. import { MousePointer2 } from 'lucide-react'
  3. import { useEffect, useState } from 'react'
  4. export const AnimatedCursors = () => {
  5. const [cursor1Position, setCursor1Position] = useState({ x: 20, y: 20 })
  6. const [cursor2Position, setCursor2Position] = useState({ x: 180, y: 80 })
  7. useEffect(() => {
  8. const animateCursors = () => {
  9. const newCursor1Position = {
  10. x: Math.random() * 160 + 20,
  11. y: Math.random() * 80 + 20,
  12. }
  13. const newCursor2Position = {
  14. x: Math.random() * 160 + 20,
  15. y: Math.random() * 80 + 20,
  16. }
  17. setCursor1Position(newCursor1Position)
  18. setCursor2Position(newCursor2Position)
  19. }
  20. const initialTimer = setTimeout(animateCursors, 1000)
  21. const interval = setInterval(animateCursors, 3000)
  22. return () => {
  23. clearTimeout(initialTimer)
  24. clearInterval(interval)
  25. }
  26. }, [])
  27. return (
  28. <div className="relative w-48 h-32 mx-auto mb-8">
  29. <motion.div
  30. className="absolute text-warning"
  31. animate={{ x: cursor1Position.x, y: cursor1Position.y }}
  32. transition={{
  33. duration: 1.2,
  34. ease: 'easeInOut',
  35. }}
  36. style={{ width: 20, height: 20 }}
  37. >
  38. <MousePointer2 size={20} />
  39. </motion.div>
  40. <motion.div
  41. className="absolute text-brand"
  42. animate={{ x: cursor2Position.x, y: cursor2Position.y }}
  43. transition={{
  44. duration: 1.2,
  45. ease: 'easeInOut',
  46. delay: 0.2,
  47. }}
  48. style={{ width: 20, height: 20 }}
  49. >
  50. <MousePointer2 size={20} />
  51. </motion.div>
  52. </div>
  53. )
  54. }