javascript - 旋转图像跟随鼠标 jquery 平滑过渡

标签 javascript jquery animation

当您将鼠标悬停在页面上的某些项目上时,我试图让图像旋转。它使用此处提供的解决方案(针对我的目的进行了编辑):https://stackoverflow.com/a/10235298 .您可以在此处查看我正在尝试实现的示例:https://jsfiddle.net/t100gq25/

$(function () {
  var img = $('.arrow');

  if (img.length > 0) {
    var offset = img.offset();

    $('.animation-trigger').mouseenter(function (event) {
      var element = $(this);
      var elementPosition = element.offset();
      var elementX = elementPosition.left + (element.width() / 2);
      var elementY = elementPosition.top + (element.height() / 2);
      var imgX = offset.left + (img.width() / 2);
      var imgY = offset.top + (img.height() / 2);
      var radians = Math.atan2(elementX - imgX, elementY - imgY);
      var degrees = (radians * (180 / Math.PI) * -1) + 90;


      img.css('-moz-transform', 'rotate(' + degrees + 'deg)')
        .css('-webkit-transform', 'rotate(' + degrees + 'deg)')
        .css('-o-transform', 'rotate(' + degrees + 'deg)')
        .css('-ms-transform', 'rotate(' + degrees + 'deg)');
    });
  }
});
body {
  padding-top: 150px;
}

.container {
  height: 500px;
}

.menu-1,
.menu-2,
.menu-3,
.menu-4 {
  position: absolute;
  z-index: 99
}

.menu-1 {
  top: 20%;
  left: 20%;
}

.menu-2 {
  top: 20%;
  right: 20%;
}

.menu-3 {
  bottom: 20%;
  left: 20%;
}

.menu-4 {
  bottom: 20%;
  right: 20%;
}

.arrow {
  position: absolute;
  top: 50%;
  left: 50%;
  margin-top: -100px;
  margin-left: -100px;
  height: 200px;
  width: 200px;

  -webkit-transition: all 400ms cubic-bezier(0.455, 0.03, 0.515, 0.955);
  -moz-transition: all 400ms cubic-bezier(0.455, 0.03, 0.515, 0.955);
  -o-transition: all 400ms cubic-bezier(0.455, 0.03, 0.515, 0.955);
  transition: all 400ms cubic-bezier(0.455, 0.03, 0.515, 0.955);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<a href="#" class="menu-1">
    <img src="http://placehold.it/140x35&text=4" class="animation-trigger">
</a>

<a href="#" class="menu-2">
    <img src="http://placehold.it/140x35&text=1" class="animation-trigger">
</a>

<a href="#" class="menu-3">
    <img src="http://placehold.it/140x35&text=3" class="animation-trigger">
</a>

<a href="#" class="menu-4">
    <img src="http://placehold.it/140x35&text=2" class="animation-trigger">
</a>

<img src="https://image.freepik.com/free-icon/arrow-full-shape-pointing-to-right-direction_318-32063.png" class="arrow">

效果很好!但是,如果您将鼠标悬停在链接 1 上,箭头将转向它,然后您决定将鼠标悬停在链接 4 上,箭头将再次指向它。然而,它一直绕着(顺时针)走,而不是走回转(逆时针)的短路线。

我已经尝试了几次,但都没有奏效,如果我想出一个可行的想法,那就太啰嗦了。我正在努力找出解决此问题的最佳方法,因此非常感谢您的帮助。

请注意 jsfiddle 是我想要实现的目标的快速模拟示例。不幸的是,由于客户 secret ,我无法共享实际的源代码。我将把提供的任何解决方案应用于最终网站。

非常感谢:)

最佳答案

您需要存储所有元素度数并检查箭头是否需要顺时针或逆时针旋转以获得最短旋转。

