我用JavaScript创建了一些基本的动画,我真的被卡住了。我想创建绘制粒子的动画,当鼠标移过它们时,它将跟随鼠标,但其他所有粒子都会随机出现。我不想使用jQuery或其中一些工作人员。到目前为止我得到了这个。有人可以给我一些提示或建议吗?到目前为止,我收到错误
未捕获的TypeError:
particles[i].draw
不是函数。
window.onload = function() {
var canvas = document.createElement("canvas"),
c = canvas.getContext("2d"),
particles = {},
particleIndex = 0,
particleNum = 250;
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
document.body.appendChild(canvas);
c.fillStyle = "black";
c.fillRect(0, 0, canvas.width, canvas.height);
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
function Particle() {
this.x = getRandomArbitrary(0, 2000);
this.y = getRandomArbitrary(0, 1000);
this.r = Math.floor(getRandomArbitrary(0, 255));
this.g = Math.floor(getRandomArbitrary(0, 255));
this.b = Math.floor(getRandomArbitrary(0, 255));
this.l = getRandomArbitrary(0, 25);
particleIndex++;
particles[particleIndex] = this;
this.id = particleIndex;
}
canvas.addEventListener('mousemove', function(evt) {
var mousePos = getMousePos(canvas, evt);
Particle.prototype.draw = function() {
this.vx = Math.random();
this.vy = Math.random();
this.x += this.vx;
this.y += this.vy;
if (this.x <= mousePos.x) {
particles[this.id].vx = (mousePos.x - canvas.width / 2) / 100;
}
if (this.y <= mousePos.y) {
particles[this.id].vy = (mousePos.y - canvas.width / 2) / 100;
}
c.fillStyle = "rgba(" + this.r + "," + this.g + "," + this.b + ",0.2)";
c.beginPath();
c.arc(this.x, this.y, this.l, 0, Math.PI * 2, false);
c.fill();
};
}, false);
for (var i = 0; i <= particleNum; i++) {
new Particle();
}
setInterval(function() {
c.fillStyle = /*"rgba(255,255,255,0.1)"*/ "black";
c.fillRect(0, 0, canvas.width, canvas.height);
c.fillStyle = "rgba(255,255,255,0.1)";
for (var i in particles) {
particles[i].draw();
}
}, 30);
};
答案 0 :(得分:1)
在鼠标事件中设置粒子绘制原型没有用。如果你不移动鼠标,你试图绘制原型将不具有绘制功能。 Particle.draw
将等于undefined
,这不是函数,因而是错误。
您应该在定义Object之后立即设置原型,并且只执行一次。
function Particle() {
this.x = getRandomArbitrary(0, 2000);
this.y = getRandomArbitrary(0, 1000);
this.r = Math.floor(getRandomArbitrary(0, 255));
this.g = Math.floor(getRandomArbitrary(0, 255));
this.b = Math.floor(getRandomArbitrary(0, 255));
this.l = getRandomArbitrary(0, 25);
particleIndex++;
particles[particleIndex] = this;
this.id = particleIndex;
}
Particle.prototype.draw = function() {
// rest of draw code
}
将其从鼠标事件中删除
应该停止错误
由于还有其他问题,我无法锻炼你想要达到的目标,所以我添加了一个你可能感兴趣的片段。按照我将如何做的方式(以及我如何告诉人们这样做,因为它变得非常复杂以获得高性能粒子而且SO没有给出空间)。
// Note this code is in ES6 check browser support if you have problems
;(function() {
const canvas = document.createElement("canvas");
const c = canvas.getContext("2d");
const particleNum = 500;
const particleMouseAttract = 5; // how far the mouse attaction fx ranges
// must be > 0
const pMA = 1 + (particleMouseAttract / 100); // alias as I hate long var names in code
const mouseAttractDistStep = 10;
const mAD = mouseAttractDistStep; // alias as I hate long var names in code
canvas.width = innerWidth;
canvas.height = innerHeight;
const maxPSize = 10
const pWidth = innerWidth + maxPSize * 2;
const pHeight = innerHeight + maxPSize * 2;
document.body.appendChild(canvas);
canvas.addEventListener('mousemove', getMousePos);
requestAnimationFrame(update);
const mousePos = { x : 0, y : 0 };
const rand = (min, max = min + (min = 0))=> Math.random() * (max - min) + min;
const randI = (min, max)=> Math.floor(rand(min, max));
const particle = {
init(){ // call to create
this.x = rand(canvas.width);
this.y = rand(canvas.height);
this.vx = rand(-0.1, 0.1);
this.vy = rand(-0.1, 0.1);
this.rad = rand(1,maxPSize);
this.col = `rgba(${randI(255)},${randI(255)},${randI(255)},0.8)`;
return this; // returns referance to this particle
},
update () {
var x,y,mDist,p;
p = this;
p.vx += rand(-0.1, 0.1);
p.vy += rand(-0.1, 0.1);
// limit speed
mDist = Math.max(1,Math.sqrt(p.vx * p.vx + p.vy * p.vy));
p.vx = (p.vx / (mDist * mDist)) * 2;
p.vy = (p.vy / (mDist * mDist)) * 2;
//paticle to the mouse as vector
x = mousePos.x - this.x;
y = mousePos.y - this.y;
// get dist
mDist = Math.max(0.001,Math.sqrt(x * x + y * y)); // stop div by zero below
x /= mDist; // normalise vector to mouse
y /= mDist;
// apply inverted s curve that results in a value 1 for
// particles very close (mDist=0) and 0 for particles that
// are infinitly far. pMA controle the amount of attraction
// over dist.
mDist = - 2 / 1 + Math.pow(pMA, -mDist) + 2;
// mDist is now in the range 0 to 1 with one very close
// add the random vector and the to mouse vector parts
p.vx = p.vx * (1-mDist) + x * mAD * mDist;
p.vy = p.vy * (1-mDist) + y * mAD * mDist;
// move the particle
p.x += p.vx;
p.y += p.vy;
// keep on the canvas
p.x = (((p.x + maxPSize) % pWidth) + pWidth) % pWidth - maxPSize;
p.y = (((p.y + maxPSize) % pHeight) + pHeight) % pHeight - maxPSize;
},
draw () {
c.fillStyle = this.col;
c.beginPath();
c.arc(this.x, this.y, this.rad, 0, Math.PI * 2);
c.fill();
},
}
const particles = {
items : [],
update() {
for(var i = 0; i < this.items.length; i ++){ this.items[i].update() }
},
draw() {
for(var i = 0; i < this.items.length; i ++){ this.items[i].draw() }
},
add(particle) { this.items.push(particle) },
}
function start(){
for (var i = 0; i <= particleNum; i++) {
particles.add({...particle}.init());
}
requestAnimationFrame(update);
}
function getMousePos(evt) {
var bounds = canvas.getBoundingClientRect();
mousePos.x = evt.clientX - bounds.left;
mousePos.y = evt.clientY - bounds.top;
}
function update(time){
c.fillStyle = "black";
c.fillRect(0, 0, canvas.width, canvas.height);
particles.update()
particles.draw();
// get next frame
requestAnimationFrame(update);
};
start();
}());
&#13;
canvas {
margin : -8px;
border-width : 0px;
}
&#13;