【发布时间】:2017-01-27 23:56:12
【问题描述】:
我一直在研究一些关于动画的研究,并且在一些 jquery 的帮助下,我创建了一个动画,当用户通过 mousemove jquery 事件移动的方块与屏幕上的另一个方块发生碰撞时(被击中的 square2) 将移动一定的长度,如果命中框在其边缘附近被击中,则对象预计会旋转。我遇到的问题是,当对象旋转时,它会产生正方形轮廓的伪残像。起初我认为我可以通过使用 clearRect() 方法来删除 afterImage 以包含 square2 周围的更大区域,但这样做不仅使我的问题无法解决,而且还会使我的第一个正方形的一部分不可见,这是不希望的。如果有人能帮我弄清楚我在这段代码中哪里出错了,我会很感激的。
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();
【问题讨论】:
标签: javascript animation canvas