From d6d4cf4b39db39edf748580db02c3a694d1b2625 Mon Sep 17 00:00:00 2001 From: Amadeus Demarzi Date: Wed, 23 Jul 2014 19:31:42 -0700 Subject: [PATCH 01/40] Grunt file cleanup Better indenatation, more readable --- website/source/Gruntfile.js | 112 ++++++++++++++++++------------------ 1 file changed, 55 insertions(+), 57 deletions(-) diff --git a/website/source/Gruntfile.js b/website/source/Gruntfile.js index 1d0f20f727..c1b922a036 100644 --- a/website/source/Gruntfile.js +++ b/website/source/Gruntfile.js @@ -1,69 +1,67 @@ +// jshint node:true module.exports = function(grunt) { - // Configuration goes here - grunt.initConfig({ +// Load plugins here +grunt.loadNpmTasks('grunt-contrib-less'); +grunt.loadNpmTasks('grunt-contrib-clean'); +grunt.loadNpmTasks('grunt-contrib-concat'); +grunt.loadNpmTasks('grunt-contrib-connect'); +grunt.loadNpmTasks('grunt-contrib-copy'); +grunt.loadNpmTasks('grunt-contrib-uglify'); +grunt.loadNpmTasks('grunt-contrib-watch'); +grunt.loadNpmTasks('grunt-recess'); - less: { - development:{ - files: { - "stylesheets/main.css": "stylesheets/main.less" - } +// Configuration goes here +grunt.initConfig({ + + less: { + development:{ + files: { + "stylesheets/main.css": "stylesheets/main.less" } - }, - - concat: { - options: { - separator: ';' - }, - site: { - src: [ - 'javascripts/app/app.js', - 'javascripts/app/util.js', - 'javascripts/app/homepage.js' - - ], - - dest: 'javascripts/app/deploy/site.js' - }, - }, - - uglify: { - app: { - files: { - 'javascripts/app/deploy/site.min.js': ['javascripts/app/deploy/site.js'] - } - } - }, - - watch: { - less: { - files: 'stylesheets/*.less', - tasks: ['less'] - }, - js: { - files: 'javascripts/app/*.js', - tasks: ['concat', 'uglify'] - } } + }, - }); + concat: { + options: { + separator: ';' + }, + site: { + src: [ + 'javascripts/app/app.js', + 'javascripts/app/util.js', + 'javascripts/app/homepage.js' + ], + dest: 'javascripts/app/deploy/site.js' + }, + }, - // Load plugins here - grunt.loadNpmTasks('grunt-contrib-less'); - grunt.loadNpmTasks('grunt-contrib-clean'); - grunt.loadNpmTasks('grunt-contrib-concat'); - grunt.loadNpmTasks('grunt-contrib-connect'); - grunt.loadNpmTasks('grunt-contrib-copy'); - grunt.loadNpmTasks('grunt-contrib-uglify'); - grunt.loadNpmTasks('grunt-contrib-watch'); - grunt.loadNpmTasks('grunt-recess'); + uglify: { + app: { + files: { + 'javascripts/app/deploy/site.min.js': ['javascripts/app/deploy/site.js'] + } + } + }, - // JS distribution task. - grunt.registerTask('dist-js', ['concat', 'uglify']); + watch: { + less: { + files: 'stylesheets/*.less', + tasks: ['less'] + }, + js: { + files: 'javascripts/app/*.js', + tasks: ['concat', 'uglify'] + } + } - // Full distribution task. - grunt.registerTask('dist', ['dist-js']); +}); - grunt.registerTask('default', ['watch']); +// JS distribution task. +grunt.registerTask('dist-js', ['concat', 'uglify']); + +// Full distribution task. +grunt.registerTask('dist', ['dist-js']); +grunt.registerTask('default', ['watch']); }; From 3adfc52092862e8291bb3db9285567c668fc50ff Mon Sep 17 00:00:00 2001 From: Amadeus Demarzi Date: Wed, 23 Jul 2014 19:50:28 -0700 Subject: [PATCH 02/40] Getting things ready... for dat import --- website/source/javascripts/app/app.js | 20 --- website/source/javascripts/app/deploy/site.js | 101 ----------- .../source/javascripts/app/deploy/site.min.js | 1 - website/source/javascripts/app/homepage.js | 49 ------ website/source/javascripts/app/util.js | 33 ---- website/source/javascripts/classy.js | 158 ------------------ website/source/javascripts/lib/Base.js | 145 ++++++++++++++++ .../javascripts/lib/String.substitute.js | 14 ++ website/source/javascripts/lib/Vector.js | 111 ++++++++++++ website/source/javascripts/lib/dbg.js | 60 +++++++ website/source/layouts/_footer.erb | 9 - website/source/stylesheets/_variables.less | 2 +- 12 files changed, 331 insertions(+), 372 deletions(-) delete mode 100644 website/source/javascripts/app/app.js delete mode 100644 website/source/javascripts/app/deploy/site.js delete mode 100644 website/source/javascripts/app/deploy/site.min.js delete mode 100644 website/source/javascripts/app/homepage.js delete mode 100644 website/source/javascripts/app/util.js delete mode 100644 website/source/javascripts/classy.js create mode 100644 website/source/javascripts/lib/Base.js create mode 100644 website/source/javascripts/lib/String.substitute.js create mode 100644 website/source/javascripts/lib/Vector.js create mode 100644 website/source/javascripts/lib/dbg.js diff --git a/website/source/javascripts/app/app.js b/website/source/javascripts/app/app.js deleted file mode 100644 index c75c3614ef..0000000000 --- a/website/source/javascripts/app/app.js +++ /dev/null @@ -1,20 +0,0 @@ -// -// app.js -// - -var APP = (function() { - - function initialize (){ - APP.Utils.runIfClassNamePresent('page-home', initHome); - } - - function initHome() { - APP.Homepage.init(); - } - - //api - return { - initialize: initialize - } - -})(); diff --git a/website/source/javascripts/app/deploy/site.js b/website/source/javascripts/app/deploy/site.js deleted file mode 100644 index 098863ffde..0000000000 --- a/website/source/javascripts/app/deploy/site.js +++ /dev/null @@ -1,101 +0,0 @@ -// -// app.js -// - -var APP = (function() { - - function initialize (){ - APP.Utils.runIfClassNamePresent('page-home', initHome); - } - - function initHome() { - APP.Homepage.init(); - } - - //api - return { - initialize: initialize - } - -})(); -;// -// util.js -// -var APP = APP || {}; - -APP.Utils = (function () { - return { - //check for mobile user agents - isMobile : (function(){ - if( navigator.userAgent.match(/Android/i) - || navigator.userAgent.match(/webOS/i) - || navigator.userAgent.match(/iPhone/i) - //|| navigator.userAgent.match(/iPad/i) - || navigator.userAgent.match(/iPod/i) - || navigator.userAgent.match(/BlackBerry/i) - || navigator.userAgent.match(/Windows Phone/i) - ){ - return true; - } - else { - return false; - } - })(), - - runIfClassNamePresent: function(selector, initFunction) { - var elms = document.getElementsByClassName(selector); - if (elms.length > 0) { - initFunction(); - } - } - } - -}());;//homepage.js - -var APP = APP || {}; - -(function () { - APP.Homepage = (function () { - return { - - ui : null, - - init: function () { - var _this = this; - - //cache elements - this.ui = { - $doc: $(window), - $hero: $('#jumbotron'), - $collapse: $('.navbar-collapse') - } - - this.addEventListeners(); - - }, - - addEventListeners: function(){ - var _this = this; - - if(APP.Utils.isMobile) - return; - - _this.ui.$doc.scroll(function() { - - //if collapseable menu is open dont do parrallax. It looks wonky. Bootstrap conflict - if( _this.ui.$collapse.hasClass('in')) - return; - - var top = _this.ui.$doc.scrollTop(), - speedAdj = (top*0.8), - speedAdjOffset = speedAdj - top; - - _this.ui.$hero.css('webkitTransform', 'translate(0, '+ speedAdj +'px)'); - _this.ui.$hero.find('.container').css('webkitTransform', 'translate(0, '+ speedAdjOffset +'px)'); - }) - } - } - }()); - -}(jQuery, this)); - diff --git a/website/source/javascripts/app/deploy/site.min.js b/website/source/javascripts/app/deploy/site.min.js deleted file mode 100644 index ea3bd58f64..0000000000 --- a/website/source/javascripts/app/deploy/site.min.js +++ /dev/null @@ -1 +0,0 @@ -var APP=function(){function a(){APP.Utils.runIfClassNamePresent("page-home",b)}function b(){APP.Homepage.init()}return{initialize:a}}(),APP=APP||{};APP.Utils=function(){return{isMobile:function(){return navigator.userAgent.match(/Android/i)||navigator.userAgent.match(/webOS/i)||navigator.userAgent.match(/iPhone/i)||navigator.userAgent.match(/iPod/i)||navigator.userAgent.match(/BlackBerry/i)||navigator.userAgent.match(/Windows Phone/i)?!0:!1}(),runIfClassNamePresent:function(a,b){var c=document.getElementsByClassName(a);c.length>0&&b()}}}();var APP=APP||{};!function(){APP.Homepage=function(){return{ui:null,init:function(){this.ui={$doc:$(window),$hero:$("#jumbotron"),$collapse:$(".navbar-collapse")},this.addEventListeners()},addEventListeners:function(){var a=this;APP.Utils.isMobile||a.ui.$doc.scroll(function(){if(!a.ui.$collapse.hasClass("in")){var b=a.ui.$doc.scrollTop(),c=.8*b,d=c-b;a.ui.$hero.css("webkitTransform","translate(0, "+c+"px)"),a.ui.$hero.find(".container").css("webkitTransform","translate(0, "+d+"px)")}})}}}()}(jQuery,this); \ No newline at end of file diff --git a/website/source/javascripts/app/homepage.js b/website/source/javascripts/app/homepage.js deleted file mode 100644 index 9af3e6d7c2..0000000000 --- a/website/source/javascripts/app/homepage.js +++ /dev/null @@ -1,49 +0,0 @@ -//homepage.js - -var APP = APP || {}; - -(function () { - APP.Homepage = (function () { - return { - - ui : null, - - init: function () { - var _this = this; - - //cache elements - this.ui = { - $doc: $(window), - $hero: $('#jumbotron'), - $collapse: $('.navbar-collapse') - } - - this.addEventListeners(); - - }, - - addEventListeners: function(){ - var _this = this; - - if(APP.Utils.isMobile) - return; - - _this.ui.$doc.scroll(function() { - - //if collapseable menu is open dont do parrallax. It looks wonky. Bootstrap conflict - if( _this.ui.$collapse.hasClass('in')) - return; - - var top = _this.ui.$doc.scrollTop(), - speedAdj = (top*0.8), - speedAdjOffset = speedAdj - top; - - _this.ui.$hero.css('webkitTransform', 'translate(0, '+ speedAdj +'px)'); - _this.ui.$hero.find('.container').css('webkitTransform', 'translate(0, '+ speedAdjOffset +'px)'); - }) - } - } - }()); - -}(jQuery, this)); - diff --git a/website/source/javascripts/app/util.js b/website/source/javascripts/app/util.js deleted file mode 100644 index f6acd8eb4a..0000000000 --- a/website/source/javascripts/app/util.js +++ /dev/null @@ -1,33 +0,0 @@ -// -// util.js -// -var APP = APP || {}; - -APP.Utils = (function () { - return { - //check for mobile user agents - isMobile : (function(){ - if( navigator.userAgent.match(/Android/i) - || navigator.userAgent.match(/webOS/i) - || navigator.userAgent.match(/iPhone/i) - //|| navigator.userAgent.match(/iPad/i) - || navigator.userAgent.match(/iPod/i) - || navigator.userAgent.match(/BlackBerry/i) - || navigator.userAgent.match(/Windows Phone/i) - ){ - return true; - } - else { - return false; - } - })(), - - runIfClassNamePresent: function(selector, initFunction) { - var elms = document.getElementsByClassName(selector); - if (elms.length > 0) { - initFunction(); - } - } - } - -}()); \ No newline at end of file diff --git a/website/source/javascripts/classy.js b/website/source/javascripts/classy.js deleted file mode 100644 index d001fc6bee..0000000000 --- a/website/source/javascripts/classy.js +++ /dev/null @@ -1,158 +0,0 @@ -/** - * Classy - classy classes for JavaScript - * - * :copyright: (c) 2011 by Armin Ronacher. - * :license: BSD. - */ - -;(function(undefined) { - var - CLASSY_VERSION = '1.4', - root = this, - old_class = root.Class, - disable_constructor = false; - - /* we check if $super is in use by a class if we can. But first we have to - check if the JavaScript interpreter supports that. This also matches - to false positives later, but that does not do any harm besides slightly - slowing calls down. */ - var probe_super = (function(){$super();}).toString().indexOf('$super') > 0; - function usesSuper(obj) { - return !probe_super || /\B\$super\b/.test(obj.toString()); - } - - /* helper function to set the attribute of something to a value or - removes it if the value is undefined. */ - function setOrUnset(obj, key, value) { - if (value === undefined) - delete obj[key]; - else - obj[key] = value; - } - - /* gets the own property of an object */ - function getOwnProperty(obj, name) { - return Object.prototype.hasOwnProperty.call(obj, name) - ? obj[name] : undefined; - } - - /* instanciate a class without calling the constructor */ - function cheapNew(cls) { - disable_constructor = true; - var rv = new cls; - disable_constructor = false; - return rv; - } - - /* the base class we export */ - var Class = function() {}; - - /* restore the global Class name and pass it to a function. This allows - different versions of the classy library to be used side by side and - in combination with other libraries. */ - Class.$noConflict = function() { - try { - setOrUnset(root, 'Class', old_class); - } - catch (e) { - // fix for IE that does not support delete on window - root.Class = old_class; - } - return Class; - }; - - /* what version of classy are we using? */ - Class.$classyVersion = CLASSY_VERSION; - - /* extend functionality */ - Class.$extend = function(properties) { - var super_prototype = this.prototype; - - /* disable constructors and instanciate prototype. Because the - prototype can't raise an exception when created, we are safe - without a try/finally here. */ - var prototype = cheapNew(this); - - /* copy all properties of the includes over if there are any */ - if (properties.__include__) - for (var i = 0, n = properties.__include__.length; i != n; ++i) { - var mixin = properties.__include__[i]; - for (var name in mixin) { - var value = getOwnProperty(mixin, name); - if (value !== undefined) - prototype[name] = mixin[name]; - } - } - - /* copy class vars from the superclass */ - properties.__classvars__ = properties.__classvars__ || {}; - if (prototype.__classvars__) - for (var key in prototype.__classvars__) - if (!properties.__classvars__[key]) { - var value = getOwnProperty(prototype.__classvars__, key); - properties.__classvars__[key] = value; - } - - /* copy all properties over to the new prototype */ - for (var name in properties) { - var value = getOwnProperty(properties, name); - if (name === '__include__' || - value === undefined) - continue; - - prototype[name] = typeof value === 'function' && usesSuper(value) ? - (function(meth, name) { - return function() { - var old_super = getOwnProperty(this, '$super'); - this.$super = super_prototype[name]; - try { - return meth.apply(this, arguments); - } - finally { - setOrUnset(this, '$super', old_super); - } - }; - })(value, name) : value - } - - /* dummy constructor */ - var rv = function() { - if (disable_constructor) - return; - var proper_this = root === this ? cheapNew(arguments.callee) : this; - if (proper_this.__init__) - proper_this.__init__.apply(proper_this, arguments); - proper_this.$class = rv; - return proper_this; - } - - /* copy all class vars over of any */ - for (var key in properties.__classvars__) { - var value = getOwnProperty(properties.__classvars__, key); - if (value !== undefined) - rv[key] = value; - } - - /* copy prototype and constructor over, reattach $extend and - return the class */ - rv.prototype = prototype; - rv.constructor = rv; - rv.$extend = Class.$extend; - rv.$withData = Class.$withData; - return rv; - }; - - /* instanciate with data functionality */ - Class.$withData = function(data) { - var rv = cheapNew(this); - for (var key in data) { - var value = getOwnProperty(data, key); - if (value !== undefined) - rv[key] = value; - } - return rv; - }; - - /* export the class */ - root.Class = Class; -})(); diff --git a/website/source/javascripts/lib/Base.js b/website/source/javascripts/lib/Base.js new file mode 100644 index 0000000000..504e2beea1 --- /dev/null +++ b/website/source/javascripts/lib/Base.js @@ -0,0 +1,145 @@ +/* + Based on Base.js 1.1a (c) 2006-2010, Dean Edwards + Updated to pass JSHint and converted into a module by Kenneth Powers + License: http://www.opensource.org/licenses/mit-license.php +*/ +/*global define:true module:true*/ +/*jshint eqeqeq:true*/ +(function (name, global, definition) { + if (typeof module !== 'undefined') { + module.exports = definition(); + } else if (typeof define !== 'undefined' && typeof define.amd === 'object') { + define(definition); + } else { + global[name] = definition(); + } +})('Base', this, function () { + // Base Object + var Base = function () {}; + + // Implementation + Base.extend = function (_instance, _static) { // subclass + var extend = Base.prototype.extend; + // build the prototype + Base._prototyping = true; + var proto = new this(); + extend.call(proto, _instance); + proto.base = function () { + // call this method from any other method to invoke that method's ancestor + }; + delete Base._prototyping; + // create the wrapper for the constructor function + //var constructor = proto.constructor.valueOf(); //-dean + var constructor = proto.constructor; + var klass = proto.constructor = function () { + if (!Base._prototyping) { + if (this._constructing || this.constructor === klass) { // instantiation + this._constructing = true; + constructor.apply(this, arguments); + delete this._constructing; + } else if (arguments[0] !== null) { // casting + return (arguments[0].extend || extend).call(arguments[0], proto); + } + } + }; + // build the class interface + klass.ancestor = this; + klass.extend = this.extend; + klass.forEach = this.forEach; + klass.implement = this.implement; + klass.prototype = proto; + klass.toString = this.toString; + klass.valueOf = function (type) { + return (type === 'object') ? klass : constructor.valueOf(); + }; + extend.call(klass, _static); + // class initialization + if (typeof klass.init === 'function') klass.init(); + return klass; + }; + + Base.prototype = { + extend: function (source, value) { + if (arguments.length > 1) { // extending with a name/value pair + var ancestor = this[source]; + if (ancestor && (typeof value === 'function') && // overriding a method? + // the valueOf() comparison is to avoid circular references + (!ancestor.valueOf || ancestor.valueOf() !== value.valueOf()) && /\bbase\b/.test(value)) { + // get the underlying method + var method = value.valueOf(); + // override + value = function () { + var previous = this.base || Base.prototype.base; + this.base = ancestor; + var returnValue = method.apply(this, arguments); + this.base = previous; + return returnValue; + }; + // point to the underlying method + value.valueOf = function (type) { + return (type === 'object') ? value : method; + }; + value.toString = Base.toString; + } + this[source] = value; + } else if (source) { // extending with an object literal + var extend = Base.prototype.extend; + // if this object has a customized extend method then use it + if (!Base._prototyping && typeof this !== 'function') { + extend = this.extend || extend; + } + var proto = { + toSource: null + }; + // do the "toString" and other methods manually + var hidden = ['constructor', 'toString', 'valueOf']; + // if we are prototyping then include the constructor + for (var i = Base._prototyping ? 0 : 1; i < hidden.length; i++) { + var h = hidden[i]; + if (source[h] !== proto[h]) + extend.call(this, h, source[h]); + } + // copy each of the source object's properties to this object + for (var key in source) { + if (!proto[key]) extend.call(this, key, source[key]); + } + } + return this; + } + }; + + // initialize + Base = Base.extend({ + constructor: function () { + this.extend(arguments[0]); + } + }, { + ancestor: Object, + version: '1.1', + forEach: function (object, block, context) { + for (var key in object) { + if (this.prototype[key] === undefined) { + block.call(context, object[key], key, object); + } + } + }, + implement: function () { + for (var i = 0; i < arguments.length; i++) { + if (typeof arguments[i] === 'function') { + // if it's a function, call it + arguments[i](this.prototype); + } else { + // add the interface using the extend method + this.prototype.extend(arguments[i]); + } + } + return this; + }, + toString: function () { + return String(this.valueOf()); + } + }); + + // Return Base implementation + return Base; +}); diff --git a/website/source/javascripts/lib/String.substitute.js b/website/source/javascripts/lib/String.substitute.js new file mode 100644 index 0000000000..da2b52a387 --- /dev/null +++ b/website/source/javascripts/lib/String.substitute.js @@ -0,0 +1,14 @@ +(function(String){ + +if (String.prototype.substitute) { + return; +} + +String.prototype.substitute = function(object, regexp){ + return String(this).replace(regexp || (/\\?\{([^{}]+)\}/g), function(match, name){ + if (match.charAt(0) == '\\') return match.slice(1); + return (object[name] !== null) ? object[name] : ''; + }); +}; + +})(String); diff --git a/website/source/javascripts/lib/Vector.js b/website/source/javascripts/lib/Vector.js new file mode 100644 index 0000000000..71002984d7 --- /dev/null +++ b/website/source/javascripts/lib/Vector.js @@ -0,0 +1,111 @@ +(function(global){ 'use strict'; + +var Vector = function(x, y){ + this.x = x || 0; + this.y = y || 0; +}; + +Vector.prototype = { + + clone: function(){ + return new Vector(this.x, this.y); + }, + + add: function(vec){ + this.x += vec.x; + this.y += vec.y; + return this; + }, + + sub: function(vec){ + this.x -= vec.x; + this.y -= vec.y; + return this; + }, + + subVal: function(val){ + this.x -= val; + this.y -= val; + return this; + }, + + mult: function(mul){ + this.x *= mul; + this.y *= mul; + return this; + }, + + div: function(div){ + if (div === 0) { + return this; + } + this.x /= div; + this.y /= div; + return this; + }, + + mag: function(){ + return Math.sqrt( + this.x * this.x + + this.y * this.y + ); + }, + + limit: function(max){ + if (this.mag() > max) { + this.normalize(); + this.mult(max); + } + return this; + }, + + normalize: function(){ + var mag = this.mag(); + if (mag === 0) { + return this; + } + this.div(mag); + return this; + }, + + heading: function(){ + return Math.atan2(this.y, this.x); + }, + + set: function(vec){ + this.x = vec.x; + this.y = vec.y; + return this; + } + +}; + +Vector.add = function(vec1, vec2){ + return vec1.clone().add(vec2.clone()); +}; + +Vector.sub = function(vec1, vec2){ + return vec1.clone().sub(vec2.clone()); +}; + +Vector.mult = function(vec, mult){ + return vec.clone().mult(mult); +}; + +Vector.div = function(vec, div){ + return vec.clone().div(div); +}; + + // Ripped from processing +Vector.random2D = function(){ + var angle = Math.random(0, 1) * Math.PI * 2; + return new Vector(Math.cos(angle), Math.sin(angle)); +}; + +Vector.coerce = function(obj){ + return new Vector(obj.x, obj.y); +}; + +global.Vector = Vector; + +})(this); diff --git a/website/source/javascripts/lib/dbg.js b/website/source/javascripts/lib/dbg.js new file mode 100644 index 0000000000..6df4f37625 --- /dev/null +++ b/website/source/javascripts/lib/dbg.js @@ -0,0 +1,60 @@ +/* + * + * name: dbg + * + * description: A bad ass little console utility, check the README for deets + * + * license: MIT-style license + * + * author: Amadeus Demarzi + * + * provides: window.dbg + * + */ + +(function(){ + + var global = this, + + // Get the real console or set to null for easy boolean checks + realConsole = global.console || null, + + // Backup / Disabled Lambda + fn = function(){}, + + // Supported console methods + methodNames = ['log', 'error', 'warn', 'info', 'count', 'debug', 'profileEnd', 'trace', 'dir', 'dirxml', 'assert', 'time', 'profile', 'timeEnd', 'group', 'groupEnd'], + + // Disabled Console + disabledConsole = { + + // Enables dbg, if it exists, otherwise it just provides disabled + enable: function(quiet){ + global.dbg = realConsole ? realConsole : disabledConsole; + }, + + // Disable dbg + disable: function(){ + global.dbg = disabledConsole; + } + + }, name, i; + + // Setup disabled console and provide fallbacks on the real console + for (i = 0; i < methodNames.length;i++){ + name = methodNames[i]; + disabledConsole[name] = fn; + if (realConsole && !realConsole[name]) + realConsole[name] = fn; + } + + // Add enable/disable methods + if (realConsole) { + realConsole.disable = disabledConsole.disable; + realConsole.enable = disabledConsole.enable; + } + + // Enable dbg + disabledConsole.enable(); + +}).call(this); diff --git a/website/source/layouts/_footer.erb b/website/source/layouts/_footer.erb index 75290181da..71280c244d 100644 --- a/website/source/layouts/_footer.erb +++ b/website/source/layouts/_footer.erb @@ -19,14 +19,5 @@ - - - - - - - diff --git a/website/source/stylesheets/_variables.less b/website/source/stylesheets/_variables.less index 43a47f42e7..8f580124b5 100755 --- a/website/source/stylesheets/_variables.less +++ b/website/source/stylesheets/_variables.less @@ -8,7 +8,7 @@ @jumbotron-height: 804px; @header-height: 90px; -@jumbotron-total-height: 804px; //jumbo+header +@jumbotron-total-height: 700px; //jumbo+header @jumbotron-color: #fff; @btn-border-radius: 4px; @el-border-radius: 6px; From c85b68f978ce2312007e033294869c08c2e52349 Mon Sep 17 00:00:00 2001 From: Amadeus Demarzi Date: Wed, 23 Jul 2014 20:35:57 -0700 Subject: [PATCH 03/40] Got the base scene functioning --- website/source/index.html.erb | 20 +- website/source/javascripts/app/Circle.js | 627 ++++++++++++++++++ .../javascripts/app/Engine.Particle.Fixed.js | 77 +++ .../source/javascripts/app/Engine.Particle.js | 176 +++++ .../source/javascripts/app/Engine.Point.js | 88 +++ .../source/javascripts/app/Engine.Polygon.js | 85 +++ website/source/javascripts/app/Engine.js | 227 +++++++ website/source/javascripts/app/Init.js | 36 + website/source/javascripts/app/Puller.js | 136 ++++ website/source/layouts/_footer.erb | 14 + website/source/layouts/_header.erb | 2 +- website/source/stylesheets/_jumbotron.less | 174 +++-- website/source/stylesheets/main.css | 141 ++-- 13 files changed, 1702 insertions(+), 101 deletions(-) create mode 100644 website/source/javascripts/app/Circle.js create mode 100644 website/source/javascripts/app/Engine.Particle.Fixed.js create mode 100644 website/source/javascripts/app/Engine.Particle.js create mode 100644 website/source/javascripts/app/Engine.Point.js create mode 100644 website/source/javascripts/app/Engine.Polygon.js create mode 100644 website/source/javascripts/app/Engine.js create mode 100644 website/source/javascripts/app/Init.js create mode 100644 website/source/javascripts/app/Puller.js diff --git a/website/source/index.html.erb b/website/source/index.html.erb index a796b8a42c..eb04d6a178 100644 --- a/website/source/index.html.erb +++ b/website/source/index.html.erb @@ -1,20 +1,16 @@
-
-
-

