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

时间:2016-09-07 23:40:07

标签: 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">
&#13;
&#13;
&#13;

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

我曾尝试过一些尝试,但没有一个尝试,如果我想出一个可以解决它的想法,那就是非常长时间的啰嗦。我正在努力找到解决这个问题的最好方法,所以任何帮助都会非常感激。

请注意,jsfiddle是我试图实现的快速模拟示例。遗憾的是,由于客户机密性,我无法分享实际的源代码。我提供的任何解决方案都将适用于最终网站。

非常感谢:)

1 个答案:

答案 0 :(得分:1)

您需要存储所有元素度数,并检查箭头是否需要顺时针旋转或逆时针旋转才能进行最短旋转。

&#13;
&#13;
$(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)');
    });
  }
});
&#13;
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);
}
&#13;
<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">
&#13;
&#13;
&#13;