根据鼠标点击移动和旋转物体?

9

我正在尝试以与鼠标单击相同的方向旋转对象,并移动到鼠标单击的位置。到目前为止,我已经安排好了移动,但我认为角度有问题,因为它不能像我一样旋转。我犯了什么错误?我该如何解决?

var theThing = document.querySelector("#thing");
var container = document.querySelector("#contentContainer");
var triangle = document.querySelector("#triangle");
container.addEventListener("click", getClickPosition, false);

function getClickPosition(e) {
  var xPosition = e.clientX;
  var yPosition = e.clientY;
  var translate3dValue = "translate3d(" + xPosition + "px," + yPosition +
    "px,0)";
  var spx = document.querySelector("#triangle").clientWidth / 2;
  var spy = document.querySelector("#triangle").clientHeight / 2;
  var angle = Math.atan2(yPosition - spy, xPosition - spx) * 180 /
    Math.PI;
  if (angle < 0) {
    angle = 360 - (-angle);
  }

  theThing.style.transform = translate3dValue;
  theThing.style.transform += "rotate(" + angle + "deg)"
}
body {
  background-color: #FFF;
  padding: 0;
  margin: 0;
}

#contentContainer {
  width: 500px;
  height: 500px;
  border: 15px #EDEDED solid;
  overflow: hidden;
  background-color: #F2F2F2;
  cursor: pointer;
}

#thing {
  width: 75px;
  height: 75px;
  background-color: rgb(255, 207, 0);
  border-radius: 0%;
  transform: translate3d(200px, 100px, 0);
  transition: transform.2s ease-in;
}

#triangle {
  width: 0;
  height: 0;
  border-left: 30px solid transparent;
  border-right: 45px solid transparent;
  border-bottom: 75px solid black;
}
<div id="contentContainer">
  <div id="thing">
    <div id="triangle">
    </div>
  </div>
</div>


你是根据什么依据或公式计算出角度的? - Abhishek Pandey
@AbhishekPandey 我从一个网站上找到了角度计算的方法。他们试图实现与我相同的目标,即旋转到鼠标位置。但是对我来说它并没有像他/她所说的那样起作用。这是链接 https://www.gamefromscratch.com/post/2012/11/18/GameDev-math-recipes-Rotating-to-face-a-point.aspx - TheOrion
你有检查过 var spx = document.querySelector("#triangle").clientWidth / 2;var spy = document.querySelector("#triangle").clientHeight / 2; 是否一直返回 0 吗? - Abhishek Pandey
你需要调试你的代码,并且需要理解 Math.atan2() 方法的工作原理。 - Abhishek Pandey
@AbhishekPandey 你说得对。我错过了那个。它不断返回0。你认为我该如何获得正确的角度? - TheOrion
带有适当计算。 - Abhishek Pandey
2个回答

1
我似乎找到了一种解决方法。虽然它不完美,但我认为现在它正在工作。我使用偏移量方法来获取图像的中心,并使用Math.atan2方法找到中心和鼠标之间的角度。

var theThing = document.querySelector("#thing");
var container = document.querySelector("#contentContainer");
var triangle = document.querySelector("#triangle");
container.addEventListener("click", getClickPosition, false);

function getClickPosition(e) {
  var xPosition = e.clientX;
  var yPosition = e.clientY;
  var translate3dValue = "translate3d(" + xPosition + "px," + yPosition + "px,0)";
  var spx = document.querySelector("#thing").clientWidth / 2;
  var spy = document.querySelector("#thing").clientHeight / 2;
  var box = $("#thing");
  var boxCenter = [box.offset().left + box.width() / 2, box.offset().top + box.height() / 2];
  var angle = Math.atan2(xPosition - boxCenter[0], -(yPosition - boxCenter[1])) * (180 / Math.PI);
  theThing.style.transform = translate3dValue;
  theThing.style.transform += "rotate(" + angle + "deg)"

}
body {
  background-color: #FFF;
  padding: 0;
  margin: 0;
}

#contentContainer {
  width: 550px;
  height: 350px;
  border: 15px #EDEDED solid;
  overflow: hidden;
  background-color: #F2F2F2;
  cursor: pointer;
}

#thing {
  width: 75px;
  height: 75px;
  background-color: rgb(255, 207, 0);
  border-radius: 0%;
  transform: translate3d(200px, 100px, 0);
  transition: transform.8s ease-in;
}

