JS Canvas - draw line at a specified angle

10,191

If i guess right, i think you want the mouse act like a baseball bat, and you need to measure the current mouse angle, that is to store previous mouse position and do some math.

You have also to keep track if you allready handled current collision, to avoid the ball being 'sticky' and follow the mouse.

http://jsfiddle.net/gamealchemist/z3U8g/

var ctx = cv.getContext('2d');

var ball = {
    x:200, y:200, 
    r : 30,
    vx : 0.4, vy:0.4
}

// when mouse moved that distance, ball speed norm will be 1
var speedNorm = 10;

var collisionOnGoing = false;

function collide() {
    var dist = sq(ball.x - mx) + sq (ball.y-my); 
    // too far from ball ?
    if (dist > sq(ball.r)) { 
        collisionOnGoing = false;
        return;
    }
    // return if collision allready handled
    if (collisionOnGoing) return;
    var mouseDist =Math.sqrt( sq(mx-lastmx) + sq(my-lastmy) );
    // no collision if mouse too slow
    if (mouseDist<speedNorm/5) return;
    // launch the ball in current direction
    // with a speed relative to the mouse speed.
    var mouseAngle = Math.atan2(my-lastmy, mx-lastmx);
    ball.vx= (mouseDist / speedNorm ) * Math.cos(mouseAngle);
    ball.vy= (mouseDist / speedNorm ) * Math.sin(mouseAngle);
    collisionOnGoing = true;    
}

function animate() {
    requestAnimationFrame(animate);
    ctx.clearRect(0,0,400,400);
    // collide ball with mouse
    collide();
    // draw ball
    ctx.beginPath();
    ctx.arc(ball.x, ball.y, ball.r, 0, 6.3);
    ctx.fill();
    ctx.closePath();
    // move
    ball.x+=ball.vx;
    ball.y+=ball.vy;
    // collide with screen
    if (ball.x>400) ball.vx=-Math.abs(ball.vx);
    if (ball.x<0) ball.vx=Math.abs(ball.vx);
    if (ball.y>400) ball.vy=-Math.abs(ball.vy);
    if (ball.y<0) ball.vy=Math.abs(ball.vy);
}

animate();

//  ---  Mouse handling ---

addEventListener('mousemove', mouseMove);

var mx=-1, my=-1, lastmx=-1, lastmy=-1;
var cvRect = cv.getBoundingClientRect();
var cvLeft = cvRect.left;
var cvTop = cvRect.top;
function mouseMove(e) {
    lastmx = mx; lastmy=my;
    mx=e.clientX - cvLeft; 
    my=e.clientY - cvTop;
}

function sq(x) { return x*x;  }
Share:
10,191
user3871
Author by

user3871

Updated on June 13, 2022

Comments

  • user3871
    user3871 almost 2 years

    I'd like to make an app where a ball moves at the angle your mouse hits it. So if you swipe your mouse down from top left quadrant at 30 degrees (I guess that would be 180-30 = angle of 150 degrees), it will knock the ball that way. I've been drawing my lines as such:

            function drawAngles () {
                var d = 50; //start line at (10, 20), move 50px away at angle of 30 degrees
                var angle = 80 * Math.PI/180;
                ctx.beginPath();
                ctx.moveTo(300,0);
                ctx.lineTo(300,600); //x, y
                ctx.moveTo(0,300);
                ctx.lineTo(600,300);
                ctx.moveTo(300,300);
                ctx.lineTo(600,100);
                ctx.arc(300,300,300,0,2*Math.PI);
                ctx.stroke();
            }
    

    But this doesn't give me an idea of what the angles are.

    Then I move the ball at that angle (for now, I'm animating it without mouse interaction)

            function getAngleX (x) {
                return x = x + (50 * Math.cos(Math.PI/6));          
            }
            function getAngleY(y) {
                return  y = y + (50 * Math.sin(Math.PI/6));
            }
    
                //just animate this box to move at an angle from center down at 30 degrees
                $(".anotherBox").mouseenter(function(e) {
                    pos =  $(this).position();
                    box2X = pos.left;
                    box2Y = pos.top;    
    
                    $(this).animate({
                        //top : $(window).outerHeight(),
                        top : getAngleY(box2Y)+"px",
                        left: getAngleX(box2X)+"px",
                    }, "slow");     
                });
    

    So how can I draw a line at a specified angle? I'd like to make sure my ball is following along that path.

    enter image description here