Javascript 画布单击粒子爆炸效果不以鼠标位置为目标

Javascript 画布单击粒子爆炸效果不以鼠标位置为目标,javascript,html,typescript,canvas,ionic2,Javascript,Html,Typescript,Canvas,Ionic2,我试图做一个简单的粒子爆炸效果,当用户点击应用程序的某个地方时,它会得到用户的点击位置,创建一个画布,创建爆炸效果,然后移除画布 我对canvas完全陌生,从这个网站上得到了这个想法: 在这种情况下,爆炸效果的点击位置不正确,应该从点击区域的中心开始。但是,我从左/上角走得越远,我的效果就会显示得越低 下面是一些代码: 在我的app.components.ts(它是主文件,我需要它在每一页上工作,所以我决定将我的代码放在这里)我有以下内容: import { Particle } from '.

我试图做一个简单的粒子爆炸效果,当用户点击应用程序的某个地方时,它会得到用户的点击位置,创建一个画布,创建爆炸效果,然后移除画布

我对canvas完全陌生,从这个网站上得到了这个想法:

在这种情况下,爆炸效果的点击位置不正确,应该从点击区域的中心开始。但是,我从左/上角走得越远,我的效果就会显示得越低

下面是一些代码:

在我的
app.components.ts
(它是主文件,我需要它在每一页上工作,所以我决定将我的代码放在这里)我有以下内容:

import { Particle } from './Particle'; //  IMPORT A PARTICLE FUNCTION

// THESE ARE MY PARTICLE OPTIONS
public ANGLE: number = 90;
public SPEED: number = 8;
public PARTICLE_SIZE: number = 1;
public NUMBER_OF_PARTICLES: number = 20;
public RANGE_OF_ANGLE: number = 360;
public PARTICLE_LIFESPAN: number = 15;
public PARTICLE_COLOR: string = 'rgb(255,0,0)';
public particles: any[] = [];
public pCtxWidth: number = window.innerWidth; // not using
public pCtxHeight: number = window.innerHeight; // not using

document.addEventListener('click', (data) => {

  // CREATE MY CANVAS HTML ELEMENT AND APPEND IN THE BODY
  let c = document.createElement('canvas');
  c.className = 'clique';
  c.style.position = 'absolute';
  c.style.width = String(window.innerWidth) + 'px'; //I'M USING THE WHOLE SCREEN SIZE, BUT IT DOESN'T NEEDS TO BE THAT BIG, IT CAN BE 80px
  c.style.height = String(window.innerHeight) + 'px';
  c.style.left = '0px';
  c.style.top = '0px';
  document.body.appendChild(c);

  // GET MY PAGE CLICK POSITION, ALSO TRIED WITHOUT - c.offsetLeft
  const x = data.pageX - c.offsetLeft,
        y = data.pageY - c.offsetTop;

  // CREATE MY 2DCONTEXT AND CALL THE SPARK FUNCTION
  let pCtx = c.getContext("2d");
  this.spark(x, y, this.ANGLE, pCtx, c);
  this.smartAudio.play('click');
}, true);

// draw a new series of spark particles
spark = (x, y, angle, pCtx, c) => {
    // create 20 particles 10 degrees surrounding the angle
    for (var i = 0; i < this.NUMBER_OF_PARTICLES; i++) {
        // get an offset between the range of the particle
        let offset = Math.round(this.RANGE_OF_ANGLE * Math.random())
            - this.RANGE_OF_ANGLE / 2;
        let scaleX = Math.round(this.SPEED * Math.random()) + 1;
        let scaleY = Math.round(this.SPEED * Math.random()) + 1;
        this.particles.push(new Particle(x, y,
            Math.cos((angle + offset) * Math.PI / 180) * scaleX,
            Math.sin((angle + offset) * Math.PI / 180) * scaleY,
            this.PARTICLE_LIFESPAN, this.PARTICLE_COLOR, pCtx));
    }
    this.animationUpdate(pCtx, c, x, y);
}

animationUpdate = function (pCtx, c, x, y) {
    // update and draw particles
    pCtx.clearRect(0, 0, x, y);
    for (var i = 0; i < this.particles.length; i++) {
        if (this.particles[i].dead()) {
            this.particles.splice(i, 1);
            i--;
        }
        else {
            this.particles[i].update();
            this.particles[i].draw(pCtx);
        }
    }
    if (this.particles.length > 0) {
        // await next frame
        requestAnimationFrame(() => { this.animationUpdate(pCtx, c, x, y) });
    } else {
        document.body.removeChild(c);
    }
}
那我做错了什么?如何使粒子效果准确地在单击的位置爆炸

这是我得到的图片,我点击了左上角的X,但是爆炸发生在点击区域的下方


提前谢谢。

我看不到您在设置画布分辨率,您只是在设置画布显示大小。这将解释渲染和用户IO之间的不匹配

创建画布时,请尝试以下操作

c.style.width = (c.width = innerWidth) + 'px'; 
c.style.height = (c.height = innerHeight) + 'px';

这将使画布分辨率与显示大小相匹配,这样您将在正确的像素位置进行渲染。

如此简单,我简直不敢相信哈哈哈,谢谢,伙计,解决了我的问题。
c.style.width = (c.width = innerWidth) + 'px'; 
c.style.height = (c.height = innerHeight) + 'px';