I've already created a bouncing ball which bounces off the walls of the HTML5 Canvas that I have specified.
My goal is to make a "Game Over" screen appear when the pointer (mouse) hovers over the ball.
I have already searched and found some tutorials on mouse events in Javascript, but I'm not really sure how to implement them into my code =/.
Any help would be amazing.
<script>
var x = Math.floor((Math.random() * 600) + 1);
var y = Math.floor((Math.random() * 300) + 1);
var dx = 2;
var dy = 4;
function begin()
{
gameCanvas = document.getElementById('gameCanvas');
context = gameCanvas.getContext('2d');
return setInterval (draw, 20);
}
begin();
function draw()
{
context.clearRect(0,0,600,300);
context.fillStyle = "#0000FF";
context.beginPath();
context.arc(x,y,80,0,Math.PI*2,true);
context.closePath();
context.fill();
if (x < 0 || x > 600) dx=-dx
if (y < 0 || y > 300) dy=-dy;
x += dx;
y += dy;
}
gameCanvas.onmousemove = function (e)
{
var gameCanvas = e.target;
var context = gameCanvas.getContext('2d');
var coords = RGraph.getMouseXY(e);
}
You need to check if the mouse is hovering over the ball (hit test) by checking the distance of the ball to the cursor. If the distance is smaller than radius of the ball, it means that the mouse is over the ball.
Note, that you need to adjust the code below to your needs
Example:
var mouse_x = 10, mouse_y = 10, ball_x = 10, ball_y = 10, ball_radius = 70, is_game_over = false
if( Math.sqrt( Math.pow( mouse_x - ball_x, 2 ) + Math.pow( mouse_x - ball_x, 2 )) < ball_radius && !is_game_over ) {
console.log('Cursor is over the mouse, game over')
is_game_over = true
}
Do it for every frame update.
you can add onmousemove=SetValues() to your body element like so:
<body onmousemove=SetValues()>
and change your code to this:
<script>
var x = Math.floor((Math.random() * 600) + 1);
var y = Math.floor((Math.random() * 300) + 1);
var dx = 2;
var dy = 4;
var mouseX;
var mouseY;
function setValues(e)
{
mouseX = e.pageX; //get mouse x
mouseY = e.pageY; //get mouse y
}
function begin()
{
gameCanvas = document.getElementById('gameCanvas');
context = gameCanvas.getContext('2d');
return setInterval (draw, 20);
}
begin();
function draw()
{
context.clearRect(0,0,600,300);
context.fillStyle = "#0000FF";
context.beginPath();
context.arc(x,y,80,0,Math.PI*2,true);
context.closePath();
context.fill();
if (x < 0 || x > 600) dx=-dx
if (y < 0 || y > 300) dy=-dy;
x += dx;
y += dy;
//check if the mouse is on the ball
var centerX = x + 80; //center of ball
var centerY = y; //center of ball
if(Math.pow((mouseX - centerX), 2) + Math.pow((mouseY - centerY), 2) <= 6400){
//do whatever to end game
}
}
Related
I am trying to make a website to show visually the working of Midpoint Line Algorithm. I want to display the dots after a specific time interval but the setTimeout() function is not working properly. It is simply showing the end result after waiting for 3 seconds.
<canvas id="ltpcanvas" style="border: 1px solid #000000;">
</canvas>
<script>
window.onload = function(){
var ltpc = document.getElementById('ltpcanvas');
ltpc.width = window.innerWidth;
ltpc.height = window.innerHeight;
var context = ltpc.getContext('2d');
var cx1,cx2,cy1,cy2;
var count=0;
ltpc.addEventListener('mousedown',onDown,false);
function onDown(event){
count++;
cx = event.pageX;
cy = event.pageY;
cy-=9;
cx-=9;
if(count == 1){
cx1=cx;
cy1=cy;
}
else{
cx2=cx;
cy2=cy;
}
var ltpc = document.getElementById('ltpcanvas');
var context = ltpc.getContext('2d');
context.fillStyle = 'black';
context.beginPath();
context.arc(cx,cy,2,0*Math.PI,2*Math.PI,true);
context.closePath();
context.fill();
if(cx1!=undefined && cx2!=undefined && cy1!=undefined && cy2!=undefined){
if(cx1<cx2&&cy1<cy2)
midpoint(cx1,cy1,cx2,cy2);
else{
alert('cx1 = '+cx1+' cy1 = '+cy1+'\ncx2 = '+cx2+' cy2 = '+cy2);
}
}
}
}
function midpoint(X1,Y1,X2,Y2){
var dx = X2 - X1;
var dy = Y2 - Y1;
var d = dy - (dx/2);
var x = X1
var y = Y1;
while (x < X2)
{
x++;
if (d < 0)
d = d + dy;
else
{
d += (dy - dx);
y++;
}
myvar = setTimeout(Dotfunction,3000,x,y);
console.log(x);
console.log(y);
}
}
function Dotfunction(x,y){
var ltpc = document.getElementById('ltpcanvas');
var context = ltpc.getContext('2d');
context.fillStyle = 'black';
context.beginPath();
context.arc(x,y,1,0*Math.PI,2*Math.PI,true);
context.closePath();
context.fill();
}
</script>
I am trying to delay the execution of Dotfunction() every time but it is delaying for 3 seconds and then showing the entire line. I want it to delay after displaying every dot.
I want to display the dots after a specific time interval
The important thing here is that we want to show not "the dots", but "each dot" after an interval. This implies that each dot will be drawn on its own. I assume you want the dots to appear one after another in an animation.
The problem is that in this code we are calling setTimeout() multiple times with the same target delay. I.e. we tell the engine "do this in 3 seconds" many times within a single instant. The easiest solution to get an animation is to pass increasingly higher timeouts. Since we call the function within a loop and since we have a counting variable in it already, we can just reuse that and ask the JS engine to draw each point 10 milliseconds after the previous one.
The following code draws a line with a speed of 100 pixels per second.
PS: I removed the body margin, so that there is no longer the need to subtract that from the cursor position.
window.onload = function(){
var ltpc = document.getElementById('ltpcanvas');
ltpc.width = window.innerWidth;
ltpc.height = window.innerHeight;
var context = ltpc.getContext('2d');
var cx1, cx2, cy1, cy2;
var count = 0;
ltpc.addEventListener('mousedown', onDown, false);
function onDown(event) {
count++;
cx = event.pageX;
cy = event.pageY;
if (count == 1) {
cx1 = cx;
cy1 = cy;
}
else {
cx2 = cx;
cy2 = cy;
}
var ltpc = document.getElementById('ltpcanvas');
var context = ltpc.getContext('2d');
context.fillStyle = 'black';
context.beginPath();
context.arc(cx, cy, 2, 0 * Math.PI, 2 * Math.PI, true);
context.closePath();
context.fill();
if (cx1 != undefined && cx2 != undefined && cy1 != undefined && cy2 != undefined) {
if (cx1 < cx2 && cy1 < cy2)
midpoint(cx1, cy1, cx2, cy2);
else {
// alert('cx1 = '+cx1+' cy1 = '+cy1+'\ncx2 = '+cx2+' cy2 = '+cy2);
}
}
}
}
function midpoint(X1, Y1, X2, Y2){
var dx = X2 - X1;
var dy = Y2 - Y1;
var d = dy - (dx / 2);
var x = X1
var y = Y1;
while (x < X2)
{
x++;
if (d < 0)
d = d + dy;
else {
d += (dy - dx);
y++;
}
setTimeout(Dotfunction, x * 10, x, y);
//console.log(x);
//console.log(y);
}
}
function Dotfunction(x, y) {
var ltpc = document.getElementById('ltpcanvas');
var context = ltpc.getContext('2d');
context.fillStyle = 'black';
context.beginPath();
context.arc(x, y, 1,0 * Math.PI, 2 * Math.PI, true);
context.closePath();
context.fill();
}
body {
margin: 0;
}
<canvas id="ltpcanvas" style="border: 1px solid #000000;"></canvas>
i have a canvas, inside of which i have a board/grid. When a user highlights their mouse over an intersection of the grid, i want it to show where their game peice will go. This worked perfectly fine when the board was the exact size of the canvas. I made it abit smaller by x all the way round.
So as you can see in the picture below, the green shows the canvas and the grid is the board. I put my cursor at the very bottom right corner of the green to show when it triggers. The only one that works fine is the middle one because regardless how big i make the board, the middle will always be the middle.
Any easy fix would just be to make the area with the mouseover event, the dimensions of the board instead of the canvas but the event listener is on the canvas. My code is below the image
Variables:
var canvas = document.getElementById("game-canvas");
var context = canvas.getContext("2d");
var boardSize = 13;
var border = canvas.width / 20;
var boardWidth = canvas.width - (border * 2);
var boardHeight = canvas.height - (border * 2);
var cellWidth = boardWidth / (boardSize - 1);
var cellHeight = boardHeight / (boardSize - 1);
var lastX;
var lastY;
Mouse over event:
canvas.addEventListener('mousemove', function(evt)
{
var position = getGridPoint(evt);
if ((position.x != lastX) || (position.y != lastY))
{
placeStone((position.x * cellWidth) + border, (position.y * cellWidth) + border, 'rgba(0, 0, 0, 0.2)');
}
lastX = position.x;
lastY = position.y;
});
Gets the point on the grid and converts that into a number 0 - 13 (in this case)
function getGridPoint(evt)
{
var rect = canvas.getBoundingClientRect();
var x = Math.round((evt.clientX-rect.left)/(rect.right-rect.left)*boardWidth);
var y = Math.round((evt.clientY-rect.top)/(rect.bottom-rect.top)*boardHeight);
var roundX = Math.round(x / cellWidth);
var roundY = Math.round(y / cellHeight);
return {
x: roundX,
y: roundY
};
}
And finally draws the piece on the board:
function placeStone(x, y, color)
{
var radius = cellWidth / 2;
context.beginPath();
context.arc(x, y, radius, 0, 2 * Math.PI, false);
context.fillStyle = color;
context.fill();
context.lineWidth = 5;
}
I left a couple bits out like how the grid refreshs so its not a string of circles following your mouse and stuff, to keep it as short as i can, im hoping its just a simple asnwer and nobody needs to recreate it but if you do i can include the function that refreshes the grid and draws everything. Thankyou for any advice
To get the position relative to a box
// just as an example w,h are width and height
const box = { x : 10, y : 10, w : 100, h : 100 };
// mouse is the mouse coords and relative to the topleft of canvas (0,0);
var mouse.box = {}
mouse.box.x = mouse.x - box.x;
mouse.box.y = mouse.y - box.y;
Negative values for mouse.box x,y and values greater than box width and height have mouse outside.
For more convenience you can get the mouse normalize pos in the box
mouse.box.nx = mouse.box.x / box.w;
mouse.box.ny = mouse.box.y / box.h;
The coords for nx,ny are in the range 0-1 when inside or on the edge of the box;
If you want to have grid positions then define the grid
box.gridW = 10; // grid divisions width
box.gridH = 10; // grid divisions height
Then getting the grid pos of mouse
mouse.box.gx = Math.floor(mouse.box.nx * box.gridW);
mouse.box.gy = Math.floor(mouse.box.ny * box.gridH);
const ctx = canvas.getContext("2d");
const box = { x : 50,y : 10, w : 200, h : 200, gridW : 10, gridH : 10}
function drawGrid(){
var sx = box.w / box.gridW;
var sy = box.h / box.gridH;
var bx = box.x;
var by = box.y;
for(var y = 0; y < box.gridH; y ++){
for(var x = 0; x < box.gridW; x ++){
ctx.strokeRect(x * sx + bx, y * sx + by,sx,sy);
}
}
if(mouse.box){
if(mouse.box.nx >= 0 && mouse.box.nx <= 1 &&
mouse.box.ny >= 0 && mouse.box.ny <= 1){
ctx.fillRect(mouse.box.gx * sx + bx, mouse.box.gy * sx + by,sx,sy);
}
}
}
const mouse = {};
canvas.addEventListener("mousemove",(e)=>{
mouse.x = e.pageX;
mouse.y = e.pageY;
});
function updateMouse(){
if(!mouse.box){
mouse.box = {};
}
mouse.box.x = mouse.x - box.x;
mouse.box.y = mouse.y - box.y;
mouse.box.nx = mouse.box.x / box.w;
mouse.box.ny = mouse.box.y / box.h;
mouse.box.gx = Math.floor(mouse.box.nx * box.gridW);
mouse.box.gy = Math.floor(mouse.box.ny * box.gridH);
var p = 20;
ctx.fillText("x : " + mouse.x,box.x+box.w+10,p); p+= 14;
ctx.fillText("y : " + mouse.y,box.x+box.w+10,p); p+= 20;
ctx.fillText("Box relative",box.x+box.w+10,p); p+= 14;
ctx.fillText("x : " + mouse.box.x,box.x+box.w+10,p); p+= 14;
ctx.fillText("y : " + mouse.box.y,box.x+box.w+10,p); p+= 14;
ctx.fillText("nx : " + mouse.box.nx,box.x+box.w+10,p); p+= 14;
ctx.fillText("ny : " + mouse.box.ny,box.x+box.w+10,p); p+= 14;
ctx.fillText("gx : " + mouse.box.gx,box.x+box.w+10,p); p+= 14;
ctx.fillText("gy : " + mouse.box.gy,box.x+box.w+10,p); p+= 14;
}
function mainLoop(time){
if(canvas.width !== innerWidth || canvas.height !== innerHeight){ // resize canvas if window size has changed
canvas.width = innerWidth;
canvas.height = innerHeight;
}
ctx.setTransform(1,0,0,1,0,0); // set default transform
ctx.clearRect(0,0,canvas.width,canvas.height); // clear the canvas
updateMouse();
drawGrid();
requestAnimationFrame(mainLoop);
}
requestAnimationFrame(mainLoop);
canvas {
position : absolute;
top : 0px;
left : 0px;
}
<canvas id=canvas><canvas>
I have an issue with dragging image that is scaled.
I've created main_canvas that contains background and image represented via bg_canvas resp. img_canvas. Then I've made coordinates of background (panoramaX, panoramaY) and image(imageX, imageY) to check if I clicked some of them and to be able to drag them.
Image is placed on top of background:
var drawToMain = function()
{
// first clear the canvas
main_ctx.clearRect(0,0,canvas.width, canvas.height);
ctx.scale(scaleFactor, scaleFactor);
// draw the background image
main_ctx.drawImage(bg_canvas, panoramaX,panoramaY, 600, 300);
// do the transforms
main_ctx.translate( imageX+img_canvas.width/2,
imageY+img_canvas.height/2);
main_ctx.rotate(angle);
main_ctx.translate( -(imageX+img_canvas.width/2),
-(imageY+img_canvas.height/2));
// draw the img with the transforms applied
main_ctx.drawImage(img_canvas, imageX, imageY);
// reset the transforms
main_ctx.setTransform(1,0,0,1,0,0);
};
To drag items I'm testing if I clicked one of them:
function hitImage(x, y) {
if (x > imageX_hit && x < imageX_hit + img_canvas.width * scaleFactor &&
y > imageY_hit && y < imageY_hit + img_canvas.height * scaleFactor)
return 1;
if (x > panoramaX && x < panoramaX + bg_canvas.width * scaleFactor &&
y > panoramaY && y < panoramaY + bg_canvas.height * scaleFactor)
return 2;
return 0;
}
Then I've made wheel event to scale content of main_canvas (background and image, both) where is my issue, I'm updating image coordinates there but it doesn't work for me, when I zoom-out image for example and try to drag it, it doesn't move and when I'm zoomig image is "travelling" in background:
canvas.addEventListener("wheel", myFunction);
canvas.addEventListener('DOMMouseScroll', myFunction);
function myFunction(evt) {
var delta = evt.wheelDelta ? evt.wheelDelta / 40 : evt.detail ? -evt.detail : 0;
if (delta > 0) scaleFactor = scaleFactor + 0.05;
else scaleFactor = scaleFactor - 0.05;
imageX = imageX * scaleFactor;
imageY = imageY * scaleFactor;
imageX_hit = imageX_hit * scaleFactor;
imageY_hit = imageY_hit * scaleFactor;
drawToMain();
}
THERE is a exapmle of my problem.
Is there any solution, please?
Here is the code (fixed Slavik's code, update 1):
$(document).ready(function() {
// x, y to place image
var imageX = 80,
imageY = 80;
var imageX_hit = 80,
imageY_hit = 80;
// x, y to place background image
var panoramaX = 0,
panoramaY = 0;
var startX,
startY,
dragImage;
// mouse coordinates in canvas
var mouseX,
mouseY;
// number represents scale of image and background
var scaleFactor = 1,
angle = 0;
// main canvas
var canvas = document.createElement('canvas');
canvas.width = 600;
canvas.height = 300;
document.body.appendChild(canvas);
var ctx = canvas.getContext('2d');
var canvasOffset = $(canvas).offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;
var main_ctx = canvas.getContext('2d');
var bg_canvas = canvas.cloneNode(); // canvas for image
var img_canvas = canvas.cloneNode();// canvas for background
var angle = 0;
// draw on the main canvas, and only on the main canvas
var drawToMain = function()
{
// first clear the canvas
main_ctx.clearRect(0,0,canvas.width, canvas.height);
ctx.scale(scaleFactor, scaleFactor);
// draw the background image
main_ctx.drawImage(bg_canvas, panoramaX,panoramaY, 600, 300);
// do the transforms
main_ctx.translate( imageX+img_canvas.width/2,
imageY+img_canvas.height/2);
main_ctx.rotate(angle);
main_ctx.translate( -(imageX+img_canvas.width/2),
-(imageY+img_canvas.height/2));
// draw the img with the transforms applied
main_ctx.drawImage(img_canvas, imageX, imageY);
// reset the transforms
main_ctx.setTransform(1,0,0,1,0,0);
};
// I changed the event to a simple onclick
$(canvas).mousedown(function(e) {
switch (e.which) {
case 1:
// mouse position and test if image is hit
startX = parseInt(e.clientX - offsetX);
startY = parseInt(e.clientY - offsetY);
dragImage = hitImage(startX, startY);
break;
default:
break;
}
});
$(canvas).mousemove(function(e) {
// Im moving with image
mouseX = parseInt(e.clientX - offsetX);
mouseY = parseInt(e.clientY - offsetY);
// move image by the amount of the latest drag
var dx = (mouseX - startX)/scaleFactor;
var dy = (mouseY - startY)/scaleFactor;
if (dragImage == 1) {
imageX += dx;
imageY += dy;
imageX_hit += dx;
imageY_hit += dy;
// reset the startXY for next time
startX = mouseX;
startY = mouseY;
drawToMain();
}
else if (dragImage == 2) {
panoramaX += dx;
panoramaY += dy;
imageX += dx;
imageY += dy;
imageX_hit += dx;
imageY_hit += dy;
// reset the startXY for next time
startX = mouseX;
startY = mouseY;
drawToMain();
}
});
$(canvas).mouseup(function(e) {
switch (e.which) {
case 1:
dragImage = 0;
break;
default:
break;
}
});
// ZOOM-IN or ZOOM-OUT
canvas.addEventListener("wheel", myFunction);
canvas.addEventListener('DOMMouseScroll', myFunction);
// COMPUTING scaleFactor - zoom
function myFunction(evt) {
var delta = evt.wheelDelta ? evt.wheelDelta / 40 : evt.detail ? -evt.detail : 0;
if (delta > 0) scaleFactor = scaleFactor + 0.05;
else scaleFactor = scaleFactor - 0.05;
//imageX = imageX * scaleFactor;
//imageY = imageY * scaleFactor;
//console.log(imageX, imageY);
//imageX_hit = imageX_hit * scaleFactor;
//imageY_hit = imageY_hit * scaleFactor;
drawToMain();
}
// test if I user clicked image or panorama
function hitImage(x, y) {
x=x/scaleFactor;
y=y/scaleFactor;
if (x > imageX_hit && x < imageX_hit + img_canvas.width &&
y > imageY_hit && y < imageY_hit + img_canvas.height)
return 1;
if (x > panoramaX && x < panoramaX + bg_canvas.width &&
y > panoramaY && y < panoramaY + bg_canvas.height)
return 2;
return 0;
}
// loading images into canvas
var img = new Image();
img.onload = function() {
var this_canvas = img_canvas;
this_canvas.width = 150;
this_canvas.height = 150;
this_canvas.getContext('2d').drawImage(this, 0,
0, this_canvas.width,
this_canvas.height);
drawToMain();
};
img.src = 'http://pgmagick.readthedocs.org/en/latest/_images/lena_scale.jpg';
var bg = new Image();
bg.onload = function() {
var this_canvas = bg_canvas;
this_canvas.getContext('2d').drawImage(this, panoramaX,
panoramaY, 600, 300);
drawToMain();
};
bg.src = 'http://www.ansteorra.org/graphics/background/bg_image.jpg';
});
You don't need to change imageX, imageY and imageX_hit, imageY_hit variables by multiplying on scaleFactor. You scale image by context.scale so you don't need change something in your coordinates. Just remember scale factor and use it in hitImage for checking coordinates.
I'll try to edit post and explain more clearly, if this would be solution for your problem:
https://jsfiddle.net/j1f306w5/1/
My changes:
function hitImage(x, y) {
if (x > imageX_hit * scaleFactor && x < imageX_hit * scaleFactor + img_canvas.width * scaleFactor &&
y > imageY_hit * scaleFactor && y < imageY_hit * scaleFactor + img_canvas.height * scaleFactor)
return 1;
if (x > panoramaX * scaleFactor && x < panoramaX * scaleFactor + bg_canvas.width * scaleFactor &&
y > panoramaY * scaleFactor && y < panoramaY * scaleFactor + bg_canvas.height * scaleFactor)
return 2;
return 0;
}
and
function myFunction(evt) {
var delta = evt.wheelDelta ? evt.wheelDelta / 40 : evt.detail ? -evt.detail : 0;
if (delta > 0) scaleFactor = scaleFactor + 0.05;
else scaleFactor = scaleFactor - 0.05;
//imageX = imageX * scaleFactor;
//imageY = imageY * scaleFactor;
//imageX_hit = imageX_hit * scaleFactor;
//imageY_hit = imageY_hit * scaleFactor;
drawToMain();
}
So first, I uploaded a car to the canvas and gave it turning and motion properties. I tried to draw a circle to go alongside the car but it is not working properly. The circle is alone and flickering for some reason. I removed the timeout completely, and both the circle and car disappeared. Adjusting the timeout rate doesn't remove the flicker. Help me get them on the screen and keep them there together please?
http://jsbin.com/zogeraduze/1/edit?html,js,output
I don't have your car image, but it seems like you have a setInterval set to 30ms and you call a timeout every 10ms (which is equivalent to a setInterval), each time clearing the canvas, hence creating a flickering. You should have only one repaint function that should clear the canvas, draw the car and then draw the circle.
try
//Setting the canvas and context
var canvas = document.getElementById('gameCanvas');
var context = canvas.getContext('2d');
//Uploading car
var car = new Image();
car.src = "file:///H:/Desktop/Game/img/car.png";
//Setting properties of car
var x = 450;
var y = 730;
var speed = 10;
var angle = 990;
var mod = 0;
//Event listeners for keys
window.addEventListener("keydown", keypress_handler, false);
window.addEventListener("keyup", keyup_handler, false);
//Drawing the car turning and changing speed
function draw() {
x += (speed * mod) * Math.cos(Math.PI / 180 * angle);
y += (speed * mod) * Math.sin(Math.PI / 180 * angle);
context.save();
context.translate(x, y);
context.rotate(Math.PI / 180 * angle);
context.drawImage(car, -(car.width / 2), -(car.height / 2));
context.restore();
}
//Setting the keys
function keyup_handler(event) {
console.log('a');
if (event.keyCode == 38 || event.keyCode == 40) {
mod = 0;
}
}
//Setting all of the keys
function keypress_handler(event) {
console.log(event.keyCode);
if (event.keyCode == 38) {
mod = 1;
}
if (event.keyCode == 40) {
mod = -1;
}
if (event.keyCode == 37) {
angle -= 5;
}
if (event.keyCode == 39) {
angle += 5;
}
}
var context = $('#gameCanvas')[0].getContext('2d');
var width = $('#gameCanvas').width();
var height = $('#gameCanvas').height();
var circleX = width / 2;
var circleY = height / 2;
var circleVX = 1.0;
var circleVY = 0.0;
var circleR = 30;
function update() {
context.clearRect(0, 0, width, height);
/*
circleX = Math.random() * (width - 2 * circleR) + circleR;
circleY = Math.random() * (height - 2 * circleR) + circleR;
*/
draw();
drawCircle(circleX, circleY, circleR);
setTimeout(update, 10);
}
function canvasClick(event) {
var clickX = event.pageX;
var clickY = event.pageY;
var edgeX = clickX - circleX;
var edgeY = clickY - circleY;
var r = Math.sqrt(edgeX * edgeX + edgeY * edgeY);
if (r < circleR) {
context.clearRect(0, 0, width, height);
}
}
function drawCircle(x, y, r) {
context.beginPath();
context.arc(x, y, r, 0, 2 * Math.PI, false);
context.fillStyle = 'red';
context.fill();
context.lineWidth = 3;
context.strokeStyle = 'black';
context.stroke();
}
$('#gameCanvas').click(canvasClick);
update();
Also, look into https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame instead of using timeouts
I'm having trouble trying to make an animation with JavaScript and the HTML5 canvas element.
I need to have an animation that starts in the bottom right corner of my canvas, which moves up diagonally to the top right hand corner and then reverses back the other direction to create a back and forth movement.
I can get my animation to move diagonally, but then I can't get it to change the direction.
I'm also having trouble getting the animation to start from the bottom no matter what I do.
The code below currently moves my animation top to bottom diagonally.
var context;
var x = 0;
var y = 0;
var stepx = 1.55;
var stepy = 1.55;
function setupAnimCanvas() {
var canvas = document.getElementById('assignmenttwoCanvas');
if (canvas.getContext) {
ctx = canvas.getContext('2d');
setInterval('draw();', 20);
img = new Image();
img.src = '../images/dragon.png';
//animation();
}
}
startPos = (500, 500);
endPos = (0, 0);
function draw() {
ctx.clearRect(0,0, 500,500);
drawBackground();
ctx.drawImage(img, y, x);
x += 3;
if(x < endPos){
x -= stepx;
y += stepy;
}
else if (y > endPos) {
x += stepx;
y -= stepy;
}
else {
endPos = startPos;startPos = y;
}
moveit();
setTimeout('mover()',25);
}
You can use a delta value for x and y. When the x or y position is at start or end you just reverse the delta by setting delta = -delta;
var dx = -3, dy = -3;
Then simply check for any criteria that would reverse the direction:
if (x < endPos[0] || x > startPos[0] || y < endPos[1] || y > startPos[1] ) {
dx = -dx;
dy = -dy;
}
See demo here:
http://jsfiddle.net/AbdiasSoftware/5dSSZ/
The essence of this (see comments and original source lines at fiddler-link)
var startPos = [500, 500];
var endPos = [0, 0];
var dx = -3, dy = -3;
var x = startPos[0], y = startPos[1];
function draw() {
ctx.clearRect(0, 0, 500, 500);
ctx.fillRect(x, y, 20, 20); //for demo as no image
x += dx;
y += dy;
if (x < endPos[0] || x > startPos[0] ||
y < endPos[1] || y > startPos[1] ) {
dx = -dx;
dy = -dy;
}
setTimeout(draw, 16); //requestAnimationFrame is a better choice
}