Plato on Github
Report Home
runner.js
Maintainability
52.79
Lines of code
190
Difficulty
39.64
Estimated Errors
1.94
Function weight
By Complexity
By SLOC
var Burner = require('burner'); var Mover = require('./items/mover'); var Oscillator = require('./items/oscillator'); var Particle = require('./items/particle'); var Utils = require('burner').Utils; var Vector = require('burner').Vector; var SimplexNoise = require('quietriot'); var Easing = require('./easing'); var Mask = require('./mask'); /** * Creates a new Runner. * @param {Object} base A map of properties describing the base of the tornado. * @param {Object} debris A map of properties describing the debris at the base of the tornado. * @param {Object} spine A map of properties describing the tornado's spine. * @param {Object} shell A map of properties describing the tornado's shell (funnel). * @constructor */ function Runner(base, opt_debris, opt_spine, opt_shell) { if (!base) { throw new Error('Runner requires a \'base\' parameter.'); } this.base = base; this.debris = opt_debris || null; this.spine = opt_spine || null; this.shell = opt_shell || null; } /** * Holds a Perlin noise value. * @type {number} * @memberof Runner */ Runner.noise = 0; /** * Initializes an instance of Runner. * @param {Object} [opt_options=] A map of initial world properties. * @param {Object} [opt_options.el = document.body] World's DOM object. * @param {number} [opt_options.width = 800] World width in pixels. * @param {number} [opt_options.height = 600] World height in pixels. * @param {number} [opt_options.borderWidth = 1] World border widthin pixels. * @param {string} [opt_options.borderStyle = 'solid'] World border style. * @param {Object} [opt_options.borderColor = 0, 0, 0] World border color. * @memberof Runner */ Runner.prototype.init = function(opt_options) { var options = opt_options || {}; Burner.System.Classes = { Mover: Mover, Oscillator: Oscillator, Particle: Particle }; Burner.System.setup(this._setupCallback.bind(this, options)); Burner.System.clock = 10000; // advance the clock so we start deeper in the noise space Burner.System.loop(this._getNoise.bind(this)); }; /** * Sets up the world and items. * @param {Object} options World options. * @memberof Runner * @private */ Runner.prototype._setupCallback = function(options) { var radionado = options.radionado; var world = Burner.System.add('World', { el: options.el || document.body, color: options.color || [40, 40, 40], width: options.width || 800, height: options.height || 600, borderWidth: options.borderWidth || 1, borderStyle: options.borderStyle || 'solid', borderColor: options.borderColor || [0, 0, 0], gravity: new Vector(), c: 0 }); // BASE this.base.configure(world); var myBase = Burner.System.add('Oscillator', this.base); // DEBRIS if (this.debris) { this.debris.configure({ parent: myBase }); Burner.System.add('Mover', this.debris); } // SPINE if (this.spine) { for (var i = 0, max = Math.floor(world.height / this.spine.density); i < max; i++) { var ease = Easing[this.spine.easing].call(null, i, 0, 1, max - 1); // joints var joint = Burner.System.add('Mover', { parent: myBase, offsetDistance: ease * world.height, offsetAngle: 270, opacity: this.spine.opacity, afterStep: this._jointAfterStep }); joint.index = i; joint.offsetFromAxis = this.spine.offsetFromAxis; // use Perlin noise to generate the parent node's offset from the funnel's y-axis // use easing so the effect is amplified joint.offsetFromCenter = Easing.easeInSine(i, 0, 1, max - 1) * SimplexNoise.noise(i * 0.1, 0) * 20; // pillows if (this.shell) { var easeShellShape = Easing[this.shell.easing].call(null, i, 0, 1, max - 1); var colorNoise = Math.floor(Utils.map(SimplexNoise.noise(i * 0.05, 0), -1, 1, this.shell.colorMin, this.shell.colorMax)); if (radionado) { for (var j = 0; j < (i + 1) * 1; j++) { Burner.Item.baseElement = 'input'; Burner.Item.baseElementAttributes = { type: 'radio' }; var rand = Utils.getRandomNumber; var osc = Burner.System.add('Oscillator', { perlin: false, parent: joint, blur: easeShellShape, color: [colorNoise, colorNoise, colorNoise], opacity: 1, scale: easeShellShape * 1, amplitude: new Vector(Utils.map(easeShellShape, 0, 1, 1, rand(50, 200)), Utils.map(easeShellShape, 0, 1, 1, rand(10, 64))), acceleration: new Burner.Vector(2 / (i + 1), 0.05), aVelocity: new Burner.Vector(rand(0, 40), rand(0, 40)) }); if (rand(1, 2) === 1) { osc.el.checked = 'checked'; } } } else { Burner.System.add('Oscillator', { width: this.shell.width, height: this.shell.height, parent: joint, opacity: this.shell.opacity, color: [colorNoise, colorNoise, colorNoise], boxShadowBlur: (easeShellShape * this.shell.blur) + this.shell.minFunnelWidth, boxShadowSpread: (easeShellShape * this.shell.spread) + this.shell.minFunnelWidth, boxShadowColor: [colorNoise, colorNoise, colorNoise], perlin: false, amplitude: new Vector((2 - easeShellShape) * 1, 0), acceleration: new Vector(1 / (i + 1), 0) }); } } } } }; /** * Called at the end of the joints' step function. * @memberof Runner * @private */ Runner.prototype._jointAfterStep = function() { if (this.offsetFromAxis) { var offset = this.index * this.offsetFromCenter * Runner.noise; this.location.x = this.location.x + (offset); } }; /** * Called at the end of each animation frame. * @memberof Runner * @private */ Runner.prototype._getNoise = function() { Runner.noise = SimplexNoise.noise(Burner.System.clock * 0.0001, 0); }; module.exports = Runner;