根据光标位置在画布中旋转的箭头

时间:2017-12-18 18:20:54

标签: javascript canvas

我正在编写一个应该执行以下操作的脚本。您将鼠标锁定到画布上。它会告诉你一个人造的"相反,您也可以使用鼠标移动光标。在此光标下,您将拥有一个也随鼠标移动的圆圈。

所有这些都与我的脚本完美配合,直到我添加了另一个不错的功能:我想在画布中间放置一个箭头,它保持不变,大小完全相同,但根据光标移动旋转。为了让您了解我所谈论的内容,我制作了这些示例图表(不要担心尺寸和颜色)。

https://i.stack.imgur.com/poO6n.jpg

https://i.stack.imgur.com/twXhY.jpg

https://i.stack.imgur.com/RFFBe.jpg

我做了一些计算来实现这一点,实现它们,希望是最好的,但它不起作用。我觉得它什么时候起作用,对于每个人来说都是一个很酷的功能。但到目前为止,我还没有看到我的错误在哪里。如果您有线索,我非常感谢每一个答案。

非常感谢!



    <!DOCTYPE HTML>
    <html>
       <head>
          <meta charset="UTF-8">
          <title>ArrowSpin</title>
          <style>
             html, body {
             margin: 0;
             padding: 0;
             }
             html {
             font-family: sans-serif;
             }
             canvas {
             display: block;
             margin: 0 auto;
             border: 1px solid black;
             }
             .information {
             width: 640px;
             margin: 0 auto 50px;
             }
             #tracker {
             position: absolute;
             top: 0;
             right: 10px;
             background-color: white;
             }
             h1 {
             font-size: 200%;
             }
          </style>
       </head>
       <body>
          <div class="information">
          <img id="mousecursor" hidden="true" width="13" height="20.5" src="mousecursor.png" alt="Cursor">
          <p id="demo" style="color: black" oncl></p>
          <p id="Message" style="color: black" oncl></p>
          <canvas id="myCanvas" width="640" height="360">
            Your browser does not support HTML5 canvas
          </canvas>
          <div id="tracker"></div>
          </div>
          <script>
             try {
             
            // helper functions
             
             const RADIUS = 20;
            
            // this image is you mousecursor
             var img = document.getElementById("mousecursor");
             
            // degree to radians
             function degToRad(degrees) {
             var result = Math.PI / 180 * degrees;
             return result;
             }
             
            // generate a random number, later on, mouse cursor should start at random position, now unused     
             function generateRandomNumber() {
             var minangle = 0;
             var maxangle = 2*Math.PI;
             randangle = Math.random() * (maxangle- minangle) + minangle;
             return randangle;
             };
    
            //this function draws the actual arrow
                 
             function drawArrow(fromx, fromy, tox, toy, colourarrow){
                        //variables to be used when creating the arrow
                        var c = document.getElementById("myCanvas");
                        var ctx = c.getContext("2d");
                        var headlen = 3;
                
                        var angle = Math.atan2(toy-fromy,tox-fromx);
                
                        //starting path of the arrow from the start square to the end square and drawing the stroke
                        ctx.beginPath();
                        ctx.moveTo(fromx, fromy);
                        ctx.lineTo(tox, toy);
                        ctx.strokeStyle = colourarrow;
                        ctx.lineWidth = 20;
                        ctx.stroke();
                
                        //starting a new path from the head of the arrow to one of the sides of the point
                        ctx.beginPath();
                        ctx.moveTo(tox, toy);
                        ctx.lineTo(tox-headlen*Math.cos(angle-Math.PI/7),toy-headlen*Math.sin(angle-Math.PI/7));
                
                        //path from the side point of the arrow, to the other side point
                        ctx.lineTo(tox-headlen*Math.cos(angle+Math.PI/7),toy-headlen*Math.sin(angle+Math.PI/7));
                
                        //path from the side point back to the tip of the arrow, and then again to the opposite side point
                        ctx.lineTo(tox, toy);
                        ctx.lineTo(tox-headlen*Math.cos(angle-Math.PI/7),toy-headlen*Math.sin(angle-Math.PI/7));
                
                        //draws the paths created above
                        ctx.strokeStyle = colourarrow;
                        ctx.lineWidth = 20;
                        ctx.stroke();
                        ctx.fillStyle = colourarrow
                        ctx.fill();
                    }
             
             // this function calculates the current angle of the cursor from the exact middle of the canvas (x0,y0) by using two simple assumptions which are a) radius=sqrt(sqr(xfrom)+sqr(y)) b) x=x0+radius*cos(alpha) <=> alpha=arccos((x-x0)/radius)    
                 
             function CursorAngle() {
             var currentrad=Math.sqrt([Math.pow(x-canvas.width/2)+Math.pow(y+canvas.height)]);
             var currentangle=Math.acos([(x-canvas.width/2)/currentrad]);
             return currentangle
             }
                 //in this function I use the just calculated cursor angle to now calculate where my arrow shall begin and end, again I use x=x0+radius*cos(alpha) and y=y0+radius*sin(alpha). In this case I always want my arrow to have a radius of 50 and I always want it to be drawn in the center of the canvas.
                 
             function ProbeAngle(alpha) {
                 var x1 = canvas.width/2+50*cos(alpha)
                 var y1 = canvas.width/2+50*sin(alpha)
                 var x2 = canvas.width/2+50*cos(alpha+Math.PI)
                 var y2 = canvas.width/2+50*sin(alpha+Math.PI)
                 return [x1; y1; x2; y2]
             }
             
             // setup of the canvas
             
             var canvas = document.querySelector('canvas');
             var ctx = canvas.getContext('2d');
             
             var x = canvas.width/2;
             var y = canvas.height/2;
             
             //refresh the canvas
             
             function canvasDraw() {
             ctx.fillStyle = "black";
             ctx.fillRect(0, 0, canvas.width, canvas.height);
             ctx.fillStyle = "#f00";
             ctx.beginPath();
             ctx.arc(x, y, RADIUS, 0, degToRad(360), true);
             ctx.fill();
             ctx.drawImage(img, x, y);         
             }
             canvasDraw();
             
             // pointer lock object forking for cross browser
             
             canvas.requestPointerLock = canvas.requestPointerLock ||
                                   canvas.mozRequestPointerLock;
             
             document.exitPointerLock = document.exitPointerLock ||
                                  document.mozExitPointerLock;
             
             canvas.onclick = function() {
             canvas.requestPointerLock();
             canvasDraw();
             };
             
             // pointer lock event listeners
             
             // Hook pointer lock state change events for different browsers
             document.addEventListener('pointerlockchange', lockChangeAlert, false);
             document.addEventListener('mozpointerlockchange', lockChangeAlert, false);
             
             function lockChangeAlert() {
             if (document.pointerLockElement === canvas ||
             document.mozPointerLockElement === canvas) {
             console.log('The pointer lock status is now locked');
             document.addEventListener("mousemove", updatePosition, false);
             } else {
             console.log('The pointer lock status is now unlocked');  
             document.removeEventListener("mousemove", updatePosition, false);
             }
             }
             
             //tracker shows x and y coordinates of "pseudo" cursor
             
             var tracker = document.getElementById('tracker');
             
                 //border protection for our image not to move out of the canvas
                 
             var animation;
             function updatePosition(e) {
             x += e.movementX;
             y += e.movementY;
             if (x > canvas.width) {
             x = canvas.width;
             }
             if (y > canvas.height) {
             y = canvas.height;
             }  
             if (x < 0) {
             x = 0;
             }
             if (y < 0) {
             y = 0;
             }
             tracker.textContent = "X position: " + x + ", Y position: " + y;
             
             if (!animation) {
             animation = requestAnimationFrame(function() {
             animation = null;
             canvasDraw();
    
    //receive the ProbeCoords by using the functions CursorAngle and ProbeAngle and draw it!
                 var ProbeCoord = ProbeAngle(CursorAngle());
               drawArrow(ProbeCoord[0],ProbeCoord[1],ProbeCoord[2],ProbeCoord[3],'white')
             });
             }
             }
             }
                         catch(err) {
                 document.getElementById("demo").innerHTML = err.message;
                         }
                 document.getElementById("Message").innerHTML = "potential Errorcode above";
             
          </script>
       </body>
    </html>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:0)

您是否尝试过使用Fabric JS?在链接的示例中,您可以单击一个对象,并在顶部显示一个句柄。之后,您可以单击手柄,它将跟随鼠标。我建议这样做,因为很可能有一种方法可以将click事件更改为悬停事件,然后获取跟随鼠标的句柄。