tsparticles / astro

tsParticles Astro official component
MIT License
33 stars 4 forks source link

Speed/distance options are wrongly applied when particles are not immediately rendered upon page load #5

Closed kslstn closed 1 year ago

kslstn commented 1 year ago

When I don't run loadFull(tsParticles) upon page load, my options don't work; it's like the speed is ignored or set to 0 or the size of the viewport is wrongly calculated as tiny or something. To make sure it wasn't something specific to my project, I've done the following and reproduced this issue:

  1. Fork the Astro Basics repo
  2. Install astro-particles
  3. Create a component, add the code from 'How to use'
  4. Copy the explosions options from the homepage

I've done the above in this Stackblitz. If you now click the button with the 'Start particles' label, you'll get the same weird effect as in https://github.com/matteobruni/tsparticles/issues/4989.

If you uncomment line 139 from ./src/components/MyParticles.astro, you'll see that the particles are rendered as intended. If you then press the 'Start particles' button again, they're also rendered correctly.

(I've posted a similar comment under bug 4989, which was marked as off-topic. I'm assuming it's better to open this more generic bug report. Considering I'm not doing much beyond applying the most basic example in the docs, this looks like a real issue to me and I want to make sure that anyone who'd care and can do something about it can see it).

tsParticles Version

2.10.1

tsParticles Configuration

"astro-particles": "^2.9.3", "tsparticles": "^2.10.1", "tsparticles-engine": "^2.10.1"

What browsers are you seeing the problem on?

Firefox, Chrome, Safari

matteobruni commented 1 year ago

Fixed in astro-particles v2.10.0, the README file is updated for this.

kslstn commented 1 year ago

Much appreciated! I'm still experiencing the same issue when I remove the init="particlesInit" though (see updated Stackblitz - you need to look really close at the bottom of the viewport). Maybe manually starting the particles now requires another method?

Just to be clear—I removed the init attribute because the particles should not start at page load; only on button click.

matteobruni commented 1 year ago

The init attribute is required, if you want to spawn particles with a button, you need to use the loaded attribute too that returns to your component the container that contains methods for spawning particles on request, like addEmitter (sample described here in React, but the concept is the same)

kslstn commented 1 year ago

Ah okay, thank you! I got it working like this, in case anyone else wants to do something similar:

<script>
  import { type Container, type Engine, tsParticles } from "tsparticles-engine";
  import { loadFull } from "tsparticles";

  // the function name is the parameter passed to the init attribute
  // required
  // add the function to window is mandatory, it will be searched there
  window.particlesInit = async function (engine: Engine) {
    await loadFull(engine);
  }

  // the function name is the parameter passed to the loaded attribute
  // optional
  // add the function to window is mandatory, it will be searched there
  window.particlesLoaded = function (container: Container) {
    container.pause()
  }

  async function start(){
    await loadFull(tsParticles);
  };
  const button = document.getElementById('button')
  button.addEventListener('click', ()=>{ start()}, false)
</script>

<Particles id="tsparticles" options={options} init="particlesInit" loaded="particlesLoaded"/>
<button id="button">Start particles</button>

TBH I really don't know what I'm doing here, but it seems to work so I'm happy.

matteobruni commented 1 year ago

Calling every time loadFull is pretty heavy, check out this sample and you see the addEmitter function at work. The options contains no particles.number (default: 0) and emitters as an empty array so nothing is loaded at start. You can call container.addEmitter (two params, first is emitter options, second is position {x:number, y:number} object) to spawn particles

kslstn commented 1 year ago

Great, thank you, that approach gives me more flexibility, because that way I can also change the emitter options for each call. It looks like I don't need/can't use astro-particles now though, am I right?

matteobruni commented 1 year ago

It’s not necessary for your usage, the component acts only as a placeholder in your case