$(function() {
  var img = $('.arrow');

  // Store clock wise degrees of all elements
  var clockwiseElemDegrees = {};
  var currentArrowAngle = 0;

  // Treat initial position of arrow as element 0
  var prevElem = '0';
  clockwiseElemDegrees['0'] = 0;

  if (img.length > 0) {

    var offset = img.offset();
    var imgX = offset.left + (img.width() / 2);
    var imgY = offset.top + (img.height() / 2);

    // Get element degrees		    
    $('.animation-trigger').each(function() {
      var element = $(this);
      var elementPosition = element.offset();
      var elementX = elementPosition.left + (element.width() / 2);
      var elementY = elementPosition.top + (element.height() / 2);

      var radians = Math.atan2(elementY - imgY, elementX - imgX);
      var degrees = radians * (180 / Math.PI);

      clockwiseElemDegrees[element.attr('elem')] = (degrees < 0) ? (degrees + 360) : degrees;
    });


    $('.animation-trigger').mouseenter(function(event) {

      // Check if arrow should be rotated clockwise
      var clockwiseDegreesForNextElem = clockwiseElemDegrees[$(this).attr('elem')];
      var clockwiseDegreesForPrevElem = clockwiseElemDegrees[prevElem];
      if (clockwiseDegreesForNextElem < clockwiseDegreesForPrevElem)
        clockwiseDegreesForNextElem += 360;

      var clockwiseRotationRequired = clockwiseDegreesForNextElem - clockwiseDegreesForPrevElem;

      if (clockwiseRotationRequired <= 180) {
        // Do clockwise rotation
        currentArrowAngle += clockwiseRotationRequired;
      } else {
        // Do anticlockwise rotation
        currentArrowAngle -= (360 - clockwiseRotationRequired);
      }

      prevElem = $(this).attr('elem');

      img.css('-moz-transform', 'rotate(' + currentArrowAngle + 'deg)')
        .css('-webkit-transform', 'rotate(' + currentArrowAngle + 'deg)')
        .css('-o-transform', 'rotate(' + currentArrowAngle + 'deg)')
        .css('-ms-transform', 'rotate(' + currentArrowAngle + 'deg)');
    });
  }
});
body {
  padding-top: 150px;
}
.container {
  height: 500px;
}
.menu-1,
.menu-2,
.menu-3,
.menu-4 {
  position: absolute;
  z-index: 99
}
.menu-1 {
  top: 20%;
  left: 20%;
}
.menu-2 {
  top: 20%;
  right: 20%;
}
.menu-3 {
  bottom: 20%;
  left: 20%;
}
.menu-4 {
  bottom: 20%;
  right: 20%;
}
.arrow {
  position: absolute;
  top: 50%;
  left: 50%;
  margin-top: -100px;
  margin-left: -100px;
  height: 200px;
  width: 200px;
  -webkit-transition: all 400ms cubic-bezier(0.455, 0.03, 0.515, 0.955);
  -moz-transition: all 400ms cubic-bezier(0.455, 0.03, 0.515, 0.955);
  -o-transition: all 400ms cubic-bezier(0.455, 0.03, 0.515, 0.955);
  transition: all 400ms cubic-bezier(0.455, 0.03, 0.515, 0.955);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<a href="#" class="menu-1">
  <img src="http://placehold.it/140x35&text=4" class="animation-trigger" elem="1">
</a>

<a href="#" class="menu-2">
  <img src="http://placehold.it/140x35&text=1" class="animation-trigger" elem="2">
</a>

<a href="#" class="menu-3">
  <img src="http://placehold.it/140x35&text=3" class="animation-trigger" elem="3">
</a>

<a href="#" class="menu-4">
  <img src="http://placehold.it/140x35&text=2" class="animation-trigger" elem="4">
</a>

<img src="https://image.freepik.com/free-icon/arrow-full-shape-pointing-to-right-direction_318-32063.png" class="arrow">

关于javascript - 旋转图像跟随鼠标 jquery 平滑过渡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39380526/

相关文章:

javascript - Bootstrap3 popover data-trigger=focus 在弹出窗口中单击 <select> 输入时关闭弹出窗口

javascript - 如何选择 HTML5 Canvas 形状?

php - 显示每个帖子的总点赞数,每 1 秒后无需刷新页面

javascript - 最好的 JavaScript 语法糖

javascript - 用户输入 future 日期变量的计时器

javascript - 在移动设备上禁用响应式侧边栏

javascript - 必须在 css 文件中使用 PHP 运行计数器

java - 如何在draw()方法中使用数组?

html - 尝试使用 CSS3 动画使 div 移动,但不起作用

jquery - 使用 JQuery 悬停时触发 CSS3 动画不起作用