You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React自定义光标点击时缩放动画实现求助

实现React自定义光标点击缩小动画

我在React应用中实现了自定义光标组件,并在Index.js中引入使用,希望实现用户点击时光标缩小等动画效果。作为前端开发新手,不清楚如何通过事件监听切换光标类名来实现该效果,恳请帮助。

原组件代码:

import React, { useRef } from 'react'

function CustomCursor() {

const cursorRef = useRef(null)

React.useEffect(() => {
    document.addEventListener('mousemove', (event)=>  {
        const {clientX, clientY} = event;
        const mouseX = clientX - cursorRef.current.clientWidth /2;
        const mouseY = clientY - cursorRef.current.clientHeight /2;
        cursorRef.current.style.transform = `translate3d(${mouseX}px, ${mouseY}px, 0)`
    })
}, [])

    return ( <div className='custom-cursor' ref={cursorRef}></div> ) }

export default CustomCursor 

原CSS样式:

.custom-cursor {
  z-index: 9999;
  border-radius: 50%;
  width: 20px;
  height: 20px;
  background-color: #8c8c8cb8;
  pointer-events: none;
  overflow: hidden;
  transform: translate(-50%, -50%);
  position: fixed;
}

解决方案

步骤1:添加状态管理类名切换

在组件中引入useState钩子,用来控制光标是否处于点击状态。

步骤2:添加鼠标点击事件监听

在useEffect中添加mousedown和mouseup事件,分别切换点击状态的布尔值,从而切换类名。

步骤3:编写CSS动画样式

新增一个.custom-cursor.clicked类,定义缩小的动画效果,同时给原光标类添加过渡效果让动画更平滑。

修改后的组件代码:

import React, { useRef, useState, useEffect } from 'react'

function CustomCursor() {
  const cursorRef = useRef(null)
  // 控制点击状态
  const [isClicked, setIsClicked] = useState(false)

  useEffect(() => {
    const handleMouseMove = (event) => {
      const {clientX, clientY} = event;
      const mouseX = clientX - cursorRef.current.clientWidth /2;
      const mouseY = clientY - cursorRef.current.clientHeight /2;
      cursorRef.current.style.transform = `translate3d(${mouseX}px, ${mouseY}px, 0)`
    }

    const handleMouseDown = () => {
      setIsClicked(true)
    }

    const handleMouseUp = () => {
      setIsClicked(false)
    }

    // 添加事件监听
    document.addEventListener('mousemove', handleMouseMove)
    document.addEventListener('mousedown', handleMouseDown)
    document.addEventListener('mouseup', handleMouseUp)

    // 组件卸载时移除监听,避免内存泄漏
    return () => {
      document.removeEventListener('mousemove', handleMouseMove)
      document.removeEventListener('mousedown', handleMouseDown)
      document.removeEventListener('mouseup', handleMouseUp)
    }
  }, [])

  // 根据isClicked状态拼接类名
  const cursorClass = `custom-cursor ${isClicked ? 'clicked' : ''}`

  return ( <div className={cursorClass} ref={cursorRef}></div> )
}

export default CustomCursor 

修改后的CSS样式:

.custom-cursor {
  z-index: 9999;
  border-radius: 50%;
  width: 20px;
  height: 20px;
  background-color: #8c8c8cb8;
  pointer-events: none;
  overflow: hidden;
  transform: translate(-50%, -50%);
  position: fixed;
  /* 添加过渡效果,让尺寸变化更平滑 */
  transition: all 0.2s ease;
}

/* 点击时的缩小样式 */
.custom-cursor.clicked {
  width: 12px;
  height: 12px;
  background-color: #5a5a5ab8;
}

说明

  • 用useState创建isClicked状态,鼠标按下时设为true,松开时设为false。
  • 在useEffect中统一管理所有事件监听,并在组件卸载时移除,防止内存泄漏。
  • 通过拼接类名的方式,根据状态给光标元素添加或移除clicked类,触发CSS中定义的尺寸和颜色变化。
  • 给.custom-cursor添加transition属性,让动画过渡更自然。

内容的提问来源于stack exchange,提问作者imnotremi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 04:15:37