- Service discovery and configuration made easy. - Distributed, highly available, and - datacenter-aware. -

+
+
+ - -
-
+
diff --git a/website/source/javascripts/app/Circle.js b/website/source/javascripts/app/Circle.js new file mode 100644 index 0000000000..bd61b9c1a3 --- /dev/null +++ b/website/source/javascripts/app/Circle.js @@ -0,0 +1,627 @@ +// jshint unused:false +var Circle = { + "Points": [ + { + "id": "point-0", + "x": 329.40000000000003, + "y": 282.96000000000004 + }, + { + "id": "point-1", + "x": 355.26, + "y": 224.82 + }, + { + "id": "point-2", + "x": 282.66, + "y": 330.3 + }, + { + "id": "point-5", + "x": 279.12, + "y": 224.10000000000002 + }, + { + "id": "point-8", + "x": 217.26000000000002, + "y": 246.06 + }, + { + "id": "point-11", + "x": 190.01999999999998, + "y": 293.52 + }, + { + "id": "point-14", + "x": 209.21999999999997, + "y": 360.9 + }, + { + "id": "point-17", + "x": 127.08000000000001, + "y": 257.88 + }, + { + "id": "point-20", + "x": 124.55999999999999, + "y": 354.12 + }, + { + "id": "point-26", + "x": 48.6, + "y": 303.06 + }, + { + "id": "point-28", + "x": 353.1, + "y": 128.46 + }, + { + "id": "point-32", + "x": 237.48000000000002, + "y": 188.51999999999998 + }, + { + "id": "point-38", + "x": 172.68, + "y": 183 + }, + { + "id": "point-41", + "x": 130.68, + "y": 189 + }, + { + "id": "point-47", + "x": 61.2, + "y": 198.96000000000004 + }, + { + "id": "point-53", + "x": 8.34, + "y": 240.48000000000002 + }, + { + "id": "point-55", + "x": 236.88000000000002, + "y": 107.28000000000002 + }, + { + "id": "point-59", + "x": 165.23999999999998, + "y": 97.8 + }, + { + "id": "point-65", + "x": 79.91999999999999, + "y": 121.14000000000001 + }, + { + "id": "point-74", + "x": 0, + "y": 160.44 + }, + { + "id": "point-78", + "x": 305.7, + "y": 50.88 + }, + { + "id": "point-79", + "x": 251.82, + "y": 14.879999999999999 + }, + { + "id": "point-83", + "x": 197.88, + "y": -0.12000000000000001 + }, + { + "id": "point-89", + "x": 132.6, + "y": 6.06 + }, + { + "id": "point-95", + "x": 44.64000000000001, + "y": 60.96 + }, + { + "id": "point-98", + "x": 18.060000000000002, + "y": 99.60000000000001 + } + ], + "Polygons": [ + { + "id": "poly-0", + "color": { + "h": 260.28985507246375, + "s": 92.82511210762333, + "l": 56.27450980392157, + "a": 1 + }, + "points": [ + "point-0", + "point-1", + "point-2" + ] + }, + { + "id": "poly-1", + "color": { + "h": 263.27102803738313, + "s": 100, + "l": 58.03921568627452, + "a": 1 + }, + "points": [ + "point-2", + "point-1", + "point-5" + ] + }, + { + "id": "poly-2", + "color": { + "h": 263.4905660377359, + "s": 86.88524590163934, + "l": 52.156862745098046, + "a": 1 + }, + "points": [ + "point-2", + "point-5", + "point-8" + ] + }, + { + "id": "poly-3", + "color": { + "h": 263.3653846153846, + "s": 88.88888888888889, + "l": 54.11764705882353, + "a": 1 + }, + "points": [ + "point-2", + "point-8", + "point-11" + ] + }, + { + "id": "poly-4", + "color": { + "h": 264.82758620689657, + "s": 79.6078431372549, + "l": 50, + "a": 1 + }, + "points": [ + "point-2", + "point-11", + "point-14" + ] + }, + { + "id": "poly-5", + "color": { + "h": 267.192118226601, + "s": 100, + "l": 39.80392156862745, + "a": 1 + }, + "points": [ + "point-11", + "point-8", + "point-17" + ] + }, + { + "id": "poly-6", + "color": { + "h": 266.8421052631579, + "s": 100, + "l": 37.254901960784316, + "a": 1 + }, + "points": [ + "point-11", + "point-17", + "point-20" + ] + }, + { + "id": "poly-7", + "color": { + "h": 267.029702970297, + "s": 93.5185185185185, + "l": 42.35294117647059, + "a": 1 + }, + "points": [ + "point-11", + "point-20", + "point-14" + ] + }, + { + "id": "poly-8", + "color": { + "h": 262.54777070063693, + "s": 100, + "l": 30.784313725490197, + "a": 1 + }, + "points": [ + "point-20", + "point-17", + "point-26" + ] + }, + { + "id": "poly-9", + "color": { + "h": 266.1764705882353, + "s": 87.17948717948718, + "l": 45.88235294117647, + "a": 1 + }, + "points": [ + "point-1", + "point-28", + "point-5" + ] + }, + { + "id": "poly-10", + "color": { + "h": 267.192118226601, + "s": 100, + "l": 39.80392156862745, + "a": 1 + }, + "points": [ + "point-5", + "point-28", + "point-32" + ] + }, + { + "id": "poly-11", + "color": { + "h": 267.029702970297, + "s": 93.5185185185185, + "l": 42.35294117647059, + "a": 1 + }, + "points": [ + "point-5", + "point-32", + "point-8" + ] + }, + { + "id": "poly-12", + "color": { + "h": 264.40677966101697, + "s": 100, + "l": 34.705882352941174, + "a": 1 + }, + "points": [ + "point-8", + "point-32", + "point-38" + ] + }, + { + "id": "poly-13", + "color": { + "h": 260.8, + "s": 100, + "l": 29.411764705882355, + "a": 1 + }, + "points": [ + "point-8", + "point-38", + "point-41" + ] + }, + { + "id": "poly-14", + "color": { + "h": 262.54777070063693, + "s": 100, + "l": 30.784313725490197, + "a": 1 + }, + "points": [ + "point-8", + "point-41", + "point-17" + ] + }, + { + "id": "poly-15", + "color": { + "h": 256.07142857142856, + "s": 88.88888888888889, + "l": 24.705882352941178, + "a": 1 + }, + "points": [ + "point-17", + "point-41", + "point-47" + ] + }, + { + "id": "poly-16", + "color": { + "h": 252.94117647058826, + "s": 87.93103448275862, + "l": 22.745098039215687, + "a": 1 + }, + "points": [ + "point-17", + "point-47", + "point-26" + ] + }, + { + "id": "poly-17", + "color": { + "h": 244.56521739130434, + "s": 100, + "l": 18.03921568627451, + "a": 1 + }, + "points": [ + "point-26", + "point-47", + "point-53" + ] + }, + { + "id": "poly-18", + "color": { + "h": 249.89010989010993, + "s": 77.77777777777779, + "l": 22.941176470588236, + "a": 1 + }, + "points": [ + "point-28", + "point-55", + "point-32" + ] + }, + { + "id": "poly-19", + "color": { + "h": 247.59493670886073, + "s": 76.69902912621359, + "l": 20.19607843137255, + "a": 1 + }, + "points": [ + "point-32", + "point-55", + "point-59" + ] + }, + { + "id": "poly-20", + "color": { + "h": 250.2, + "s": 78.12500000000001, + "l": 25.098039215686274, + "a": 1 + }, + "points": [ + "point-32", + "point-59", + "point-38" + ] + }, + { + "id": "poly-21", + "color": { + "h": 250.12048192771087, + "s": 79.04761904761905, + "l": 20.58823529411765, + "a": 1 + }, + "points": [ + "point-38", + "point-59", + "point-65" + ] + }, + { + "id": "poly-22", + "color": { + "h": 250.00000000000003, + "s": 77.99999999999999, + "l": 19.607843137254903, + "a": 1 + }, + "points": [ + "point-38", + "point-65", + "point-41" + ] + }, + { + "id": "poly-23", + "color": { + "h": 249.79591836734693, + "s": 77.77777777777777, + "l": 24.705882352941178, + "a": 1 + }, + "points": [ + "point-41", + "point-65", + "point-47" + ] + }, + { + "id": "poly-24", + "color": { + "h": 250.54054054054055, + "s": 78.72340425531914, + "l": 18.43137254901961, + "a": 1 + }, + "points": [ + "point-47", + "point-65", + "point-74" + ] + }, + { + "id": "poly-25", + "color": { + "h": 250.74626865671638, + "s": 78.82352941176471, + "l": 16.666666666666664, + "a": 1 + }, + "points": [ + "point-47", + "point-74", + "point-53" + ] + }, + { + "id": "poly-26", + "color": { + "h": 247.01298701298703, + "s": 90.58823529411765, + "l": 16.666666666666664, + "a": 1 + }, + "points": [ + "point-78", + "point-79", + "point-55" + ] + }, + { + "id": "poly-27", + "color": { + "h": 250.1538461538462, + "s": 91.54929577464787, + "l": 13.92156862745098, + "a": 1 + }, + "points": [ + "point-55", + "point-79", + "point-83" + ] + }, + { + "id": "poly-28", + "color": { + "h": 240, + "s": 77.77777777777777, + "l": 12.352941176470589, + "a": 1 + }, + "points": [ + "point-55", + "point-83", + "point-59" + ] + }, + { + "id": "poly-29", + "color": { + "h": 247.24137931034483, + "s": 90.62500000000001, + "l": 12.549019607843137, + "a": 1 + }, + "points": [ + "point-59", + "point-83", + "point-89" + ] + }, + { + "id": "poly-30", + "color": { + "h": 242.53521126760566, + "s": 87.65432098765433, + "l": 15.88235294117647, + "a": 1 + }, + "points": [ + "point-59", + "point-89", + "point-65" + ] + }, + { + "id": "poly-31", + "color": { + "h": 247.63636363636363, + "s": 90.16393442622952, + "l": 11.960784313725489, + "a": 1 + }, + "points": [ + "point-65", + "point-89", + "point-95" + ] + }, + { + "id": "poly-32", + "color": { + "h": 246.25, + "s": 88.88888888888887, + "l": 10.588235294117649, + "a": 1 + }, + "points": [ + "point-65", + "point-95", + "point-98" + ] + }, + { + "id": "poly-33", + "color": { + "h": 240, + "s": 87.50000000000001, + "l": 9.411764705882353, + "a": 1 + }, + "points": [ + "point-98", + "point-74", + "point-65" + ] + }, + { + "id": "poly-34", + "color": { + "h": 250.2, + "s": 78.12500000000001, + "l": 25.098039215686274, + "a": 1 + }, + "points": [ + "point-28", + "point-78", + "point-55" + ] + } + ] +}; diff --git a/website/source/javascripts/app/Engine.Particle.Fixed.js b/website/source/javascripts/app/Engine.Particle.Fixed.js new file mode 100644 index 0000000000..164b430572 --- /dev/null +++ b/website/source/javascripts/app/Engine.Particle.Fixed.js @@ -0,0 +1,77 @@ +(function( + Particle, + Engine, + Vector +){ + +Particle.Fixed = function(width, height){ + var targetX, targetY; + + this.radius = Engine.getRandomFloat(0.1, 1); + // this.fillA = 'rgba(136,67,237,' + Engine.getRandomFloat(0.4, 0.5) + ')'; + // this.fillB = 'rgba(136,67,237,' + Engine.getRandomFloat(0.51, 0.6) + ')'; + this.fillA = '#3a1066'; + this.fillB = '#561799'; + this.frameMax = Engine.getRandomInt(4, 10); + + this.max = { + x: width + this.maxRadius, + y: height + this.maxRadius + }; + + this.min = { + x: 0 - this.maxRadius, + y: 0 - this.maxRadius + }; + + targetX = Engine.getRandomInt(0 + this.radius, width + this.radius); + targetY = Engine.getRandomInt(0 + this.radius, height + this.radius); + + this.pos = new Vector(targetX, targetY); +}; + +Engine.Particle.Fixed.prototype = { + + radius: 1, + + pos: { + x: 0, + y: 0 + }, + + frame: 0, + showA: false, + + update: function(engine){ + this.frame++; + if (this.frame > this.frameMax) { + this.frame = 0; + this.showA = !this.showA; + } + return this; + }, + + draw: function(ctx, scale){ + // Draw a circle - far less performant + ctx.beginPath(); + ctx.arc( + this.pos.x * scale, + this.pos.y * scale, + this.radius * scale, + 0, + Math.PI * 2, + false + ); + if (this.showA) { + ctx.fillStyle = this.fillA; + } else { + ctx.fillStyle = this.fillB; + } + ctx.fill(); + + return this; + } + +}; + +})(window.Engine.Particle, window.Engine, window.Vector); diff --git a/website/source/javascripts/app/Engine.Particle.js b/website/source/javascripts/app/Engine.Particle.js new file mode 100644 index 0000000000..549f8b4ec3 --- /dev/null +++ b/website/source/javascripts/app/Engine.Particle.js @@ -0,0 +1,176 @@ +(function( + Engine, + Vector +){ + +Engine.Particle = function(width, height){ + var side, targetX, targetY; + this.accel = Vector.coerce(this.accel); + this.vel = Vector.coerce(this.vel); + this.pos = new Vector( + width / 2, + height / 2 + ); + + this.maxRadius = Engine.getRandomFloat(0.1, 2.5); + this.maxSpeed = Engine.getRandomFloat(0.01, 1000); + + this.max = { + x: width + this.maxRadius, + y: height + this.maxRadius + }; + + this.min = { + x: 0 - this.maxRadius, + y: 0 - this.maxRadius + }; + + // Pick a random target + side = Engine.getRandomInt(0, 3); + if (side === 0 || side === 2) { + targetY = (side === 0) ? (0 - this.maxRadius) : (height + this.maxRadius); + targetX = Engine.getRandomInt(0 - this.maxRadius, width + this.maxRadius); + } else { + targetY = Engine.getRandomInt(0 - this.maxRadius, height + this.maxRadius); + targetX = (side === 3) ? (0 - this.maxRadius) : (width + this.maxRadius); + } + + this.target = new Vector(targetX, targetY); + this.maxDistance = this.distanceTo(this.target); + + // this.fillA = 'rgba(136,67,237,' + Engine.getRandomFloat(0.7, 0.8) + ')'; + // this.fillB = 'rgba(136,67,237,1)'; + // this.fillA = '#651bb3'; + // this.fillB = '#9027ff'; + this.fillA = '#8750c2'; + this.fillB = '#b976ff'; + // b976ff + this.frameMax = Engine.getRandomInt(1, 5); +}; + +Engine.Particle.prototype = { + + radius: 1, + + frame: 0, + showA: false, + + accel: { + x: 0, + y: 0 + }, + + vel: { + x: 0, + y: 0 + }, + + pos: { + x: 0, + y: 0 + }, + + opacity: 1, + + maxSpeed: 1500, + maxForce: 1500, + + update: function(engine){ + var distancePercent; + + this.accel.mult(0); + this.seek(); + + this.vel + .add(this.accel) + .limit(this.maxSpeed); + + this.pos.add(Vector.mult(this.vel, engine.tick)); + + if ( + this.pos.x < this.min.x || + this.pos.x > this.max.x || + this.pos.y < this.min.y || + this.pos.y > this.max.y + ) { + this.kill(engine); + } + + distancePercent = (this.maxDistance - this.distanceTo(this.target)) / this.maxDistance; + this.radius = Math.max(0.1, this.maxRadius * distancePercent); + + this.frame++; + if (this.frame > this.frameMax) { + this.frame = 0; + this.showA = !this.showA; + } + + return this; + }, + + seek: function(){ + var desired, steer; + + desired = Vector.sub(this.target, this.pos) + .normalize() + .mult(this.maxSpeed); + + steer = Vector + .sub(desired, this.vel) + .limit(this.maxForce); + + this.applyForce(steer); + }, + + draw: function(ctx, scale){ + if (this.radius < 0.25) { + return; + } + + if (this.showA) { + ctx.fillStyle = this.fillA; + } else { + ctx.fillStyle = this.fillB; + } + + // Draw a square - very performant + ctx.fillRect( + this.pos.x * scale, + this.pos.y * scale, + this.radius * scale, + this.radius * scale + ); + + // Draw a circle - far less performant + // ctx.beginPath(); + // ctx.arc( + // this.pos.x * scale, + // this.pos.y * scale, + // this.radius * scale, + // 0, + // Math.PI * 2, + // false + // ); + // ctx.fill(); + + return this; + }, + + applyForce: function(force){ + this.accel.add(force); + return this; + }, + + kill: function(engine){ + engine._deferred.push(this); + return this; + }, + + distanceTo: function(target) { + var xd = this.pos.x - target.x; + var yd = this.pos.y - target.y; + return Math.sqrt(xd * xd + yd * yd ); + } +}; + +})(window.Engine, window.Vector); diff --git a/website/source/javascripts/app/Engine.Point.js b/website/source/javascripts/app/Engine.Point.js new file mode 100644 index 0000000000..66618fc8b0 --- /dev/null +++ b/website/source/javascripts/app/Engine.Point.js @@ -0,0 +1,88 @@ +(function( + Engine, + Vector +){ + +Engine.Point = function(id, x, y, width, height){ + this.id = id; + this.pos = new Vector(x, y); + this.target = this.pos.clone(); + this.pos.x = width / 2; + this.pos.y = height / 2; + this.accel = Vector.coerce(this.accel); + this.vel = Vector.coerce(this.vel); + + this.pos.add({ + x: (Engine.getRandomFloat(0, 6) - 3), + y: (Engine.getRandomFloat(0, 6) - 3) + }); + + // Physics randomness + // this.stiffness = Engine.getRandomFloat(2, 5); + // this.stiffness = Engine.getRandomFloat(0.4, 0.8); + this.stiffness = Engine.getRandomFloat(3, 6); + this.friction = Engine.getRandomFloat(0.15, 0.3); +}; + +Engine.Point.prototype = { + + radius: 1, + + stiffness : 0.5, + // friction : 0.00001, + friction : 0.01, + threshold : 0.03, + + pos: { + x: 0, + y: 0 + }, + + accel: { + x: 0, + y: 0 + }, + + vel : { + x: 0, + y: 0 + }, + + target: { + x: 0, + y: 0 + }, + + update: function(engine){ + var newAccel; + + newAccel = Vector.sub(this.target, this.pos) + .mult(this.stiffness) + .sub(Vector.mult(this.vel, this.friction)); + + this.accel.set(newAccel); + + this.vel.add(this.accel); + + this.pos.add( + Vector.mult(this.vel, engine.tick) + ); + }, + + draw: function(ctx, scale){ + ctx.beginPath(); + ctx.arc( + this.pos.x * scale, + this.pos.y * scale, + this.radius * scale, + 0, + Math.PI * 2, + false + ); + ctx.fillStyle = '#ffffff'; + ctx.fill(); + } + +}; + +})(window.Engine, window.Vector); diff --git a/website/source/javascripts/app/Engine.Polygon.js b/website/source/javascripts/app/Engine.Polygon.js new file mode 100644 index 0000000000..819d722ec5 --- /dev/null +++ b/website/source/javascripts/app/Engine.Polygon.js @@ -0,0 +1,85 @@ +(function( + Engine, + Vector +){ + +Engine.Polygon = function(a, b, c, color){ + this.a = a; + this.b = b; + this.c = c; + + this.color = color; + this.maxS = this.color.s; + this.maxL = this.color.l; + + // this.color.s = 0; + this.color.l = 0; + + this.start = Date.now() / 1000; + + this.fillStyle = this.hslaTemplate.substitute(this.color); + + // this.up = !!Engine.getRandomInt(0,1); + // this.hueShiftSpeed = 15; + // this.toColor = { + // a: 1 + // }; +}; + +Engine.Polygon.prototype = { + + rgbaTemplate: 'rgba({r},{g},{b},{a})', + hslaTemplate: 'hsla({h},{s}%,{l}%,{a})', + + hueShiftSpeed: 20, + duration: 3, + delay: 2.5, + + // Determine color fill? + update: function(engine){ + var delta; + + delta = engine.now - this.start; + + if ( + delta > this.delay && + delta < this.delay + this.duration + 1 && + this.color.l < this.maxL + ) { + // this.color.s = this.maxS * delta / this.duration; + this.color.l = this.maxL * (delta - this.delay) / this.duration; + + if (this.color.l > this.maxL) { + // this.color.s = this.maxS; + this.color.l = this.maxL; + } + + this.fillStyle = this.hslaTemplate.substitute(this.color); + } + }, + + draw: function(ctx, scale){ + ctx.beginPath(); + ctx.moveTo( + this.a.pos.x * scale, + this.a.pos.y * scale + ); + ctx.lineTo( + this.b.pos.x * scale, + this.b.pos.y * scale + ); + ctx.lineTo( + this.c.pos.x * scale, + this.c.pos.y * scale + ); + ctx.closePath(); + ctx.fillStyle = this.fillStyle; + ctx.lineWidth = 0.25 * scale; + ctx.strokeStyle = this.fillStyle; + ctx.fill(); + ctx.stroke(); + } + +}; + +})(window.Engine, window.Vector); diff --git a/website/source/javascripts/app/Engine.js b/website/source/javascripts/app/Engine.js new file mode 100644 index 0000000000..8aefd7de3a --- /dev/null +++ b/website/source/javascripts/app/Engine.js @@ -0,0 +1,227 @@ +/* jshint unused: false */ +/* global console */ +(function(Base, Vector, Circle){ + +var sqrt, pow, Engine; + +if (!window.requestAnimationFrame) { + window.requestAnimationFrame = (function(){ + return window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + function( callback ){ + window.setTimeout(callback, 1000 / 60); + }; + })(); +} + +sqrt = Math.sqrt; +pow = Math.pow; + +Engine = Base.extend({ + + scale: window.devicePixelRatio || 1, + // scale:1, + + particles : [], + _deferred : [], + + points : [], + polygons : [], + + speed: 1, + accel: 0.08, + + constructor: function(canvas, bg){ + var image, el; + if (typeof canvas === 'string') { + this.canvas = document.getElementById(canvas); + } else { + this.canvas = canvas; + } + + if (!this.canvas.getContext) { + return; + } + + this.context = this.canvas.getContext('2d'); + + this.resize = this.resize.bind(this); + this.resize(); + window.addEventListener('resize', this.resize, false); + + this.setupStarfield(bg); + this.setupTessellation(); + + this.last = Date.now() / 1000; + + this.start = this.last; + + this.render = this.render.bind(this); + this.render(); + + this.canvas.style.opacity = 1; + /* + image = document.getElementById(bg); + image.style.webkitTransform = 'translate3d(0,0,0) scale(1)'; + image.style.opacity = 1; + */ + + el = document.body; + + setTimeout(function() { + el.className += ' state-one'; + setTimeout(function() { + el.className += ' state-two'; + setTimeout(function() { + el.className += ' state-three'; + setTimeout(function() { + el.className += ' state-four'; + }, 550); + }, 200); + }, 200); + }, 4000); + }, + + setupStarfield: function(){ + this.particles = []; + this.generateParticles(50, true); + this.generateParticles(200); + }, + + setupTessellation: function(canvas){ + var row, col, rows, cols, rowMod, colMod, i, p, ref, point, poly; + + ref = {}; + for (i = 0; i < Circle.Points.length; i++) { + point = new Engine.Point( + Circle.Points[i].id, + Circle.Points[i].x + (this.width / 2 - 180), + Circle.Points[i].y + (this.height / 2 - 180), + this.width, + this.height + ); + ref[point.id] = point; + this.points.push(point); + } + + for (i = 0; i < Circle.Polygons.length; i++) { + poly = Circle.Polygons[i]; + this.polygons.push(new Engine.Polygon( + ref[poly.points[0]], + ref[poly.points[1]], + ref[poly.points[2]], + poly.color + )); + } + }, + + render: function(){ + var tick; + + this.context.clearRect( + 0, + 0, + this.width * this.scale, + this.height * this.scale + ); + + this.now = Date.now() / 1000; + + // if (this.slow) { + // this.speed = Math.max(0.1, this.speed - this.accel); + // } else { + // this.speed = Math.min(1, this.speed + this.accel); + // } + + tick = Math.min(this.now - this.last, 0.017); + this.tick = this.speed * tick; + + this.renderStarfield(this.now); + this.tick = tick; + + if (this.now - this.start > 3) { + // this.slow = true; + this.renderTessellation(this.now); + } + + this.last = this.now; + + window.requestAnimationFrame(this.render); + }, + + renderTessellation: function(){ + var scale = this.scale, + p; + + for (p = 0; p < this.points.length; p++) { + this.points[p].update(this); + // this.points[p].draw(this.context, scale); + } + + for (p = 0; p < this.polygons.length; p++) { + this.polygons[p].update(this); + this.polygons[p].draw(this.context, scale); + } + }, + + generateParticles: function(num, fixed){ + var p; + + for (p = 0; p < num; p++) { + if (fixed) { + this.particles.push(new Engine.Particle.Fixed(this.width, this.height)); + } else { + this.particles.push(new Engine.Particle(this.width, this.height)); + } + } + }, + + resize: function(){ + this.width = window.innerWidth; + this.height = 700; + + this.canvas.width = this.width * this.scale; + this.canvas.height = this.height * this.scale; + + window.scrollTo(0, 0); + }, + + renderStarfield: function(){ + var scale = this.scale, p, index; + + // Update all particles... may need to be optimized + for (p = 0; p < this.particles.length; p++) { + this.particles[p] + .update(this) + .draw(this.context, scale); + } + + // Remove destroyed entities + for (p = 0; p < this._deferred.length; p++) { + index = this.particles.indexOf(this._deferred.pop()); + if (index >= 0) { + this.particles.splice(index, 1); + } + } + + this.generateParticles(600 * this.tick >> 0); + } + +}); + +Engine.map = function(val, istart, istop, ostart, ostop) { + return ostart + (ostop - ostart) * ((val - istart) / (istop - istart)); +}; + +Engine.getRandomFloat = function(min, max) { + return Math.random() * (max - min) + min; +}; + +Engine.getRandomInt = function(min, max) { + return Math.floor(Math.random() * (max - min + 1) + min); +}; + +window.Engine = Engine; + +})(window.Base, window.Vector, window.Circle); diff --git a/website/source/javascripts/app/Init.js b/website/source/javascripts/app/Init.js new file mode 100644 index 0000000000..89b455fb0b --- /dev/null +++ b/website/source/javascripts/app/Init.js @@ -0,0 +1,36 @@ +(function( + Engine +){ + +var Init = { + + start: function(){ + var id = document.body.id.toLowerCase(); + + if (this.Pages[id]) { + this.Pages[id](); + } + }, + + Pages: { + 'page-home': function(){ + var jumbotron = document.getElementById('jumbotron'), + canvas; + + if (!jumbotron) { + return; + } + + canvas = document.createElement('canvas'); + canvas.className = 'terraform-canvas'; + + jumbotron.appendChild(canvas); + window.engine = new Engine(canvas, 'image'); + } + } + +}; + +Init.start(); + +})(window.Engine); diff --git a/website/source/javascripts/app/Puller.js b/website/source/javascripts/app/Puller.js new file mode 100644 index 0000000000..2df85c7338 --- /dev/null +++ b/website/source/javascripts/app/Puller.js @@ -0,0 +1,136 @@ +(function( + Engine, + Vector +){ + +var Puller = function(x, y){ + this.pos.x = x; + this.pos.y = y; + this.pos = Vector.coerce(this.pos); + this.home = this.pos.clone(); + this.accel = Vector.coerce(this.accel); + this.vel = Vector.coerce(this.vel); +}; + +Puller.prototype = { + + fillStyle: '#ffffff', + radius: 5, + + maxSpeed: 160, + maxForce: 50, + + pos: { + x: 0, + y: 0 + }, + + accel: { + x: 0, + y: 0 + }, + + vel: { + x: 0, + y: 0 + }, + + aRad: 200, + + safety: 0.25, + + update: function(engine){ + var distanceToMouse = this.distanceTo(engine.mouse), + toHome, mag, safety; + // distanceToHome = this.distanceTo(this.home); + + this.accel.mult(0); + + if (distanceToMouse < this.aRad) { + this.toChase(engine.mouse); + } + + this.toChase(this.home, this.maxForce / 2); + + this.vel.add(this.accel); + this.pos.add( + Vector.mult(this.vel, engine.tick) + ); + + toHome = Vector.sub(this.home, this.pos); + mag = toHome.mag(); + safety = this.aRad * (this.safety * 3); + if (mag > this.aRad - safety) { + toHome.normalize(); + toHome.mult(this.aRad - safety); + this.pos = Vector.sub(this.home, toHome); + } + }, + + toChase: function(target, maxForce){ + var desired, steer, distance, mult, safety; + + maxForce = maxForce || this.maxForce; + + target = Vector.coerce(target); + desired = Vector.sub(target, this.pos); + distance = desired.mag(); + desired.normalize(); + + safety = this.aRad * this.safety; + + if (distance < safety) { + mult = Engine.map(distance, 0, safety, 0, this.maxSpeed); + } else if (distance > this.aRad - safety){ + mult = Engine.map(this.aRad - distance, 0, safety, 0, this.maxSpeed); + } else { + mult = this.maxSpeed; + } + + desired.mult(mult); + + steer = Vector.sub(desired, this.vel); + steer.limit(maxForce); + this.accel.add(steer); + }, + + draw: function(ctx, scale){ + // ctx.beginPath(); + // ctx.arc( + // this.home.x * scale, + // this.home.y * scale, + // this.aRad * scale, + // 0, + // Math.PI * 2, + // false + // ); + // ctx.fillStyle = 'rgba(255,255,255,0.1)'; + // ctx.fill(); + + ctx.beginPath(); + ctx.arc( + this.pos.x * scale, + this.pos.y * scale, + this.radius * scale, + 0, + Math.PI * 2, + false + ); + ctx.fillStyle = this.fillStyle; + ctx.fill(); + + }, + + distanceTo: function(target) { + var xd = this.home.x - target.x; + var yd = this.home.y - target.y; + return Math.sqrt(xd * xd + yd * yd ); + } +}; + +window.Puller = Puller; + +})( + window.Engine, + window.Vector +); diff --git a/website/source/layouts/_footer.erb b/website/source/layouts/_footer.erb index 71280c244d..3df1589fa3 100644 --- a/website/source/layouts/_footer.erb +++ b/website/source/layouts/_footer.erb @@ -19,5 +19,19 @@
+ + + + + + + + + + + + + + diff --git a/website/source/layouts/_header.erb b/website/source/layouts/_header.erb index 2d2f5c7d74..c69272659e 100644 --- a/website/source/layouts/_header.erb +++ b/website/source/layouts/_header.erb @@ -34,7 +34,7 @@ -"> +" class="page-<%= current_page.data.page_title ? "#{current_page.data.page_title} layout-#{current_page.data.layout} page-sub" : "home layout-#{current_page.data.layout}" %>">