Skip to content

Instantly share code, notes, and snippets.

@arielsalminen
Last active May 19, 2017 18:06
Show Gist options
  • Save arielsalminen/7eb48b7c19fa8221c43c9bb962fd79e0 to your computer and use it in GitHub Desktop.
Save arielsalminen/7eb48b7c19fa8221c43c9bb962fd79e0 to your computer and use it in GitHub Desktop.
(function (window, document, undefined) {
"use strict";
/**
* The Universe object
*
* @constructor
*/
function Universe() {
this.loaded = false;
this.header = document.querySelector("header");
this.initialWidth = window.innerWidth || document.documentElement.clientWidth || document.getElementsByTagName('body')[0].clientWidth;
this.cvs = document.createElement("canvas");
this.ctx = this.cvs.getContext("2d");
}
Universe.prototype = {
constructor : Universe,
/**
* Intializes the instance
*
* @function
*/
init : function () {
this.box = this.header.getBoundingClientRect();
this.w = this.box.width;
this.h = this.box.height;
this.numDotsOrig = 150;
this.size = 1.6;
if (this.w > 700) {
this.size = 2;
}
if (this.w > 1300 && this.w < 1600) {
this.numDotsOrig = 200;
} else if (this.w > 1600 && this.w < 2000) {
this.numDotsOrig = 250;
} else if (this.w > 2000) {
this.numDotsOrig = 300;
}
this.numDots = this.numDotsOrig;
this.currDot;
this.maxRad = this.w / 1.2;
this.minRad = this.w / 2.5;
if (this.w > 500 && this.w < 800) {
this.maxRad = this.w / 1.5;
this.minRad = this.w / 3;
} else if (this.w > 800 && this.w < 1000) {
this.maxRad = this.w / 1.8;
this.minRad = this.w / 6;
} else if (this.w > 1000 && this.w < 1600) {
this.maxRad = this.w / 2;
this.minRad = this.w / 6;
} else if (this.w > 1600) {
this.maxRad = this.w / 2.3;
this.minRad = this.w / 8;
}
this.radDiff = this.maxRad - this.minRad;
this.dots = [];
this.centerPt = {x:0, y:0};
this.prevFrameTime = 0;
while(this.numDots--) {
this.currDot = {};
this.currDot.radius = this.minRad + Math.random() * this.radDiff;
this.currDot.ang = (1 - Math.random() * 2) * Math.PI;
this.currDot.speed = (1 - Math.random() * 2) * 0.005;
this.currDot.intensity = Math.round(Math.random() * 255);
this.currDot.fillColor = "rgb(" + this.currDot.intensity * 255 + "," + this.currDot.intensity + "," + this.currDot.intensity + ")";
this.dots.push(this.currDot);
}
this._centerPt = this.centerPt;
this._context = this.ctx;
this.dX = 0;
this.dY = 0;
this.prevFrameTime = 0;
this.cvs.width = this.w;
this.cvs.height = this.h;
this.centerPt.x = Math.round(this.w / 2);
this.centerPt.y = Math.round(this.h / 2);
if (!this.loaded) {
this.generateDomStructure();
this.initThrottle();
this.requestUpdate();
this.loaded = true;
}
},
/**
* Updates universe when needed
*
* @function
* @private
*/
requestUpdate : function (elapsedTime) {
var timeSinceLastFrame = elapsedTime - (this.prevFrameTime || 0);
// queue up an rAF draw call
if (window.matchMedia) {
if (!window.matchMedia('(prefers-reduced-motion)').matches) {
requestAnimFrame(util.bind(this.requestUpdate, this));
}
} else {
requestAnimFrame(util.bind(this.requestUpdate, this));
}
// if we *don't* already have a first frame, and the
// delta is less than 33ms (30fps in this case) then
// don't do anything and return
if (timeSinceLastFrame < 30 && this.prevFrameTime) {
return;
}
// else we have a frame we want to draw at 30fps...
// capture the last frame draw time so we can work out
// a delta next time.
this.prevFrameTime = elapsedTime;
var n = this.numDotsOrig;
this._context.clearRect(0, 0, this.cvs.width, this.cvs.height);
while(n--) {
this.currDot = this.dots[n];
this.dX = this._centerPt.x + Math.sin(this.currDot.ang) * this.currDot.radius;
this.dY = this._centerPt.y + Math.cos(this.currDot.ang) * this.currDot.radius;
this.currDot.ang += this.currDot.speed;
this._context.fillStyle = this.currDot.fillColor;
this._context.fillRect(this.dX, this.dY, this.size, this.size);
}
},
/**
* Resizes the instance
*
* @function
* @private
*/
resize : function () {
this.currWidth = window.innerWidth || document.documentElement.clientWidth || document.getElementsByTagName('body')[0].clientWidth;
if (this.currWidth !== this.initialWidth) {
this.initialWidth = this.currWidth;
cancelAnimFrame(util.bind(this.update, this));
this.init();
}
},
/**
* Generates the DOM structure
*
* @function
* @private
*/
generateDomStructure : function () {
this.remove = document.querySelector("canvas");
if (this.remove) {
this.remove.parentNode.removeChild(this.remove);
}
this.cvs.classList.add("canvas--hidden");
this.header.appendChild(this.cvs);
this.cvs.classList.add("canvas--active");
},
/**
* Initialize throttled update
*
* @function
* @private
*/
initThrottle : function () {
this.throttledUpdate = util.onResizeEnd(this.resize, 100, this);
util.addListener(window, "resize", this.throttledUpdate, false);
}
};
/**
* Expose a public-facing API
*
* @param {String} CSS selector for target elements
* @param {Object} the options
*/
function expose() {
var uni = new Universe();
uni.init();
return uni;
}
window.universe = expose;
}(window, document));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment