[英]Canvas on mousemove
我正在使用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);
};
在鼠標事件中設置粒子繪制原型沒有幫助。 如果您在嘗試繪制原型之前不移動鼠標,則不會具有繪制功能。 Particle.draw
將等於undefined
,這不是函數,因此是錯誤。
您應該在定義對象之后設置原型,並且只進行一次。
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 px += p.vx; py += p.vy; // keep on the canvas px = (((px + maxPSize) % pWidth) + pWidth) % pWidth - maxPSize; py = (((py + 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(); }());
canvas { margin : -8px; border-width : 0px; }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.