diff --git a/src/async.js b/src/async.js new file mode 100644 index 00000000..9ef63818 --- /dev/null +++ b/src/async.js @@ -0,0 +1,162 @@ +/** + * Util classes + */ + + +/** + * Particle System Engine + * + * Handles async stuff like adding the edges, etc + */ +function Engine() { + this.addEdgeTimeout = null; + this.edgeClosures = []; +} + +Engine.prototype.addEdge = function(node1, node2) { + this.touchEdgeTimer(); + + this.edgeClosures.push(this.edgeClosureFactory(node1, node2)); +}; + +Engine.prototype.edgeClosureFactory = function(node1, node2) { + var c = function() { + var e = sys.addEdge(node1, node2); + if (e) { + e.afterConstruct(); + } + }; + return c; +}; + +Engine.prototype.touchEdgeTimer = function(key) { + if (this.addEdgeTimeout) { + return; + } + + var _this = this; + this.addEdgeTimeout = setTimeout(function() { + _this.startEdgeScheduler(); + }, 100); +}; + +Engine.prototype.startEdgeScheduler = function() { + // start scheduler + var s = new Scheduler(this.edgeClosures, time.edgeAddInterval, 'add_edge'); + s.start(); + + this.resetEdges(); +}; + +Engine.prototype.resetEdges = function() { + this.edgeClosures = []; + this.addEdgeTimeout = null; +}; + + +function Scheduler(closures, interval, type) { + if (!closures || !closures.length || !interval || !type) { + throw new Error('invalid params'); + } + + this.done = false; + this.closures = closures; + this.interval = interval; + this.type = type; + this.timeOut = null; + this.index = 0; + + ee.addListener('scheduler_stop', this.stopSchedule, this); +} + +Scheduler.prototype.start = function() { + // set the first interval + this.index = 0; + this.done = false; + this.setNext(); +}; + +Scheduler.prototype.setNext = function(interval) { + var _this = this; + this.timeOut = setTimeout(function() { + _this.step(); + }, interval || this.interval); +}; + +Scheduler.prototype.stopSchedule = function(type) { + console.log('received event signal'); + if (type == 'all' || type == this.type) { + // either of these should work... + this.done = true; + clearTimeout(this.timeOut); + } +}; + +Scheduler.prototype.step = function() { + if (this.done) { + return; + } + + var results = this.closures[this.index]() || {}; + this.index++; + + if (results.done || this.index >= this.closures.length) { + this.done = true; + return; + } + this.setNext(results.interval); +}; + + + +/** + * class Breather + */ +function Breather(closure, baseline, delta, period, wait) { + this.delta = delta; + this.baseline = baseline; + this.closure = closure; + + this.t = 0; + this.interval = 1/40 * 1000; // 40fps + + var period_in_seconds = period || time.breathePeriod; + this.period = 2 * Math.PI * 1000 * period_in_seconds; + + this.interpolationFunction = TWEEN.Easing.Cubic.EaseInOut; + + if (wait) { + var _this = this; + setTimeout(function() { + _this.start(); + }, wait); + } else { + this.start(); + } +} + +Breather.prototype.start = function() { + this.t = 0; + this.next(); +}; + +Breather.prototype.next = function() { + this.timeout = setTimeout( + $.proxy(function() { + this.breathe(); + }, this), + this.interval); +}; + +Breather.prototype.stop = function() { + clearTimeout(this.timeout); +}; + +Breather.prototype.breathe = function() { + this.t += this.interval; + + var value = Math.sin(this.t / this.period) * this.delta + this.baseline; + this.closure(value); + + this.next(); +}; diff --git a/src/commandline.js b/src/commandline.js new file mode 100644 index 00000000..647e9ba8 --- /dev/null +++ b/src/commandline.js @@ -0,0 +1,143 @@ +/** + * class Command + * @desc A parser for commands given + */ +function Command(str) { + this.rawCommand = str; + this.results = { + msgs: [] + }; + this.command = null; + + this.parse(str); +} + +Command.prototype.getShortcutMap = function() { + return { + gc: 'git commit', + ga: 'git add', + gchk: 'git checkout', + gr: 'git rebase' + }; +}; + +Command.prototype.getRegexMap = function() { + return { + commit: /^commit /, + add: /^add /, + checkout: /^checkout /, + rebase: /^rebase /, + reset: /^reset / + }; +}; + +Command.prototype.parse = function(str) { + // first check if shortcut exists, and replace + str = this.getShortcutMap()[str] || str; + + // see if begins with git + if (str.slice(0,3) !== 'git') { + return this.nonGitCommand(); + } + + // now slice off command part + this.command = str.slice(4); + + //TODO: underscore.js here + for (var method in this.getRegexMap()) { + var regex = this.getRegexMap()[method]; + if (regex.exec(this.command)) { + this.options = this.comand.slice(method.length + 1); + // break out here + return this[method](); + } + } + + this.results.msgs.push('The git command "' + command + + '" is not supported, sorry!'); +}; + +Command.prototype.nonGitCommand = function() { + this.results.error = { + msg: 'Git only commands, sorry!' + }; +}; + +Command.prototype.commit = function() { + this.results.msgs.push( + 'Commiting with options "' + this.options + '" + ); + + // commit for us means simply either ammending the current commit + // or just popping a new commit on top + var optionMap = { + // supported options + '--amend': false, + // pass through options, dont care but shouldnt fatal + '-a': false, + '-c': false, + '-C': false + }; + + this.options = new OptionParser(this.command, optionMap); + this.results.exec = function(gitEngine) { + gitEngine.commit(optionMap); + }; +}; + +Command.prototype.add = function() { + this.results.msgs.push( + "This demo is meant to demonstrate git branching, so don't worry " + + "about adding / staging files. Just go ahead and commit away!" + ); +}; + +Command.prototype.checkout = function() { + +}; + +Command.prototype.rebase = function() { + +}; + +Command.reset = function() { + +}; + +/** + * OptionParser + */ +function OptionParser(str, supportedMap) { + this.str = str; + this.supportedMap = supportedMap; + this.results = { + unsupportedOptions: [] + }; + + this.explodeAndSet(); +} + +OptionParser.prototype.explodeAndSet = function() { + var exploded = this.str.split(' '); + var options =[]; + + // TODO: underscore + for (var i = 0; i < exploded.length; i++) { + var part = exploded[i]; + if (part.slice(0,1) == '-') { + options.push(part); + } + } + // TODO: undersore + for (var i = 0; i < options.length; i++) { + var option = options[i]; + if (this.supportedMap[option] !== undefined) { + this.supportedMap[option] = true; + } else { + this.results.unsupportedOptions.push(option); + } + } + // done! +}; + + diff --git a/src/constants.js b/src/constants.js new file mode 100644 index 00000000..fe99076c --- /dev/null +++ b/src/constants.js @@ -0,0 +1,38 @@ + +/** + * Constants....!!! + */ +var constants = { + clickDragMass: 20, + baseMass: 1, +}; + +var time = { + edgeAddInterval: 200, + breathePeriod: 0.3 +}; + +/** + * Graphics style + */ +var graphics = { + // colors + edgeStroke: 'rgba(94%, 96%, 98%, 0.5)', // '#EFF5FB', + nodeEdge: 'rgba(94%, 96%, 98%, 0.9)', // '#EFF5FB', + nodeFill: '#0066cc', + + // widths + nodeStrokeWidth: 15, + edgeWidth: 2, +}; + +function randomString(string_length) { + var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz"; + var randomstring = ''; + for (var i=0; i - + + + + diff --git a/src/legacy.js b/src/legacy.js index b262069e..c46dcd01 100644 --- a/src/legacy.js +++ b/src/legacy.js @@ -39,7 +39,7 @@ Renderer = function(canvas) { resize: function(){ var w = $(window).width(), h = $(window).height(); - // resize the canvas element to fill the screen + // resize the canvas element to fill the screen TODO -- fix this canvas.width = w; canvas.height = h; // inform the system so it can map coords for us particleSystem.screenSize(w,h); @@ -96,19 +96,10 @@ Renderer = function(canvas) { return that; } -function makeEdgeAddClosure(sys, node1, node2) { - var c = function() { - var e = sys.addEdge(node1, node2); - if (e) { - e.afterConstruct(); - } - }; - return c; -} - var Maps = function(elt){ - sys = arbor.ParticleSystem(4000, 500, 0.5, false, 55, 0.005, 'verlet') - sys.renderer = Renderer("#viewport") // our newly created renderer will have its .init() method called shortly by sys... + sys = arbor.ParticleSystem(4000, 500, 0.5, false, 55, 0.005, 'verlet'); + sys.renderer = Renderer("#viewport"); + // our newly created renderer will have its .init() method called shortly by sys... // Add some random nodes and edges to the graph! nodes = []; diff --git a/src/mine.js b/src/mine.js index 23c4dc79..ddaf38cf 100644 --- a/src/mine.js +++ b/src/mine.js @@ -1,4 +1,3 @@ - /** * Globals */ @@ -8,24 +7,26 @@ var engine = null; var graphicsEffects = {}; $(document).ready(function(){ - engine = new Engine(); - ee = new EventEmitter(); + if (false) { + engine = new Engine(); + ee = new EventEmitter(); - var mcp = Maps("#maps"); + var mcp = Maps("#maps"); - var repulsionBreathe = function(r) { - sys.parameters({repulsion: r}); - }; - var b = new Breather(repulsionBreathe, 6050, 4000); + var repulsionBreathe = function(r) { + sys.parameters({repulsion: r}); + }; + var b = new Breather(repulsionBreathe, 6050, 4000); - graphicsEffects.edgeStrokeEffect = new GraphicsEffect('edgeStroke', {wait: 1000}); + graphicsEffects.edgeStrokeEffect = new GraphicsEffect('edgeStroke', {wait: 1000}); + } }); + + /** - * Extend the Arbiter classes below with my own custom functionality to - * stop this horrible object cross link stuff + * Extend the Arbiter classes below with my own custom functionality. */ Node.prototype.afterConstruct = function() { - this.positions = []; }; Node.prototype.draw = function(ctx, pt) { @@ -49,7 +50,6 @@ Node.prototype.drawCircleNode = function(ctx, pt) { * Edge */ Edge.prototype.afterConstruct = function() { - //this.pastEdges = []; }; Edge.prototype.draw = function(ctx, pt1, pt2) { @@ -71,6 +71,9 @@ Edge.prototype.drawLine = function(ctx, pt1, pt2, opacityPercent) { }; +/** + * class GraphicsEffect + */ function GraphicsEffect(gKey, options) { this.baseColor = graphics[gKey]; @@ -101,7 +104,7 @@ GraphicsEffect.prototype.resume = function() { }; /** - * Breather + * class Breather */ function Breather(closure, baseline, delta, period, wait) { this.delta = delta; @@ -132,10 +135,11 @@ Breather.prototype.start = function() { }; Breather.prototype.next = function() { - var _this = this; - this.timeout = setTimeout(function() { - _this.breathe(); - }, this.interval); + this.timeout = setTimeout( + $.proxy(function() { + this.breathe(); + }, this), + this.interval); }; Breather.prototype.stop = function() { @@ -201,61 +205,3 @@ Engine.prototype.resetEdges = function() { this.addEdgeTimeout = null; }; -/** - * Cover Photo - */ -function CoverPhoto(id, profile_pic_src, cover_photo_src) { - this.pp_src = profile_pic_src; - this.cp_src = cover_photo_src; - this.profile_id = id; - - // this is where I _should_ use templating... but i wont :P - this.html = '' + - '
' + - '
' + - '' + - '
' + - '
' + - '
' + - '
' + - '' + - '
' + - '
' - ; - - $('body').append(this.html); - this.cp_node = $('#' + id + 'coverphoto')[0]; - this.pp_node = $('#' + id + 'profilepic')[0]; -}; - -CoverPhoto.prototype.show = function() { - var _this = this; - // let it get drawn first so it animates - setTimeout(function() { - _this.toggleShow(true); - }, 10); -}; - -CoverPhoto.prototype.hide = function() { - this.toggleShow(false); -}; - -CoverPhoto.prototype.toggle = function() { - $(this.cp_node).toggleClass('visible'); - $(this.pp_node).toggleClass('visible'); -}; - -CoverPhoto.prototype.toggleShow = function(bool) { - $(this.cp_node).toggleClass('visible', bool); - $(this.pp_node).toggleClass('visible', bool); -}; - -var profile_pic_src = 'https://fbcdn-profile-a.akamaihd.net/hprofile-ak-ash2/368844_545515979_1956877679_n.jpg'; -var cover_photo_src = 'https://fbcdn-sphotos-a.akamaihd.net/hphotos-ak-ash3/c0.0.851.315/p851x315/564389_10150741774845980_1149055874_n.jpg'; -var c = new CoverPhoto('pcottle', profile_pic_src, cover_photo_src); - -c.show(); -setTimeout(function() { - c.hide(); -}, 2000); - diff --git a/src/util.js b/src/util.js deleted file mode 100644 index 024abc74..00000000 --- a/src/util.js +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Util classes - */ - -function Scheduler(closures, interval, type) { - if (!closures || !closures.length || !interval || !type) { - throw new Error('invalid params'); - } - - this.done = false; - this.closures = closures; - this.interval = interval; - this.type = type; - this.timeOut = null; - this.index = 0; - - ee.addListener('scheduler_stop', this.stopSchedule, this); -} - -Scheduler.prototype.start = function() { - // set the first interval - this.index = 0; - this.done = false; - this.setNext(); -}; - -Scheduler.prototype.setNext = function(interval) { - var _this = this; - this.timeOut = setTimeout(function() { - _this.step(); - }, interval || this.interval); -}; - -Scheduler.prototype.stopSchedule = function(type) { - console.log('received event signal'); - if (type == 'all' || type == this.type) { - // either of these should work... - this.done = true; - clearTimeout(this.timeOut); - } -}; - -Scheduler.prototype.step = function() { - if (this.done) { - return; - } - - //console.log(this.type + ' is stepping with index ' + this.index); - var results = this.closures[this.index]() || {}; - this.index++; - - if (results.done || this.index >= this.closures.length) { - this.done = true; - return; - } - this.setNext(results.interval); -}; - -/** - * Constants....!!! - */ -var constants = { - clickDragMass: 20, - baseMass: 1, -}; - -var time = { - edgeAddInterval: 200, - breathePeriod: 0.3 -}; - -/** - * Graphics style - */ -var graphics = { - // colors - edgeStroke: 'rgba(94%, 96%, 98%, 0.5)', // '#EFF5FB', - nodeEdge: 'rgba(94%, 96%, 98%, 0.9)', // '#EFF5FB', - nodeFill: '#0066cc', - - // widths - nodeStrokeWidth: 15, - edgeWidth: 2, -}; - -function randomString(string_length) { - var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz"; - var randomstring = ''; - for (var i=0; i