Source: flowfield.js

var FlowFieldMarker = require('./flowfieldmarker'),
    Item = require('burner').Item,
    SimplexNoise = require('quietriot'),
    System = require('burner').System,
    Utils = require('burner').Utils,
    Vector = require('burner').Vector;

/**
 * Creates a new FlowField.
 *
 * @constructor
 */
function FlowField() {
  Item.call(this);
}
Utils.extend(FlowField, Item);


/**
 * Initializes an instance.
 *
 * @param {Object} [opt_options=] A map of initial properties.
 * @param {number} [opt_options.resolution = 50] The lower the value, the more vectors are created
 *    to define the flow field. Low values increase processing time to create the field.
 * @param {number} [opt_options.perlinSpeed = 0.01] The speed to move through the Perlin Noise space.
 * @param {number} [opt_options.perlinTime = 100] Sets the Perlin Noise time.
 * @param {Object} [opt_options.field = null] A list of vectors that define the flow field.
 * @param {Object} [opt_options.createMarkers = false] Set to true to visualize the flow field.
 * @param {Object} [opt_options.world = System.firstWorld()] The flowField's world.
 */
FlowField.prototype.init = function(world, opt_options) {
  FlowField._superClass.init.call(this, world, opt_options);

  var options = opt_options || {};

  this.resolution = typeof options.resolution !== 'undefined' ? options.resolution : 50;
  this.perlinSpeed = typeof options.perlinSpeed !== 'undefined' ? options.perlinSpeed : 0.01;
  this.perlinTime = typeof options.perlinTime !== 'undefined' ? options.perlinTime : 100;
  this.field = options.field || null;
  this.createMarkers = !!options.createMarkers;
  this.world = world;
  this.lifespan = -1;
};

/**
 * Builds a FlowField.
 */
FlowField.prototype.build = function() {

  var col, colMax, row, rowMax, x, y, theta, fieldX, fieldY, field, angle,
      vectorList = {},
      world = this.world,
      cols = Math.ceil(world.width / parseFloat(this.resolution)),
      rows = Math.ceil(world.height / parseFloat(this.resolution)),
      xoff = this.perlinTime, // create markers and vectors
      yoff;

  for (col = 0, colMax = cols; col < colMax ; col += 1) {

    yoff = this.perlinTime;
    vectorList[col] = {};
    for (row = 0, rowMax = rows; row < rowMax ; row += 1) {

      x = col * this.resolution + this.resolution / 2; // get location on the grid
      y = row * this.resolution + this.resolution / 2;

      theta = Utils.map(SimplexNoise.noise(xoff, yoff), 0, 1, 0, Math.PI * 2); // get the vector based on Perlin noise
      fieldX = Math.cos(theta);
      fieldY = Math.sin(theta);
      field = new Vector(fieldX, fieldY);
      vectorList[col][row] = field;
      angle = Utils.radiansToDegrees(Math.atan2(fieldY, fieldX)); // get the angle of the vector

      if (this.createMarkers) {

        var ffm = new FlowFieldMarker();
        world.el.appendChild(ffm.init({ // create the marker
          location: new Vector(x, y),
          scale: 1,
          opacity: Utils.map(angle, -360, 360, 0.1, 0.75),
          width: this.resolution,
          height: this.resolution/2,
          field: field,
          angle: angle,
          colorMode: 'rgb',
          color: [200, 100, 50],
          borderRadius: 0,
          zIndex: 0
        }));
      }
      yoff += parseFloat(this.perlinSpeed);
    }
    xoff += parseFloat(this.perlinSpeed);
  }
  this.field = vectorList;
};

FlowField.prototype.step = function() {};

FlowField.prototype.draw = function() {};

module.exports = FlowField;