jQuery Plasma

It's always necessary to keep your skills up as a professional developer, and I wanted to
do a bit more ES6 with webpack, which I hadn't done for a while. So, I decided to port my
Java plasma routine to Javascript just for fun. It also allowed me to test how to make jQuery
plugins using ES6.

So, what's plasma? This sort of thing:

Plasma is essentially a colour mapped interference pattern. The interference is caused by
a number of moving patterns that are based around sine waves.

Basic Usage

As with other jQuery plugins, include the libraries, create a div into which you want to put the widget and
call the $.plasma() function on it.

The plasma has various defaults that means is shows up as above, but these can be overridden as described below.

Options

As usual, options can be passed in as a Javascript object when mapping your element to a plasma.

$('#plasma').plasma( { ... options ... } );

Width and Height

Width and height are controlled by the width and height fields. These need to be pixel amounts
(without a 'px' suffix):

$('#plasma').plasma({
width: 300,
height: 70
});

Colour

The plasma comes with some built-in colour maps which can be referenced by name (in the ES6 they are a map of functions, but
I've made them available externally by name). The available list is: [RED_GREEN, PINK_YELLOW, RGB, GREY, ZEBRA, MAGNOLIA, STRANGE_WAVES, WHITE_WAVES].
They look like this:

Scaling

Due to the amount of pixels that Javascript is shifting around and doing calculations on, it
is preferable to minimize this pixel count. With the hardware accelerated, bi-linear interpolated image scaling
that occurs on today's browsers, it's actually possible to scale a plasma up without too much degradation.
For that we have the scale option.

With a scaling of 4 (a quarter of the full resolution in each dimension), there are 16x less pixels being moved
around, which can be important if the area being rendered is large enough. If you look closely, you can begin
to see the pixels showing up in the second one, but it barely notices.

Patterns

The patterns that are mixed to form the interference pattern are generated by functions. There are a number of
built-in functions in the plugin which can be accessed by name. The generators to use, and the order to aggregate
them in, is provided by the plasmas option, which takes a list of strings or objects.

If strings are provided, then these must be one of the names of the built-in pattern generators, which are one of:
["verticalBars","horizontalBars","rotatingZoomingBars","circles"]. They generate patterns as follows:

A pattern generator is just an object that has the following method in it:
getPlasma(values, time, height, width). values is a flattened
array of the pixels which is why it's useful to know the width and height. The time is
provided as a means for placing the frame being generated in time; the idea being that
higher frame rates will provide more frames with smaller time steps
but, overall, the same interference events will occur a the same time regardless of frame rate.

If you want to, you can supply your own pattern generator by giving the plasma
field an object containing the appropriate function. Behold this monstrosity:

Aggregations

After the various individual patterns are generated they are aggregated into a final
interference pattern using an aggregation method. There is only one built-in, which is
AVERAGE and is set by default. If you want to override it, supply a function
to the aggregator field with the following signature: function(plasmas,w).
plasmas is an array of each of the flattened pixel maps for each of the individual patterns.
The function should return a new array that is w*h long and contains values 0 <= v <= 255.

Here's a simple custom aggregator that takes the maximum of all patterns for each pixel.