简体   繁体   English

鼠标移动画布

[英]Canvas on mousemove

I'm creating some basic animation with JavaScript and I am really stuck. 我正在使用JavaScript创建一些基本的动画,但我真的很困惑。 I wanna create animation that draw particles and when mouse go over them it will follow the mouse but every other particles will go random. 我想创建动画来绘制粒子,当鼠标移到它们上方时,它将跟随鼠标移动,但其他所有粒子将随机化。 I don't wanna use jQuery or some of this staff. 我不想使用jQuery或其中一些人员。 So far I got this. 到目前为止,我明白了。 Can someone give me some hint or advice please? 有人可以给我一些提示或建议吗? So far I getting error that 到目前为止,我得到的错误

Uncaught TypeError: particles[i].draw is not a function. 未捕获的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);
};

Setting the particle draw prototype inside the mouse event is no helping. 在鼠标事件中设置粒子绘制原型没有帮助。 If you don't move the mouse befor you try to draw the prototype will not have the function draw. 如果您在尝试绘制原型之前不移动鼠标,则不会具有绘制功能。 Particle.draw will equal undefined which is not a function and thus the error. Particle.draw将等于undefined ,这不是函数,因此是错误。

You should set the prototype just after you define the Object and do it only once. 您应该在定义对象之后设置原型,并且只进行一次。

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
}

And remove it from the mouse event 并将其从鼠标事件中删除

That should stop the error 那应该停止错误

As there are other problems and I couldn't workout what you were trying to achieve so I added a snippet that may interest you. 由于还有其他问题,我无法锻炼您想要达到的目标,因此我添加了一段您可能会感兴趣的片段。 Along the lines of how I would do it (well how I tell people to do it as it gets very complex to get high performace particles and SO does not give room for that). 遵循我将如何做的路线(以及我如何告诉人们去做,因为要获得高性能粒子变得非常复杂,因此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