Get a System given a seed. So, why do I need that? Well, it's much nicer
to generate random particles if we can do it synchronously, so I keep track of a
seed so we can do everything in one call to your update! If you don't really
care about the seed, you can initialize it like this:
init (Random.initialSeed 0)If you want one that's actually pseudo-random, get a random seed with the
Random.independentSeed generator or pass the current time in when you
initialize your app from JavaScript.
Make a burst of a bunch of particles at once! Use this for things like confetti or fireworks. We use randomness here because 100 particles all doing exactly the same thing tends to be uninteresting.
If you haven't used the Random library before, check the docs at the top of
Particle.
We could make a burst of 50 confetti particles like this:
burst (Random.list 50 confettiParticles) systemUpdate all the particles by one step. Use it in your update function
whenever you get a Msg. Probably like this:
update msg model.systemView all the particles in the system. You'll need to provide a rendering
function for each particle—the same one you'd give to Particle.view—as well as
a list of attributes on the SVG element itself.
For example, if you wanted a full-screen particle display, it would look like this:
view viewConfetti
[ Html.Attributes.style "width" "100%"
, Html.Attributes.style "height" "100vh"
]
systemSubscribe to the right events in the browser. In this case, that's
requestAnimationFrame deltas. You don't have to worry about how to hook up the
right functions, just stick this in the subscriptions of your app and call
update with the Msg you get.
The first parameter here is a list of emitters. These are different than bursts in that they continuously spout particles. This can create particle effects like water or fire. They live in the subscription so that we can manage our subscriptions intelligently. It also means that you don't have to store generators—which contain functions—in your model. So maybe you want to turn a stream of water on and off, or control the pressure? That's great! You can store those parameters in your model, and use them to make your generators.
Each emitter gets the time since the last frame in milliseconds so that it can calculate how many particles to emit. So, for example, a water emitter that emitted 60 drops per second may look like this:
waterEmitter : Float -> Generator (List (Particle Droplet))
waterEmitter delta =
Random.list (ceiling (delta * (60 / 1000))) dropletGeneratorThen you'd use this in your subscription like this:
sub [ waterEmitter ] ParticleMsg model.systemIf this doesn't make sense, go read the Water.elm example, which ties
all of this together.
Hold and simulate all your particles at once! This is a whole lot easier than managing all the subscriptions and emitters yourself.