跟随鼠标圈HTML5画布jQuery

时间:2019-01-20 15:56:16

标签: javascript html html5-canvas

我正在尝试在游戏中使用的HTML Canvas中使鼠标跟随一个圆圈。我试图使圆每次迭代移动5px,但是水平移动时速度变慢,垂直移动时速度变快。这是我使用的数学:

x=distance between mouse and circle on the x-axis
y=distance between mouse and circle on the y-axis
z=shortest distance between mouse and circle
a=number of units circle should move along the x-axis
b=number of units circle should move along the y axis


x^2 + y^2=z^2
Want the total distance traveled every iteration to be five pixels
a^2 + b^2 = 25
b/a=y/x
b=ay/x
a=sqrt(25-ay/x^2)
a^2+ay/x-25=0
Use Quadratic formula to find both answers
a=(-y/x+-sqrt(y/x)^2+100)/2

我在下面的代码中复制了问题

$(function(){
      let canvas = $("canvas")[0];
      let ctx = canvas.getContext("2d");
      
      //Gets position of mouse and stores the value in variables mouseX and mouseY
      let mouseX = mouseY = 0;
      $("canvas").mousemove(function(e){
        mouseX = e.pageX;
        mouseY = e.pageY;
      }).trigger("mousemove");

      let circleX = 0;
      let circleY = 0;
      function loop(t){
        //Background
        ctx.fillStyle="blue";
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        
        let xFromMouse = mouseX-circleX;
        let yFromMouse = mouseY-circleY;
        let yxRatio = yFromMouse/xFromMouse;
        let xyRatio = xFromMouse/yFromMouse;
        let speed = 25;
        let possibleXValues = [(-yxRatio+Math.sqrt(Math.pow(yxRatio,2)+(4*speed)))/2,(-yxRatio-Math.sqrt(Math.pow(yxRatio,2)+(4*speed)))/2];
        
        //I use this code as a temporary fix to stop the circle from completely disappearing
        if(xFromMouse === 0 || isNaN(yxRatio) || isNaN(possibleXValues[0]) || isNaN(possibleXValues[1])){
          possibleXValues = [0,0];
          yxRatio = 0;
        }
        //Uses b=ay/x to calculate for y values
        let possibleYValues = [possibleXValues[0]*yxRatio,possibleXValues[1]*yxRatio];

        if(xFromMouse >= 0){
          circleX += possibleXValues[0];
          circleY += possibleYValues[0];
        } else {
          circleX += possibleXValues[1];
          circleY += possibleYValues[1];
        }
        
        ctx.beginPath();
        ctx.arc(circleX, circleY, 25, 0, 2 * Math.PI,false);
        ctx.fillStyle = "red";
        ctx.lineWidth = 0;
        ctx.fill();

        window.requestAnimationFrame(loop);
      }
      window.requestAnimationFrame(loop);
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas width="450" height="250"></canvas>

1 个答案:

答案 0 :(得分:1)

我认为使用笛卡尔到极坐标转换可能会更好。这是我以前做过的一个例子。这样一来,您就可以使每个迭代的“速度”步长一致。

//Canvas, context, mouse.
let c, a, m = { x:0, y:0};

//onload.
window.onload = function(){
    let circle = {},
        w, h,
        speed = 5; //step speed = 5 "pixels" (this will be fractional in any one direction depending on direction of travel).

    //setup
    c = document.getElementById('canvas');
    a = c.getContext('2d');             
    w = c.width = window.innerWidth;
    h = c.height = window.innerHeight;

    function move(){
        //get distance and angle from mouse to circle.
        let v1m = circle.x - m.x,
            v2m = circle.y - m.y,
            vDm = Math.sqrt(v1m*v1m + v2m*v2m),
            vAm = Math.atan2(v2m, v1m);

            //if distance is above some threshold, to stop jittering, move the circle by 'speed' towards mouse.
            if(vDm > speed) { 
                circle.x -= Math.cos(vAm) * speed;
                circle.y -= Math.sin(vAm) * speed;
            }
    }

    function draw(){
        //draw it all.
        a.fillStyle = "blue";
        a.fillRect(0,0,w,h);

        a.fillStyle = "red";
        a.beginPath();
            a.arc(circle.x, circle.y, circle.r, Math.PI * 2, false);
        a.closePath();
        a.fill();
    }

    circle = {x:w/2, y:h/2, r:25};

    function animate(){
        requestAnimationFrame(animate);
        move();
        draw();
    }

    c.onmousemove = function(e){
        m.x = e.pageX;
        m.y = e.pageY;
    };

    animate();
}