簡體   English   中英

鼠標移動畫布

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM