API Docs for: 0.1.5
Show:

File: src\hygress.js

import CanvasRenderer from "canvasrenderer";
import Hypotrochoid from "./hypotrochoid";

/**
 * Hygress.
 * A hy(potrochoid pro)gress visualisation.
 *
 * @class Hygress
 * @constructor
 * @extends CanvasRenderer
 * @param {Object} [options] - The settings.
 * @param {Number} [options.dt=1/60] - The update rate in seconds.
 * @param {Object} [options.hypotrochoid] - The hypotrochoid settings. If none is supplied, a random one will be created.
 * @param {HTMLCanvasElement} [options.canvas] - The canvas to use. A new one will be created if none is supplied.
 * @param {Boolean} [options.clearCanvas=true] - Whether the canvas should be cleared before rendering.
 * @param {Boolean} [options.colourRoll=true] - Whether the colour should continuously change (rainbow).
 * @param {Number} [options.hue=0.0] - The hue in degree.
 * @param {Number} [options.saturation=100.0] - The saturation in percent.
 * @param {Number} [options.luminance=50.0] - The luminance in percent.
 * @param {Number} [options.opacity=0.75] - The initial opacity.
 * @param {Number} [options.scale=1.0] - The initial scale.
 * @param {Number} [options.transitionTime=0.25] - The initial transitionTime.
 * @param {Array} [options.size] - The canvas size.
 */

export default function Hygress(options) {

	CanvasRenderer.call(this, options);

	/**
	 * The internal hypotrochoid instance.
	 *
	 * @property ht
	 * @type Hypotrochoid
	 * @private
	 */

	this.ht = new Hypotrochoid();

	/**
	 * The transition time.
	 *
	 * @property transitionTime
	 * @type Number
	 */

	this.transitionTime = 0.25;

	/**
	 * The internal opacity transition values.
	 *
	 * @property _opacity
	 * @type Number
	 * @private
	 */

	this._opacity = {
		start: 0.0,
		difference: 0.0,
		target: 0.75,
		elapsed: 0,
		transitionActive: false
	};

	/**
	 * The internal scale transition values.
	 *
	 * @property _scale
	 * @type Number
	 * @private
	 */

	this._scale = {
		start: 0.0,
		difference: 0.0,
		target: 0.0,
		max: 0.0,
		factor: 1.0,
		elapsed: 0,
		transitionActive: false
	};

	/**
	 * Visible flag, used to determine if the hypotrochoid
	 * should be drawn this frame.
	 *
	 * @property visible
	 * @type Boolean
	 * @private
	 */

	this.visible = true;

	// Set the initial canvas size and the hypotrochoid's size.
	this.size = this.size;

	// Overwrite the default values.
	if(options !== undefined) {

		if(options.dt !== undefined) { this.dt = options.dt; }
		if(options.clearCanvas !== undefined) { this.clearCanvas = options.clearCanvas; }
		if(options.transitionTime !== undefined) { this.transitionTime = options.transitionTime; }
		if(options.colourRoll !== undefined) { this.ht.colourRoll = options.colourRoll; }
		if(options.hue !== undefined) { this.ht.hue = options.hue; }
		if(options.saturation !== undefined) { this.ht.saturation = options.saturation; }
		if(options.luminance !== undefined) { this.ht.hue = options.luminance; }
		if(options.canvas !== undefined) { this.canvas = options.canvas; }

		this.ht.settings = options.hypotrochoid;
		this.size = options.size;

		if(options.opacity !== undefined) {

			this.ht.opacity = this._opacity.target = options.opacity;

		}

		if(options.scale !== undefined) {

			this._scale.factor = options.scale;
			this.ht.d *= this._scale.factor;

		}

	}

	// Update the visible flag.
	this.visible = this.ht.opacity > 0.0 && this.ht.d > 0.0;

}

Hygress.prototype = Object.create(CanvasRenderer.prototype);
Hygress.prototype.constructor = Hygress;

/**
 * The hypotrochoid.
 * Assigning a new object only overwrites the defined
 * fields and keeps the other ones.
 *
 * @property hypotrochoid
 * @type Object
 */

Object.defineProperty(Hygress.prototype, "hypotrochoid", {

	get: function() { return this.ht.settings; },
	set: function(x) { this.ht.settings = x; }

});

/**
 * The size of the internal canvas.
 * 
 * @property size
 * @type Array
 * @example
 *  [width, height]
 */

Object.defineProperty(Hygress.prototype, "size", {

	get: function() {

		return [
			this.ctx.canvas.width,
			this.ctx.canvas.height
		];

	},

	set: function(x) {

		var min;

		if(x !== undefined && x.length === 2) {

			min = (x[0] < x[1]) ? x[0] : x[1];
			this.ctx.canvas.width = min;
			this.ctx.canvas.height = min;
			this.htSize = min >> 1;
			this.ht.origin.x = this.ht.origin.y = this._scale.max;

		}

	}

});

/**
 * The hypotrochoid's size.
 *
 * @property htSize
 * @type Number
 */

Object.defineProperty(Hygress.prototype, "htSize", {

	get: function() { return this.ht.d; },

	set: function(x) {

		if(x !== undefined && typeof x === "number" && !isNaN(x)) {

			this._scale.max = x;
			this._scale.target = this._scale.factor * this._scale.max;

			if(!this._scale.transitionActive) {

				this.ht.d = this._scale.target;

			}

		}

	}

});

/**
 * The hypotrochoid's origin.
 *
 * @property origin
 * @type Array
 * @example
 *  [x, y]
 */

Object.defineProperty(Hygress.prototype, "origin", {

	get: function() { return this.ht.origin; },

	set: function(x) {

		if(x !== undefined && x.length === 2) {

			this.ht.origin.x = x[0];
			this.ht.origin.y = x[1];

		}

	}

});

/**
 * The hypotrochoid's colour roll flag.
 *
 * @property colourRoll
 * @type Boolean
 */

Object.defineProperty(Hygress.prototype, "colourRoll", {

	get: function() { return this.ht.colourRoll; },

	set: function(x) {

		if(x !== undefined && typeof x === "boolean") {

			this.ht.colourRoll = x;

		}

	}

});

/**
 * The hypotrochoid's hue in degree.
 *
 * @property hue
 * @type Number
 */

Object.defineProperty(Hygress.prototype, "hue", {

	get: function() { return this.ht.colour; },

	set: function(x) {

		if(x !== undefined && typeof x === "number" && !isNaN(x)) {

			this.ht.hue = x;

		}

	}

});

/**
 * The hypotrochoid's saturation in percent.
 *
 * @property saturation
 * @type Number
 */

Object.defineProperty(Hygress.prototype, "saturation", {

	get: function() { return this.ht.colour; },

	set: function(x) {

		if(x !== undefined && typeof x === "number" && !isNaN(x)) {

			this.ht.saturation = x;

		}

	}

});

/**
 * The hypotrochoid's luminance in percent.
 *
 * @property luminance
 * @type Number
 */

Object.defineProperty(Hygress.prototype, "luminance", {

	get: function() { return this.ht.colour; },

	set: function(x) {

		if(x !== undefined && typeof x === "number" && !isNaN(x)) {

			this.ht.luminance = x;

		}

	}

});

/**
 * The line width of the hypotrochoid.
 *
 * @property lineWidth
 * @type Number
 */

Object.defineProperty(Hygress.prototype, "lineWidth", {

	get: function() { return this.ht.lineWidth; },

	set: function(x) {

		if(x !== undefined && typeof x === "number" && !isNaN(x)) {

			this.ht.lineWidth = x;

		}

	}

});

/**
 * The opacity of the hypotrochoid. Valid values: 0.0 to 1.0.
 *
 * Setting the opacity to a new value triggers a gradual change
 * towards the target value. The transition is linear and 
 * depends on the transitionTime variable.
 *
 * @property opacity
 * @type Number
 */

