Jump to content

Thousands of interactive Sprites - performance issues


arek
 Share

Recommended Posts

Hi,

i am trying to render thousands (e.g. 300 000) of Sprites from Canvas. Each is changing texture on pointerover and pointerout event. Performance is not very good.

Is it possible to optimize it somehow?

Code here:

window.onload = () => {
  const [canvas, canvasHover] = createCanvas();

  let app = new PIXI.Application({
    width: window.innerWidth,
    height: window.innerHeight,
    antialias: true,
    transparent: false,
    resolution: 1
  });

  document.body.appendChild(app.view);

  const stage = app.stage;
  stage.interactive = true;

  const container = new PIXI.Container();
  let baseCircle = new PIXI.BaseTexture.from(canvas);
  let baseCircleHover = new PIXI.BaseTexture.from(canvasHover);
  let texture = new PIXI.Texture(baseCircle);
  let textureHover = new PIXI.Texture(baseCircleHover);

  for (let i = 1; i <= 300000; i++) {
    const sprite = new PIXI.Sprite(texture);
    sprite.interactive = true;
    sprite.buttonMode = true;
    const x = _.random(0, 1400);
    const y = _.random(0, 700);
    sprite.x = x
    sprite.y = y;

    sprite.on('pointerover', onMouseOver)
      .on('pointerout', onMouseOut);

    container.addChild(sprite);

  }
  app.stage.addChild(container);

  function onMouseOver() {
    this.isOver = true;
    this.texture = textureHover;
  }

  function onMouseOut() {
    this.isOver = false;
    this.texture = texture;
  }
}

function createCanvas() {
  const canvas = document.createElement('canvas');
  canvas.id = "canvasCircle";
  canvas.width = 16;
  canvas.height = 16;
  canvas.style.zIndex = 1111;
  canvas.style.position = "absolute";
  canvas.style.top = "50px";
  canvas.style.left = "50px";
  var ctx = canvas.getContext("2d");
  ctx.beginPath();
  ctx.arc(8, 8, 7, 0, 2 * Math.PI);
  ctx.fillStyle = '#0081ff';
  ctx.strokeStyle = '#ffffff';
  ctx.lineWidth = 1;
  ctx.fill();
  ctx.stroke();

  const canvasHover = document.createElement('canvas');
  canvasHover.id = "canvasCircleHover";
  canvasHover.width = 16;
  canvasHover.height = 16;
  canvasHover.style.zIndex = 1111;
  canvasHover.style.position = "absolute";
  canvasHover.style.top = "50px";
  canvasHover.style.left = "100px";
  var ctx = canvasHover.getContext("2d");
  ctx.beginPath();
  ctx.arc(8, 8, 7, 0, 2 * Math.PI);
  ctx.fillStyle = '#fff000';
  ctx.strokeStyle = '#ffffff';
  ctx.lineWidth = 1;
  ctx.fill();
  ctx.stroke();

  return [canvas, canvasHover];
}

Thank you!

Link to comment
Share on other sites

300k at 60fps seems viable on desktop with ParticleContainer.  Why do all the circles need their own interaction events?  You may do better to use a "system" ... color map, distance calculation, tree search etc to determine which circles are "over".  And those "circles" would be pretty small to fit them all on screen at once, are they all needed, and is it essential that every interaction occurs every update?  Many ways to optimise, just change some of the upfront assumptions.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...