#triangle {
  width: 0;
  height: 0;
  border-left: 30px solid transparent;
  border-right: 45px solid transparent;
  border-bottom: 75px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="contentContainer">
  <div id="thing">
    <div id="triangle">
    </div>
  </div>
</div>


1

你需要稍微调整一下并替换硬编码的值。此外,这并不意味着以任何方式都是高效或优雅的。

<html>

<head>
    <title>Move to click position</title>
    <style>
        body {
            background-color: #FFF;
            padding: 0;
            margin: 0;
        }

        #contentContainer {
            width: 500px;
            height: 500px;
            /* border: 15px #EDEDED solid; */
            overflow: hidden;
            background-color: #F2F2F2;
            cursor: pointer;
            display: block;

        }

        #thing {
            width: 75px;
            height: 75px;
            background-color: rgb(255, 207, 0);
            border-radius: 0%;
            /* transform: translate3d(200px, 100px, 0); */
            transition: transform.2s ease-in;
            /* transform-origin: 0% 0% */
        }

        #triangle {
            width: 0;
            height: 0;
            border-left: 30px solid transparent;
            border-right: 45px solid transparent;
            border-bottom: 75px solid black;
        }
    </style>
</head>

<body>
    <div id="contentContainer">
        <div id="thing">
            <div id="triangle">
            </div>
        </div>
    </div>
    <script>
        var theThing = document.querySelector("#thing");
        var container = document.querySelector("#contentContainer");
        var triangle = document.querySelector("#triangle");
        container.addEventListener("click", getClickPosition, false);
        // container.addEventListener("mousemove", getClickPosition, false);

        // we'll keep tarck of a vector going from center to head 
        var center = {
            'x': 75 / 2.0,
            'y': 75 / 2.0
        }
        var head = {
            'x': 75 / 2.0,
            'y': 0.0
        }

        function norm(vx, vy) {
            return Math.sqrt(vx * vx + vy * vy);
        }

        function normalize(vx, vy) {
            d = norm(vx, vy);
            return { 'x': vx / d, 'y': vy / d };
        }

        function dot(vx, vy, wx, wy) {
            return vx * wx + vy * wy;
        }

        function det(vx, vy, wx, wy) {
            return vx * wy - vy * wx;
        }

        // compute clockwise angle between two vectors
        function vwAngle(vx, vy, wx, wy) {
            return Math.atan2(det(vx, vy, wx, wy), dot(vx, vy, wx, wy));
        }

        function getClickPosition(e) {
            var xPosition = e.clientX;
            var yPosition = e.clientY;
            console.log(xPosition, yPosition);
            var spx = document.querySelector("#triangle").clientWidth / 2.0;
            var spy = document.querySelector("#triangle").clientHeight / 2.0;
            console.log(spx, spy);
            console.log();

            // vector from center to mouse
            var m = normalize(
                xPosition - center.x,
                yPosition - center.y
            );

            // v is a vector fron center to head
            var vNormalized = normalize(head.x - center.x, head.y - center.y);

            // clockwise angle between vectors m and v
            var between = -vwAngle(m.x, m.y, vNormalized.x, vNormalized.y);


            // Update vector v by updated head:

            // rotate v around point 
            var cosb = Math.cos(between);
            var sinb = Math.sin(between);
            var vRotated = {
                'x': cosb * vNormalized.x - sinb * vNormalized.y,
                'y': sinb * vNormalized.x + cosb * vNormalized.y
            };
            var d = norm(head.x - center.x, head.y - center.y);
            head.x = center.x + vRotated.x * d;
            head.y = center.y + vRotated.y * d;


            // translation:
            var dx = xPosition - center.x
            var dy = yPosition - center.y
            center.x = xPosition - 75 / 2.0;
            center.y = yPosition - 75 / 2.0;
            head.x += dx;
            head.y += dy;
            var translate3dValue = "translate3d(" + center.x + "px," + center.y + "px,0)";
            theThing.style.transform = translate3dValue;
            theThing.style.transform += "rotate(" + (between * 180 / Math.PI) + "deg)";

        }

    </script>
</body>
</body>

</html>

非常感谢您的回答。但是,当我运行此代码时,它并没有完全指向鼠标位置。我将尝试找出问题所在,并进行一些更改。顺便说一下,我稍微修改了代码并使用了jQuery,现在它似乎可以正常工作了。 - TheOrion

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接