Object.defineProperty(Hygress.prototype, "opacity", {

	get: function() { return this.ht.opacity; },

	set: function(x) {

		if(x !== undefined && typeof x === "number" && !isNaN(x)) {

			if(x < 0.0) { x = 0.0; }
			else if(x > 1.0) { x = 1.0; }

			this._opacity.start = this.ht.opacity;
			this._opacity.target = x;
			this._opacity.difference = this.ht.opacity - this._opacity.target;
			this._opacity.elapsed = 0;
			this._opacity.transitionActive = true;
			this.visible = true;

		}

	}

});

/**
 * The scale of the hypotrochoid. Valid values: 0.0 to 1.0.
 *
 * Setting the scale to a new value triggers a gradual change
 * towards the target value. The transition is linear and 
 * depends on the transitionTime variable.
 *
 * @property scale
 * @type Number
 */

Object.defineProperty(Hygress.prototype, "scale", {

	get: function() { return this.ht.d; },

	set: function(x) {

		if(x !== undefined && typeof x === "number" && !isNaN(x)) {

			if(x < 0.0) { x = 0.0; }
			else if(x > 1.0) { x = 1.0; }

			this._scale.factor = x;
			this._scale.start = this.ht.d;
			this._scale.target = this._scale.factor * this._scale.max;
			this._scale.difference = this.ht.d - this._scale.target;
			this._scale.elapsed = 0;
			this._scale.transitionActive = true;
			this.visible = true;

		}

	}

});

/**
 * Updates the animation.
 *
 * @method update
 * @private
 * @param {Number} elapsed - The elapsed time since the last frame in milliseconds.
 */

Hygress.prototype.update = function(elapsed) {

	var opacity, scale, percentage;

	// Need seconds.
	elapsed /= 1000.0;

	if(this.visible) {

		opacity = this._opacity;
		scale = this._scale;

		if(opacity.transitionActive) {

			percentage = opacity.elapsed / this.transitionTime;
			if(percentage > 1.0 || isNaN(percentage)) { percentage = 1.0; }
			this.ht.opacity = opacity.start - percentage * opacity.difference;
			opacity.elapsed += elapsed;

			if(this.ht.opacity === opacity.target) {

				opacity.transitionActive = false;

				if(this.ht.opacity === 0.0) {

					this.draw();
					this.visible = false;

				}

			}

		}

		if(scale.transitionActive) {

			percentage = scale.elapsed / this.transitionTime;
			if(percentage > 1.0 || isNaN(percentage)) { percentage = 1.0; }
			this.ht.d = scale.start - percentage * scale.difference;
			scale.elapsed += elapsed;

			if(this.ht.d === scale.target) {

				scale.transitionActive = false;

				if(this.ht.d === 0.0) {

					this.draw();
					this.visible = false;

				}

			}

		}

		this.ht.update();

	}

};

/**
 * Draws the hypotrochoid.
 *
 * @method draw
 * @private
 */

Hygress.prototype.draw = function() {

	if(this.visible) {

		this.ht.draw(this.ctx);

	}

};

/**
 * Predefined hypotrochoids.
 *
 * @property Hypotrochoid
 * @type Object
 * @static
 * @final
 */

Hygress.Hypotrochoid = Object.freeze({
	ILLUMINATI: {r: 0.0147, R: 0.022, iterations: 220, rotation: 0.003},
	MULTISTAR: {r: 0.675, R: 1.64, iterations: 34, rotation: 0.023},
	HYPNOTIZER: {r: 0.42, R: 0.86, iterations: 43, rotation: 0.01},
	NEGATIVE: {r: 0.35, R: 0.614, iterations: 100, rotation: 0.023},
	WINDMILL: {r: 0.7853, R: 1.3751, iterations: 64, rotation: 0.01},
	TRIPLET: {r: 1.671, R: 2.509, iterations: 160, rotation: 0.046},
	PENTAGRAM: {r: 3.0, R: 5.0, iterations: 5, rotation: 0.03},
	RING: {r: 3.9, R: 5.0, iterations: 50, rotation: 0.013}
});