I've been working on some studies with animation and with the help of some jquery I've created an animation where when a square that is moved by the users mouse through a mousemove jquery event collides with another square on the screen (square2) thats been hit will move a certain length and if the hitbox is struck near its edges than the object is expected to rotate. The problem ive been running into is that when the object rotates it creates a pseudo afterimage of the outline of the square. At first I thought that I could remove the afterImage by using a clearRect() method to encompass a larger area around square2, but doing this not only leaves my problem unresolved, but also makes a part of my first square invisible which is undesired. If anybody could hep me figure out where ive gone wrong in this code, would definitely appreciate it fellas.
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.width = 1000;
canvas.height = 400;
var width = canvas.width;
var height = canvas.height;
var particles = [];
var mouseSize = 50;
var isColliding = false;
var mouseX;
var mouseY;
var animationForward = false;
function particle() {
var particle = {
originX: width / 2,
originY: height / 2,
x: width / 2,
y: height / 2,
size: 30,
centerPointX: this.x + this.size / 2,
centerPointY: this.y + this.size / 2,
decay: .98,
vx: 0,
vy: 0,
rotate: 0,
vr: 0,
draw: function() {
ctx.fillStyle = "white";
ctx.fillRect(this.x, this.y, this.size, this.size)
// rotation logic
// method found at http://stackoverflow.com/questions/2677671/how-do-i-rotate-a-single-object-on-an-html-5-canvas
function drawImageRot(x, y, width, height, deg) {
ctx.clearRect(x, y, width, height);
//Convert degrees to radian
var rad = deg * Math.PI / 180;
//Set the origin to the center of the image
ctx.translate(x + width / 2, y + height / 2);
//Rotate the canvas around the origin
ctx.rotate(rad);
//draw the image
ctx.fillRect(width / 2 * (-1), height / 2 * (-1), width, height);
//reset the canvas
ctx.rotate(rad * (-1));
ctx.translate((x + width / 2) * (-1), (y + height / 2) * (-1));
}
//check for collision
if (mouseX < particles[0].x + particles[0].size &&
mouseX + mouseSize > particles[0].x &&
mouseY < particles[0].y + particles[0].size &&
mouseSize + mouseY > particles[0].y) {
isColliding = true;
} else {
isColliding = false;
}
//controlling velocity dependending on location of collision.
if (isColliding) {
//x axis
animationForward = true;
// checking below to see if mouseRect is hitting near the center of particleRect.
// if it hits near center the vy or vx will not be as high depending on direction and if it //does not than we will make square rotate
if (mouseX < this.x) {
this.vr = 3 + Math.random() * 10
if (mouseX + mouseSize / 2 > this.x) {
this.vx = 0 + Math.random() * 2;
} else {
this.vx = 3 + Math.random() * 3;
}
} else {
this.vr = -3 - Math.random() * 10
if (mouseX + mouseSize / 2 < this.x + this.size) {
this.vx = 0 - Math.random() * 2;
} else {
this.vx = -3 - Math.random() * 3;
}
}
//y axis checking
if (mouseY < this.y) {
if (mouseY + mouseSize / 2 > this.y) {
this.vy = 0 + Math.random() * 2;
} else {
this.vy = 3 + Math.random() * 3;
}
} else {
if (mouseY + mouseSize / 2 < this.y + this.size) {
this.vy = 0 - Math.random() * 2;
} else {
this.vy = -3 - Math.random() * 3;
}
}
}
//decay all motions each frame while animation is forward
if (animationForward) {
this.vx *= this.decay;
this.vy *= this.decay;
this.vr *= this.decay;
}
//when animation is done, set all velocities to 0
if (this.x != this.originX && Math.abs(this.vx) < .1 && this.y != this.originY && Math.abs(this.vy) < .1) {
animationForward = false;
this.vx = 0;
this.vy = 0;
this.vr = 0
}
//x check to see if animation over. if it is slowly put square back to original location
if (this.x != this.originX && !animationForward) {
if (this.x > this.originX) {
this.vx = -1;
}
if (this.x < this.originX) {
this.vx = 1;
}
if (this.x > this.originX && this.x - this.originX < 1) {
this.vx = 0;
this.x = this.originX;
}
if (this.x < this.originX && this.originX - this.x < 1) {
this.vx = 0;
this.x = this.originX;
}
}
// end x collison
// y check to see if animation over
if (this.y != this.originX && !animationForward) {
if (this.y > this.originY) {
this.vy = -1;
}
if (this.y < this.originY) {
this.vy = 1;
}
if (this.y > this.originY && this.y - this.originY < 1) {
this.vy = 0;
this.y = this.originY;
}
if (this.y < this.originY && this.originY - this.y < 1) {
this.vy = 0;
this.y = this.originY;
}
}
// end y collison
//check rotation
if (this.rotate != 0 && !animationForward) {
this.rotate = Math.round(this.rotate);
if (this.rotate < 0) {
if (this.rotate < -300) {
this.rotate += 10
} else if (this.rotate < -200) {
this.rotate += 7
} else if (this.rotate < -125) {
this.rotate += 5
} else if (this.rotate < -50) {
this.rotate += 3
} else {
this.rotate++;
}
} else {
if (this.rotate > 300) {
this.rotate -= 10;
} else if (this.rotate > 200) {
this.rotate -= 7
} else if (this.rotate > 125) {
this.rotate -= 5
} else if (this.rotate > 50) {
this.rotate -= 3
} else {
this.rotate--;
}
}
}
// move the rect based off of previous set conditions and make square rotate if edges hit
this.x += this.vx;
this.y += this.vy;
this.rotate += this.vr;
drawImageRot(this.x, this.y, this.size, this.size, this.rotate);
// boundary control
if (this.x + this.size > width || this.x < 0) {
this.vx = -this.vx * 2
}
if (this.y + this.size > height || this.y < 0) {
this.vy = -this.vy * 2
}
}
}
return particle;
}
function createParticles() {
particles.push(particle())
//wouldnt be too hard to put more particles. would have to go back and change the isColliding and animationForward global variable and make each object have their own to check. also would have to go back and implement for loops wherever i mention an element in my array
}
createParticles();
function draw() {
console.log(particles[0].rotate);
ctx.clearRect(0, 0, width, height);
ctx.fillStyle = 'white';
ctx.fillRect(mouseX, mouseY, mouseSize, mouseSize);
particles[0].draw();
requestAnimationFrame(draw);
}
$("#canvas").mousemove(function(event) {
mouseX = event.pageX;
mouseY = event.pageY;
})
window.onload = draw();