【问题标题】:Javascript mousemove animation angle needs to go slowly back to ZeroJavascript mousemove动画角度需要慢慢回零
【发布时间】:2020-12-03 13:25:19
【问题描述】:

const initEyeMove = () => {
  let eyeBall = document.querySelector(`.eyeball`);
  let pupil = document.querySelector(`.pupil`);

  if (eyeBall && pupil) {

    let eyeArea = eyeBall.getBoundingClientRect();
    let pupilArea = pupil.getBoundingClientRect();
    let R = eyeArea.width / 2;
    let r = pupilArea.width / 2;
    let centerX = eyeArea.left + R;
    let centerY = eyeArea.top + R;

    document.addEventListener(`mousemove`, (e) => {
      let x = e.clientX - centerX;
      let y = e.clientY - centerY;
      let theta = Math.atan2(y, x);
      let angle = theta * 180 / Math.PI + 360;

      if (angle < 330 || angle > 380) {
        angle = 0;
      }


      pupil.style.transform = `translateX(${R - r + `px`}) rotate(${angle + `deg`})`;
      pupil.style.transformOrigin = `${r + `px`} center`;
    });
  }
};

 initEyeMove();
.pupil {
  background-color: transparent;
  width: 1px;
  height: 1px;
  border-radius: 50%;
}

.pupil svg {
  top: 50%;
  left: 50%;
  transform: translate(30%, 30%);
}

.eye {
  position: absolute;
  top: 1px;
  left: 6px;
}

.eyeball {
  width: 10px;
  height: 10px;
  background-color: none;
  position: absolute;
  top: 120px;
  left: 6px;
}
<div class="eyeball">
  <div class="pupil">
   <svg xmlns="http://www.w3.org/2000/svg">
  <defs>
    <style>
      .cls-2{fill-rule:evenodd}
    </style>
  </defs>
  <g id="Слой_2" data-name="Слой 2">
    <g id="Слой_1-2" data-name="Слой 1">
      <g id="Untitled">
        <path fill="#ff0" fill-rule="evenodd" stroke="#ff0" stroke-linecap="round" stroke-linejoin="round" stroke-width="10" d="M5 71.4C5 34.7 37.3 5 77.1 5s72.1 29.7 72.1 66.4-32.3 66.4-72.1 66.4S5 108 5 71.4z"/>
        <path d="M59.9 31.3a15.2 15.2 0 1115.2 15.2 15.19 15.19 0 01-15.2-15.2zM82 75.3c2.9-19.8 16.7-35.4 30.8-34.9s23.1 16.9 20.2 36.7-16.7 35.4-30.8 34.9S79.1 95.1 82 75.3z" class="cls-2"/>
      </g>
    </g>
  </g>
</svg>

  </div>
</div>

有一个 if 语句可以在特定条件下使 mousemove 上的元素的角度归零。 需要让它从超出设定条件之前的角度慢慢回零。

更新:添加了更多细节,希望这个眼睛能更平滑地回到起始位置,而不是在角度大于或小于需要时立即返回。

【问题讨论】:

    标签: javascript if-statement animation mousemove decrement


    【解决方案1】:

    要使其恢复正常,您必须使用 animationFrame 逐帧调整它。我认为最简单的方法是将计算和角度的应用分开,然后允许一种方法继续调用角度的减少。由于我不确定最终结果是什么,以下只是一个猜测(假设您的角度是否回到 0):

    const initEyeMove = () => {
      let eyeBall = document.querySelector(`.eyeball`);
      let pupil = document.querySelector(`.pupil`);
    
      if (eyeBall && pupil) {
    
        let eyeArea = eyeBall.getBoundingClientRect();
        let pupilArea = pupil.getBoundingClientRect();
        let R = eyeArea.width / 2;
        let r = pupilArea.width / 2;
        let centerX = eyeArea.left + R;
        let centerY = eyeArea.top + R;
    
        // Store this globally so both your methods can access and change it
        let angle = 0;
    
        function undoPupil( t ){
    
            // Reduce the angle, limit it, etc...
            angle -= 1;
            angle = angle < 0 ? 0 : angle;
            
            // Only request an animation frame if the angle needs to change further
            if( angle > 0 ) window.requestAnimationFrame( applyPupil );
    
        }
        function applyPupil( angle ){
    
          pupil.style.transform = `translateX(${R - r + `px`}) rotate(${angle + `deg`})`;
          pupil.style.transformOrigin = `${r + `px`} center`;
        
          // Start undoing the angle here
          undoPupil();
    
        }
    
        document.addEventListener(`mousemove`, (e) => {
            
          let x = e.clientX - centerX;
          let y = e.clientY - centerY;
          let theta = Math.atan2(y, x);
          
          angle = theta * 180 / Math.PI + 360;
          applyPupil();
    
        });
    
      }
    };
    
    
    export {initEyeMove};

    如果您想要更流畅的体验,或者您可以控制持续时间,您可以走以下路线,我们存储时间并使用它来计算增量,以便我们可以在给定时间内应用它:

    const initEyeMove = () => {
      let eyeBall = document.querySelector(`.eyeball`);
      let pupil = document.querySelector(`.pupil`);
    
      if (eyeBall && pupil) {
    
        let eyeArea = eyeBall.getBoundingClientRect();
        let pupilArea = pupil.getBoundingClientRect();
        let R = eyeArea.width / 2;
        let r = pupilArea.width / 2;
        let centerX = eyeArea.left + R;
        let centerY = eyeArea.top + R;
        let angle = 0;
        
        // We will store the time the animation frame gets called here
        let time = 0;
        // Store the duration as well.
        let duration = 5000;
    
        function undoPupil( t ){
    
            const delta = time - t;
    
            time = t;
    
            // Reduce the angle, limit it, etc...
            angle *= 1 - (delta / duration);
            angle = angle < 0 ? 0 : angle;
            
            // Only request an animation frame if the angle needs to change further
            if( angle > 0 ) window.requestAnimationFrame( applyPupil );
    
        }
        function applyPupil( angle ){
    
          pupil.style.transform = `translateX(${R - r + `px`}) rotate(${angle + `deg`})`;
          pupil.style.transformOrigin = `${r + `px`} center`;
        
          // Start undoing the angle here
          undoPupil();
    
        }
    
        document.addEventListener(`mousemove`, (e) => {
    
          let x = e.clientX - centerX;
          let y = e.clientY - centerY;
          let theta = Math.atan2(y, x);
          
          angle = theta * 180 / Math.PI + 360;
          time = window.performance ? window.performance.now() : Date.now()
          applyPupil();
    
        });
    
      }
    };
    
    
    export {initEyeMove};

    请注意,我没有测试过这些,因为我不知道应该发生什么。添加您的 HTML 和一些代码以在 SO 中的 sn-p 中显示您想要的效果,然后我们可以进一步帮助您。

    【讨论】:

    • 添加了更多上下文,我的错。需要这只眼睛比现在更平滑地移动到开始位置。当它刚刚达到零角度时。
    猜你喜欢
    • 1970-01-01
    • 2010-09-29
    • 1970-01-01
    • 2017-01-18
    • 2011-10-19
    • 1970-01-01
    • 2021-02-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多