在反应中没有获得平滑的光标动画

问题描述

我正在使用此反应代码在主光标之后获取自定义光标。动画是使用 gsap 和 lerp 函数完成的。但是动画不是无缝的,chrome 性能监视器显示 cpu 使用率超过 100%。请帮我解决这个问题。我参考了这个视频链接获取光标动画:https://www.youtube.com/watch?v=MEO6yQLAgKw&list=PLtSHrBhMos7hXeImRWnnC38mdYp_4c333&index=2&t=630s

import gsap from 'gsap';
import React,{Component} from 'react';
import './cursor.scss';

class Cursor extends Component{
  constructor(props){
    super(props);
    this.state={
     x : 0,y : 0
    };
    this.cursor = React.createRef();
    this.cursorConfigs = {
      x: { prevIoUs: 0,current: 0,amt: 0.2 },y: { prevIoUs: 0,};

    this.lerp = (a,b,n) => (1 - n) * a + n * b;
    
    
  }
  
  componentDidMount(){
    
   window.addEventListener("mousemove",e=> {
      this.setState({
        x: e.pageX,y:e.pageY
      })
    });
    
    
    this.cursor.current.style.opacity = 0;
    
    this.onMouseMoveEv = () => {
    this.cursorConfigs.x.prevIoUs = this.cursorConfigs.x.current = this.state.x;
    this.cursorConfigs.y.prevIoUs = this.cursorConfigs.y.current = this.state.y;

    gsap.to(this.cursor.current,{
      duration: 1,ease: "Power4.eaSEOut",opacity: 1,});
    
    
    
    window.removeEventListener("mousemove",this.onMouseMoveEv);

    requestAnimationFrame(() =>this.render());
    };

    window.addEventListener("mousemove",this.onMouseMoveEv);

}
 
  render(){

    
    

    
    this.cursorConfigs.x.current = this.state.x;
    this.cursorConfigs.y.current = this.state.y;
   

    for (const Key in this.cursorConfigs){
      this.cursorConfigs[Key].prevIoUs = this.lerp(
      this.cursorConfigs[Key].prevIoUs,this.cursorConfigs[Key].current,this.cursorConfigs[Key].amt
     );
    }
   
    console.log(this.cursorConfigs.x.prevIoUs,this.cursorConfigs.x.current)
    var styles = {
      transform:`translateX(${this.cursorConfigs.x.prevIoUs}px) translateY(${this.cursorConfigs.y.prevIoUs}px)`
    }
   
    requestAnimationFrame(() =>this.render());


    return(
      <div className="cursor" ref={this.cursor} style={styles}>
      <div className="cursor-media">
      
        
      </div>
    </div>
    )

   
  }
}


export default Cursor;```

解决方法

您实际上不需要在每次鼠标移动时更新。考虑去抖动 setState

示例:

// delay in ms
function debounced(delay,fn) {
    let timerId;
    return function (...args) {
        if (timerId) {
            clearTimeout(timerId);
        }
        timerId = setTimeout(() => {
            fn(...args);
            timerId = null;
        },delay);
    };
}

function handler(e) {
    this.setState({
        x: e.pageX,y: e.pageY,});
};

window.addEventListener("mousemove",debounced(200,handler));