diff --git a/build/bundle.js b/build/bundle.js index 2fc78082..7b68f042 100644 --- a/build/bundle.js +++ b/build/bundle.js @@ -4385,23 +4385,15 @@ require.define("/node_modules/backbone/node_modules/underscore/underscore.js",fu }); -require.define("/src/js/visuals/index.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore'); +require.define("/src/js/visuals/visualization.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore'); // horrible hack to get localStorage Backbone plugin var Backbone = (!require('../util').isBrowser()) ? Backbone = require('backbone') : Backbone = window.Backbone; -var GRAPHICS = require('../util/constants').GRAPHICS; -var GLOBAL = require('../util/constants').GLOBAL; - var Collections = require('../models/collections'); var CommitCollection = Collections.CommitCollection; var BranchCollection = Collections.BranchCollection; -var Tree = require('../visuals/tree'); -var VisEdgeCollection = Tree.VisEdgeCollection; -var VisBranchCollection = Tree.VisBranchCollection; -var VisNode = Tree.VisNode; -var VisBranch = Tree.VisBranch; -var VisEdge = Tree.VisEdge; +var GitVisuals = require('../visuals').GitVisuals; var Visualization = Backbone.View.extend({ initialize: function(options) { @@ -4478,618 +4470,9 @@ var Visualization = Backbone.View.extend({ this.paper.setSize(width, height); this.gitVisuals.canvasResize(width, height); } - }); -function GitVisuals(options) { - this.commitCollection = options.commitCollection; - this.branchCollection = options.branchCollection; - this.visNodeMap = {}; - - this.visEdgeCollection = new VisEdgeCollection(); - this.visBranchCollection = new VisBranchCollection(); - this.commitMap = {}; - - this.rootCommit = null; - this.branchStackMap = null; - this.upstreamBranchSet = null; - this.upstreamHeadSet = null; - - this.paper = options.paper; - this.gitReady = false; - - this.branchCollection.on('add', this.addBranchFromEvent, this); - this.branchCollection.on('remove', this.removeBranch, this); - this.deferred = []; - - this.events = require('../app').getEvents(); - this.events.on('refreshTree', _.bind( - this.refreshTree, this - )); -} - -GitVisuals.prototype.defer = function(action) { - this.deferred.push(action); -}; - -GitVisuals.prototype.deferFlush = function() { - _.each(this.deferred, function(action) { - action(); - }, this); - this.deferred = []; -}; - -GitVisuals.prototype.resetAll = function() { - // make sure to copy these collections because we remove - // items in place and underscore is too dumb to detect length change - var edges = this.visEdgeCollection.toArray(); - _.each(edges, function(visEdge) { - visEdge.remove(); - }, this); - - var branches = this.visBranchCollection.toArray(); - _.each(branches, function(visBranch) { - visBranch.remove(); - }, this); - - _.each(this.visNodeMap, function(visNode) { - visNode.remove(); - }, this); - - this.visEdgeCollection.reset(); - this.visBranchCollection.reset(); - - this.visNodeMap = {}; - this.rootCommit = null; - this.commitMap = {}; -}; - -GitVisuals.prototype.assignGitEngine = function(gitEngine) { - this.gitEngine = gitEngine; - this.initHeadBranch(); - this.deferFlush(); -}; - -GitVisuals.prototype.initHeadBranch = function() { - // it's unfortaunte we have to do this, but the head branch - // is an edge case because it's not part of a collection so - // we can't use events to load or unload it. thus we have to call - // this ugly method which will be deleted one day - - // seed this with the HEAD pseudo-branch - this.addBranchFromEvent(this.gitEngine.HEAD); -}; - -GitVisuals.prototype.getScreenBounds = function() { - // for now we return the node radius subtracted from the walls - return { - widthPadding: GRAPHICS.nodeRadius * 1.5, - heightPadding: GRAPHICS.nodeRadius * 1.5 - }; -}; - -GitVisuals.prototype.toScreenCoords = function(pos) { - if (!this.paper.width) { - throw new Error('being called too early for screen coords'); - } - var bounds = this.getScreenBounds(); - - var shrink = function(frac, total, padding) { - return padding + frac * (total - padding * 2); - }; - - return { - x: shrink(pos.x, this.paper.width, bounds.widthPadding), - y: shrink(pos.y, this.paper.height, bounds.heightPadding) - }; -}; - -GitVisuals.prototype.animateAllFromAttrToAttr = function(fromSnapshot, toSnapshot, idsToOmit) { - var animate = function(obj) { - var id = obj.getID(); - if (_.include(idsToOmit, id)) { - return; - } - - if (!fromSnapshot[id] || !toSnapshot[id]) { - // its actually ok it doesnt exist yet - return; - } - obj.animateFromAttrToAttr(fromSnapshot[id], toSnapshot[id]); - }; - - this.visBranchCollection.each(function(visBranch) { - animate(visBranch); - }); - this.visEdgeCollection.each(function(visEdge) { - animate(visEdge); - }); - _.each(this.visNodeMap, function(visNode) { - animate(visNode); - }); -}; - -/*************************************** - == BEGIN Tree Calculation Parts == - _ __ __ _ - \\/ / \ \//_ - \ \ / __| __ - \ \___/ /_____/ / - | _______ \ - \ ( ) / \_\ - \ / - | | - | | - ____+-_=+-^ ^+-=_=__________ - -^^ I drew that :D - - **************************************/ - -GitVisuals.prototype.genSnapshot = function() { - this.fullCalc(); - - var snapshot = {}; - _.each(this.visNodeMap, function(visNode) { - snapshot[visNode.get('id')] = visNode.getAttributes(); - }, this); - - this.visBranchCollection.each(function(visBranch) { - snapshot[visBranch.getID()] = visBranch.getAttributes(); - }, this); - - this.visEdgeCollection.each(function(visEdge) { - snapshot[visEdge.getID()] = visEdge.getAttributes(); - }, this); - - return snapshot; -}; - -GitVisuals.prototype.refreshTree = function(speed) { - if (!this.gitReady) { - return; - } - - // this method can only be called after graphics are rendered - this.fullCalc(); - - this.animateAll(speed); -}; - -GitVisuals.prototype.refreshTreeHarsh = function() { - this.fullCalc(); - - this.animateAll(0); -}; - -GitVisuals.prototype.animateAll = function(speed) { - this.zIndexReflow(); - - this.animateEdges(speed); - this.animateNodePositions(speed); - this.animateRefs(speed); -}; - -GitVisuals.prototype.fullCalc = function() { - this.calcTreeCoords(); - this.calcGraphicsCoords(); -}; - -GitVisuals.prototype.calcTreeCoords = function() { - // this method can only contain things that dont rely on graphics - if (!this.rootCommit) { - throw new Error('grr, no root commit!'); - } - - this.calcUpstreamSets(); - this.calcBranchStacks(); - - this.calcDepth(); - this.calcWidth(); -}; - -GitVisuals.prototype.calcGraphicsCoords = function() { - this.visBranchCollection.each(function(visBranch) { - visBranch.updateName(); - }); -}; - -GitVisuals.prototype.calcUpstreamSets = function() { - this.upstreamBranchSet = this.gitEngine.getUpstreamBranchSet(); - this.upstreamHeadSet = this.gitEngine.getUpstreamHeadSet(); -}; - -GitVisuals.prototype.getCommitUpstreamBranches = function(commit) { - return this.branchStackMap[commit.get('id')]; -}; - -GitVisuals.prototype.getBlendedHuesForCommit = function(commit) { - var branches = this.upstreamBranchSet[commit.get('id')]; - if (!branches) { - throw new Error('that commit doesnt have upstream branches!'); - } - - return this.blendHuesFromBranchStack(branches); -}; - -GitVisuals.prototype.blendHuesFromBranchStack = function(branchStackArray) { - var hueStrings = []; - _.each(branchStackArray, function(branchWrapper) { - var fill = branchWrapper.obj.get('visBranch').get('fill'); - - if (fill.slice(0,3) !== 'hsb') { - // crap! convert - var color = Raphael.color(fill); - fill = 'hsb(' + String(color.h) + ',' + String(color.l); - fill = fill + ',' + String(color.s) + ')'; - } - - hueStrings.push(fill); - }); - - return blendHueStrings(hueStrings); -}; - -GitVisuals.prototype.getCommitUpstreamStatus = function(commit) { - if (!this.upstreamBranchSet) { - throw new Error("Can't calculate this yet!"); - } - - var id = commit.get('id'); - var branch = this.upstreamBranchSet; - var head = this.upstreamHeadSet; - - if (branch[id]) { - return 'branch'; - } else if (head[id]) { - return 'head'; - } else { - return 'none'; - } -}; - -GitVisuals.prototype.calcBranchStacks = function() { - var branches = this.gitEngine.getBranches(); - var map = {}; - _.each(branches, function(branch) { - var thisId = branch.target.get('id'); - - map[thisId] = map[thisId] || []; - map[thisId].push(branch); - map[thisId].sort(function(a, b) { - var aId = a.obj.get('id'); - var bId = b.obj.get('id'); - if (aId == 'master' || bId == 'master') { - return aId == 'master' ? -1 : 1; - } - return aId.localeCompare(bId); - }); - }); - this.branchStackMap = map; -}; - -GitVisuals.prototype.calcWidth = function() { - this.maxWidthRecursive(this.rootCommit); - - this.assignBoundsRecursive(this.rootCommit, 0, 1); -}; - -GitVisuals.prototype.maxWidthRecursive = function(commit) { - var childrenTotalWidth = 0; - _.each(commit.get('children'), function(child) { - // only include this if we are the "main" parent of - // this child - if (child.isMainParent(commit)) { - var childWidth = this.maxWidthRecursive(child); - childrenTotalWidth += childWidth; - } - }, this); - - var maxWidth = Math.max(1, childrenTotalWidth); - commit.get('visNode').set('maxWidth', maxWidth); - return maxWidth; -}; - -GitVisuals.prototype.assignBoundsRecursive = function(commit, min, max) { - // I always center myself within my bounds - var myWidthPos = (min + max) / 2.0; - commit.get('visNode').get('pos').x = myWidthPos; - - if (commit.get('children').length === 0) { - return; - } - - // i have a certain length to divide up - var myLength = max - min; - // I will divide up that length based on my children's max width in a - // basic box-flex model - var totalFlex = 0; - var children = commit.get('children'); - _.each(children, function(child) { - if (child.isMainParent(commit)) { - totalFlex += child.get('visNode').getMaxWidthScaled(); - } - }, this); - - var prevBound = min; - - // now go through and do everything - // TODO: order so the max width children are in the middle!! - _.each(children, function(child) { - if (!child.isMainParent(commit)) { - return; - } - - var flex = child.get('visNode').getMaxWidthScaled(); - var portion = (flex / totalFlex) * myLength; - var childMin = prevBound; - var childMax = childMin + portion; - this.assignBoundsRecursive(child, childMin, childMax); - prevBound = childMax; - }, this); -}; - -GitVisuals.prototype.calcDepth = function() { - var maxDepth = this.calcDepthRecursive(this.rootCommit, 0); - if (maxDepth > 15) { - // issue warning - console.warn('graphics are degrading from too many layers'); - } - - var depthIncrement = this.getDepthIncrement(maxDepth); - _.each(this.visNodeMap, function(visNode) { - visNode.setDepthBasedOn(depthIncrement); - }, this); -}; - -/*************************************** - == END Tree Calculation == - _ __ __ _ - \\/ / \ \//_ - \ \ / __| __ - \ \___/ /_____/ / - | _______ \ - \ ( ) / \_\ - \ / - | | - | | - ____+-_=+-^ ^+-=_=__________ - -^^ I drew that :D - - **************************************/ - -GitVisuals.prototype.animateNodePositions = function(speed) { - _.each(this.visNodeMap, function(visNode) { - visNode.animateUpdatedPosition(speed); - }, this); -}; - -GitVisuals.prototype.turnOnPaper = function() { - this.gitReady = false; -}; - -// does making an accessor method make it any less hacky? that is the true question -GitVisuals.prototype.turnOffPaper = function() { - this.gitReady = true; -}; - -GitVisuals.prototype.addBranchFromEvent = function(branch, collection, index) { - var action = _.bind(function() { - this.addBranch(branch); - }, this); - - if (!this.gitEngine || !this.gitReady) { - this.defer(action); - } else { - action(); - } -}; - -GitVisuals.prototype.addBranch = function(branch) { - var visBranch = new VisBranch({ - branch: branch, - gitVisuals: this, - gitEngine: this.gitEngine - }); - - this.visBranchCollection.add(visBranch); - if (this.gitReady) { - visBranch.genGraphics(this.paper); - } -}; - -GitVisuals.prototype.removeVisBranch = function(visBranch) { - this.visBranchCollection.remove(visBranch); -}; - -GitVisuals.prototype.removeVisNode = function(visNode) { - this.visNodeMap[visNode.getID()] = undefined; -}; - -GitVisuals.prototype.removeVisEdge = function(visEdge) { - this.visEdgeCollection.remove(visEdge); -}; - -GitVisuals.prototype.animateRefs = function(speed) { - this.visBranchCollection.each(function(visBranch) { - visBranch.animateUpdatedPos(speed); - }, this); -}; - -GitVisuals.prototype.animateEdges = function(speed) { - this.visEdgeCollection.each(function(edge) { - edge.animateUpdatedPath(speed); - }, this); -}; - -GitVisuals.prototype.getDepthIncrement = function(maxDepth) { - // assume there are at least 7 layers until later - maxDepth = Math.max(maxDepth, 7); - var increment = 1.0 / maxDepth; - return increment; -}; - -GitVisuals.prototype.calcDepthRecursive = function(commit, depth) { - commit.get('visNode').setDepth(depth); - - var children = commit.get('children'); - var maxDepth = depth; - _.each(children, function(child) { - var d = this.calcDepthRecursive(child, depth + 1); - maxDepth = Math.max(d, maxDepth); - }, this); - - return maxDepth; -}; - -// we debounce here so we aren't firing a resize call on every resize event -// but only after they stop -GitVisuals.prototype.canvasResize = _.debounce(function(width, height) { - // refresh when we are ready - if (GLOBAL.isAnimating) { - this.events.trigger('processCommandFromEvent', 'refresh'); - } else { - this.refreshTree(); - } -}, 200); - -GitVisuals.prototype.addNode = function(id, commit) { - this.commitMap[id] = commit; - if (commit.get('rootCommit')) { - this.rootCommit = commit; - } - - var visNode = new VisNode({ - id: id, - commit: commit, - gitVisuals: this, - gitEngine: this.gitEngine - }); - this.visNodeMap[id] = visNode; - - if (this.gitReady) { - visNode.genGraphics(this.paper); - } - return visNode; -}; - -GitVisuals.prototype.addEdge = function(idTail, idHead) { - var visNodeTail = this.visNodeMap[idTail]; - var visNodeHead = this.visNodeMap[idHead]; - - if (!visNodeTail || !visNodeHead) { - throw new Error('one of the ids in (' + idTail + - ', ' + idHead + ') does not exist'); - } - - var edge = new VisEdge({ - tail: visNodeTail, - head: visNodeHead, - gitVisuals: this, - gitEngine: this.gitEngine - }); - this.visEdgeCollection.add(edge); - - if (this.gitReady) { - edge.genGraphics(this.paper); - } -}; - -GitVisuals.prototype.collectionChanged = function() { - // TODO ? -}; - -GitVisuals.prototype.zIndexReflow = function() { - this.visNodesFront(); - this.visBranchesFront(); -}; - -GitVisuals.prototype.visNodesFront = function() { - _.each(this.visNodeMap, function(visNode) { - visNode.toFront(); - }); -}; - -GitVisuals.prototype.visBranchesFront = function() { - this.visBranchCollection.each(function(vBranch) { - vBranch.nonTextToFront(); - }); - - this.visBranchCollection.each(function(vBranch) { - vBranch.textToFront(); - }); -}; - -GitVisuals.prototype.drawTreeFromReload = function() { - this.gitReady = true; - // gen all the graphics we need - this.deferFlush(); - - this.calcTreeCoords(); -}; - -GitVisuals.prototype.drawTreeFirstTime = function() { - this.gitReady = true; - this.calcTreeCoords(); - - _.each(this.visNodeMap, function(visNode) { - visNode.genGraphics(this.paper); - }, this); - - this.visEdgeCollection.each(function(edge) { - edge.genGraphics(this.paper); - }, this); - - this.visBranchCollection.each(function(visBranch) { - visBranch.genGraphics(this.paper); - }, this); - - this.zIndexReflow(); -}; - - -/************************ - * Random util functions, some from liquidGraph - ***********************/ -function blendHueStrings(hueStrings) { - // assumes a sat of 0.7 and brightness of 1 - - var x = 0; - var y = 0; - var totalSat = 0; - var totalBright = 0; - var length = hueStrings.length; - - _.each(hueStrings, function(hueString) { - var exploded = hueString.split('(')[1]; - exploded = exploded.split(')')[0]; - exploded = exploded.split(','); - - totalSat += parseFloat(exploded[1]); - totalBright += parseFloat(exploded[2]); - var hue = parseFloat(exploded[0]); - - var angle = hue * Math.PI * 2; - x += Math.cos(angle); - y += Math.sin(angle); - }); - - x = x / length; - y = y / length; - totalSat = totalSat / length; - totalBright = totalBright / length; - - var hue = Math.atan2(y, x) / (Math.PI * 2); // could fail on 0's - if (hue < 0) { - hue = hue + 1; - } - return 'hsb(' + String(hue) + ',' + String(totalSat) + ',' + String(totalBright) + ')'; -} - exports.Visualization = Visualization; -exports.GitVisuals = GitVisuals; - }); @@ -5118,55 +4501,6 @@ exports.splitTextCommand = function(value, func, context) { }); }; -}); - -require.define("/src/js/util/constants.js",function(require,module,exports,__dirname,__filename,process,global){/** - * Constants....!!! - */ -var TIME = { - betweenCommandsDelay: 400 -}; - -// useful for locks, etc -var GLOBAL = { - isAnimating: false -}; - -var GRAPHICS = { - arrowHeadSize: 8, - - nodeRadius: 17, - curveControlPointOffset: 50, - defaultEasing: 'easeInOut', - defaultAnimationTime: 400, - - //rectFill: '#FF3A3A', - rectFill: 'hsb(0.8816909813322127,0.7,1)', - headRectFill: '#2831FF', - rectStroke: '#FFF', - rectStrokeWidth: '3', - - multiBranchY: 20, - upstreamHeadOpacity: 0.5, - upstreamNoneOpacity: 0.2, - edgeUpstreamHeadOpacity: 0.4, - edgeUpstreamNoneOpacity: 0.15, - - visBranchStrokeWidth: 2, - visBranchStrokeColorNone: '#333', - - defaultNodeFill: 'hsba(0.5,0.8,0.7,1)', - defaultNodeStrokeWidth: 2, - defaultNodeStroke: '#FFF', - - orphanNodeFill: 'hsb(0.5,0.8,0.7)' -}; - -exports.GLOBAL = GLOBAL; -exports.TIME = TIME; -exports.GRAPHICS = GRAPHICS; - - }); require.define("/src/js/models/collections.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore'); @@ -8878,6 +8212,55 @@ var AnimationQueue = Backbone.Model.extend({ exports.Animation = Animation; exports.AnimationQueue = AnimationQueue; +}); + +require.define("/src/js/util/constants.js",function(require,module,exports,__dirname,__filename,process,global){/** + * Constants....!!! + */ +var TIME = { + betweenCommandsDelay: 400 +}; + +// useful for locks, etc +var GLOBAL = { + isAnimating: false +}; + +var GRAPHICS = { + arrowHeadSize: 8, + + nodeRadius: 17, + curveControlPointOffset: 50, + defaultEasing: 'easeInOut', + defaultAnimationTime: 400, + + //rectFill: '#FF3A3A', + rectFill: 'hsb(0.8816909813322127,0.7,1)', + headRectFill: '#2831FF', + rectStroke: '#FFF', + rectStrokeWidth: '3', + + multiBranchY: 20, + upstreamHeadOpacity: 0.5, + upstreamNoneOpacity: 0.2, + edgeUpstreamHeadOpacity: 0.4, + edgeUpstreamNoneOpacity: 0.15, + + visBranchStrokeWidth: 2, + visBranchStrokeColorNone: '#333', + + defaultNodeFill: 'hsba(0.5,0.8,0.7,1)', + defaultNodeStrokeWidth: 2, + defaultNodeStroke: '#FFF', + + orphanNodeFill: 'hsb(0.5,0.8,0.7)' +}; + +exports.GLOBAL = GLOBAL; +exports.TIME = TIME; +exports.GRAPHICS = GRAPHICS; + + }); require.define("/src/js/git/treeCompare.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore'); @@ -9100,7 +8483,6 @@ var InteractiveRebaseView = Backbone.View.extend({ }, toggleVisibility: function(toggle) { - console.log('toggling'); $('#dialogHolder').toggleClass('shown', toggle); }, @@ -9598,10 +8980,10 @@ var mainVis = null; /////////////////////////////////////////////////////////////////////// var init = function(){ - var Visuals = require('../visuals'); + var Visualization = require('../visuals/visualization').Visualization; ui = new UI(); - mainVis = new Visuals.Visualization({ + mainVis = new Visualization({ el: $('#canvasWrapper')[0] }); @@ -10036,6 +9418,634 @@ exports.CommandPromptView = CommandPromptView; exports.CommandLineHistoryView = CommandLineHistoryView; +}); + +require.define("/src/js/visuals/index.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore'); +// horrible hack to get localStorage Backbone plugin +var Backbone = (!require('../util').isBrowser()) ? Backbone = require('backbone') : Backbone = window.Backbone; + +var GRAPHICS = require('../util/constants').GRAPHICS; +var GLOBAL = require('../util/constants').GLOBAL; + +var Collections = require('../models/collections'); +var CommitCollection = Collections.CommitCollection; +var BranchCollection = Collections.BranchCollection; + +var Tree = require('../visuals/tree'); +var VisEdgeCollection = Tree.VisEdgeCollection; +var VisBranchCollection = Tree.VisBranchCollection; +var VisNode = Tree.VisNode; +var VisBranch = Tree.VisBranch; +var VisEdge = Tree.VisEdge; + +function GitVisuals(options) { + this.commitCollection = options.commitCollection; + this.branchCollection = options.branchCollection; + this.visNodeMap = {}; + + this.visEdgeCollection = new VisEdgeCollection(); + this.visBranchCollection = new VisBranchCollection(); + this.commitMap = {}; + + this.rootCommit = null; + this.branchStackMap = null; + this.upstreamBranchSet = null; + this.upstreamHeadSet = null; + + this.paper = options.paper; + this.gitReady = false; + + this.branchCollection.on('add', this.addBranchFromEvent, this); + this.branchCollection.on('remove', this.removeBranch, this); + this.deferred = []; + + this.events = require('../app').getEvents(); + this.events.on('refreshTree', _.bind( + this.refreshTree, this + )); +} + +GitVisuals.prototype.defer = function(action) { + this.deferred.push(action); +}; + +GitVisuals.prototype.deferFlush = function() { + _.each(this.deferred, function(action) { + action(); + }, this); + this.deferred = []; +}; + +GitVisuals.prototype.resetAll = function() { + // make sure to copy these collections because we remove + // items in place and underscore is too dumb to detect length change + var edges = this.visEdgeCollection.toArray(); + _.each(edges, function(visEdge) { + visEdge.remove(); + }, this); + + var branches = this.visBranchCollection.toArray(); + _.each(branches, function(visBranch) { + visBranch.remove(); + }, this); + + _.each(this.visNodeMap, function(visNode) { + visNode.remove(); + }, this); + + this.visEdgeCollection.reset(); + this.visBranchCollection.reset(); + + this.visNodeMap = {}; + this.rootCommit = null; + this.commitMap = {}; +}; + +GitVisuals.prototype.assignGitEngine = function(gitEngine) { + this.gitEngine = gitEngine; + this.initHeadBranch(); + this.deferFlush(); +}; + +GitVisuals.prototype.initHeadBranch = function() { + // it's unfortaunte we have to do this, but the head branch + // is an edge case because it's not part of a collection so + // we can't use events to load or unload it. thus we have to call + // this ugly method which will be deleted one day + + // seed this with the HEAD pseudo-branch + this.addBranchFromEvent(this.gitEngine.HEAD); +}; + +GitVisuals.prototype.getScreenPadding = function() { + // for now we return the node radius subtracted from the walls + return { + widthPadding: GRAPHICS.nodeRadius * 1.5, + heightPadding: GRAPHICS.nodeRadius * 1.5 + }; +}; + +GitVisuals.prototype.toScreenCoords = function(pos) { + if (!this.paper.width) { + throw new Error('being called too early for screen coords'); + } + var padding = this.getScreenPadding(); + + var shrink = function(frac, total, padding) { + return padding + frac * (total - padding * 2); + }; + + return { + x: shrink(pos.x, this.paper.width, padding.widthPadding), + y: shrink(pos.y, this.paper.height, padding.heightPadding) + }; +}; + +GitVisuals.prototype.animateAllFromAttrToAttr = function(fromSnapshot, toSnapshot, idsToOmit) { + var animate = function(obj) { + var id = obj.getID(); + if (_.include(idsToOmit, id)) { + return; + } + + if (!fromSnapshot[id] || !toSnapshot[id]) { + // its actually ok it doesnt exist yet + return; + } + obj.animateFromAttrToAttr(fromSnapshot[id], toSnapshot[id]); + }; + + this.visBranchCollection.each(function(visBranch) { + animate(visBranch); + }); + this.visEdgeCollection.each(function(visEdge) { + animate(visEdge); + }); + _.each(this.visNodeMap, function(visNode) { + animate(visNode); + }); +}; + +/*************************************** + == BEGIN Tree Calculation Parts == + _ __ __ _ + \\/ / \ \//_ + \ \ / __| __ + \ \___/ /_____/ / + | _______ \ + \ ( ) / \_\ + \ / + | | + | | + ____+-_=+-^ ^+-=_=__________ + +^^ I drew that :D + + **************************************/ + +GitVisuals.prototype.genSnapshot = function() { + this.fullCalc(); + + var snapshot = {}; + _.each(this.visNodeMap, function(visNode) { + snapshot[visNode.get('id')] = visNode.getAttributes(); + }, this); + + this.visBranchCollection.each(function(visBranch) { + snapshot[visBranch.getID()] = visBranch.getAttributes(); + }, this); + + this.visEdgeCollection.each(function(visEdge) { + snapshot[visEdge.getID()] = visEdge.getAttributes(); + }, this); + + return snapshot; +}; + +GitVisuals.prototype.refreshTree = function(speed) { + if (!this.gitReady) { + return; + } + + // this method can only be called after graphics are rendered + this.fullCalc(); + + this.animateAll(speed); +}; + +GitVisuals.prototype.refreshTreeHarsh = function() { + this.fullCalc(); + + this.animateAll(0); +}; + +GitVisuals.prototype.animateAll = function(speed) { + this.zIndexReflow(); + + this.animateEdges(speed); + this.animateNodePositions(speed); + this.animateRefs(speed); +}; + +GitVisuals.prototype.fullCalc = function() { + this.calcTreeCoords(); + this.calcGraphicsCoords(); +}; + +GitVisuals.prototype.calcTreeCoords = function() { + // this method can only contain things that dont rely on graphics + if (!this.rootCommit) { + throw new Error('grr, no root commit!'); + } + + this.calcUpstreamSets(); + this.calcBranchStacks(); + + this.calcDepth(); + this.calcWidth(); +}; + +GitVisuals.prototype.calcGraphicsCoords = function() { + this.visBranchCollection.each(function(visBranch) { + visBranch.updateName(); + }); +}; + +GitVisuals.prototype.calcUpstreamSets = function() { + this.upstreamBranchSet = this.gitEngine.getUpstreamBranchSet(); + this.upstreamHeadSet = this.gitEngine.getUpstreamHeadSet(); +}; + +GitVisuals.prototype.getCommitUpstreamBranches = function(commit) { + return this.branchStackMap[commit.get('id')]; +}; + +GitVisuals.prototype.getBlendedHuesForCommit = function(commit) { + var branches = this.upstreamBranchSet[commit.get('id')]; + if (!branches) { + throw new Error('that commit doesnt have upstream branches!'); + } + + return this.blendHuesFromBranchStack(branches); +}; + +GitVisuals.prototype.blendHuesFromBranchStack = function(branchStackArray) { + var hueStrings = []; + _.each(branchStackArray, function(branchWrapper) { + var fill = branchWrapper.obj.get('visBranch').get('fill'); + + if (fill.slice(0,3) !== 'hsb') { + // crap! convert + var color = Raphael.color(fill); + fill = 'hsb(' + String(color.h) + ',' + String(color.l); + fill = fill + ',' + String(color.s) + ')'; + } + + hueStrings.push(fill); + }); + + return blendHueStrings(hueStrings); +}; + +GitVisuals.prototype.getCommitUpstreamStatus = function(commit) { + if (!this.upstreamBranchSet) { + throw new Error("Can't calculate this yet!"); + } + + var id = commit.get('id'); + var branch = this.upstreamBranchSet; + var head = this.upstreamHeadSet; + + if (branch[id]) { + return 'branch'; + } else if (head[id]) { + return 'head'; + } else { + return 'none'; + } +}; + +GitVisuals.prototype.calcBranchStacks = function() { + var branches = this.gitEngine.getBranches(); + var map = {}; + _.each(branches, function(branch) { + var thisId = branch.target.get('id'); + + map[thisId] = map[thisId] || []; + map[thisId].push(branch); + map[thisId].sort(function(a, b) { + var aId = a.obj.get('id'); + var bId = b.obj.get('id'); + if (aId == 'master' || bId == 'master') { + return aId == 'master' ? -1 : 1; + } + return aId.localeCompare(bId); + }); + }); + this.branchStackMap = map; +}; + +GitVisuals.prototype.calcWidth = function() { + this.maxWidthRecursive(this.rootCommit); + + this.assignBoundsRecursive(this.rootCommit, 0, 1); +}; + +GitVisuals.prototype.maxWidthRecursive = function(commit) { + var childrenTotalWidth = 0; + _.each(commit.get('children'), function(child) { + // only include this if we are the "main" parent of + // this child + if (child.isMainParent(commit)) { + var childWidth = this.maxWidthRecursive(child); + childrenTotalWidth += childWidth; + } + }, this); + + var maxWidth = Math.max(1, childrenTotalWidth); + commit.get('visNode').set('maxWidth', maxWidth); + return maxWidth; +}; + +GitVisuals.prototype.assignBoundsRecursive = function(commit, min, max) { + // I always center myself within my bounds + var myWidthPos = (min + max) / 2.0; + commit.get('visNode').get('pos').x = myWidthPos; + + if (commit.get('children').length === 0) { + return; + } + + // i have a certain length to divide up + var myLength = max - min; + // I will divide up that length based on my children's max width in a + // basic box-flex model + var totalFlex = 0; + var children = commit.get('children'); + _.each(children, function(child) { + if (child.isMainParent(commit)) { + totalFlex += child.get('visNode').getMaxWidthScaled(); + } + }, this); + + var prevBound = min; + + // now go through and do everything + // TODO: order so the max width children are in the middle!! + _.each(children, function(child) { + if (!child.isMainParent(commit)) { + return; + } + + var flex = child.get('visNode').getMaxWidthScaled(); + var portion = (flex / totalFlex) * myLength; + var childMin = prevBound; + var childMax = childMin + portion; + this.assignBoundsRecursive(child, childMin, childMax); + prevBound = childMax; + }, this); +}; + +GitVisuals.prototype.calcDepth = function() { + var maxDepth = this.calcDepthRecursive(this.rootCommit, 0); + if (maxDepth > 15) { + // issue warning + console.warn('graphics are degrading from too many layers'); + } + + var depthIncrement = this.getDepthIncrement(maxDepth); + _.each(this.visNodeMap, function(visNode) { + visNode.setDepthBasedOn(depthIncrement); + }, this); +}; + +/*************************************** + == END Tree Calculation == + _ __ __ _ + \\/ / \ \//_ + \ \ / __| __ + \ \___/ /_____/ / + | _______ \ + \ ( ) / \_\ + \ / + | | + | | + ____+-_=+-^ ^+-=_=__________ + +^^ I drew that :D + + **************************************/ + +GitVisuals.prototype.animateNodePositions = function(speed) { + _.each(this.visNodeMap, function(visNode) { + visNode.animateUpdatedPosition(speed); + }, this); +}; + +GitVisuals.prototype.turnOnPaper = function() { + this.gitReady = false; +}; + +// does making an accessor method make it any less hacky? that is the true question +GitVisuals.prototype.turnOffPaper = function() { + this.gitReady = true; +}; + +GitVisuals.prototype.addBranchFromEvent = function(branch, collection, index) { + var action = _.bind(function() { + this.addBranch(branch); + }, this); + + if (!this.gitEngine || !this.gitReady) { + this.defer(action); + } else { + action(); + } +}; + +GitVisuals.prototype.addBranch = function(branch) { + var visBranch = new VisBranch({ + branch: branch, + gitVisuals: this, + gitEngine: this.gitEngine + }); + + this.visBranchCollection.add(visBranch); + if (this.gitReady) { + visBranch.genGraphics(this.paper); + } +}; + +GitVisuals.prototype.removeVisBranch = function(visBranch) { + this.visBranchCollection.remove(visBranch); +}; + +GitVisuals.prototype.removeVisNode = function(visNode) { + this.visNodeMap[visNode.getID()] = undefined; +}; + +GitVisuals.prototype.removeVisEdge = function(visEdge) { + this.visEdgeCollection.remove(visEdge); +}; + +GitVisuals.prototype.animateRefs = function(speed) { + this.visBranchCollection.each(function(visBranch) { + visBranch.animateUpdatedPos(speed); + }, this); +}; + +GitVisuals.prototype.animateEdges = function(speed) { + this.visEdgeCollection.each(function(edge) { + edge.animateUpdatedPath(speed); + }, this); +}; + +GitVisuals.prototype.getDepthIncrement = function(maxDepth) { + // assume there are at least 7 layers until later + maxDepth = Math.max(maxDepth, 7); + var increment = 1.0 / maxDepth; + return increment; +}; + +GitVisuals.prototype.calcDepthRecursive = function(commit, depth) { + commit.get('visNode').setDepth(depth); + + var children = commit.get('children'); + var maxDepth = depth; + _.each(children, function(child) { + var d = this.calcDepthRecursive(child, depth + 1); + maxDepth = Math.max(d, maxDepth); + }, this); + + return maxDepth; +}; + +// we debounce here so we aren't firing a resize call on every resize event +// but only after they stop +GitVisuals.prototype.canvasResize = _.debounce(function(width, height) { + // refresh when we are ready + if (GLOBAL.isAnimating) { + this.events.trigger('processCommandFromEvent', 'refresh'); + } else { + this.refreshTree(); + } +}, 200); + +GitVisuals.prototype.addNode = function(id, commit) { + this.commitMap[id] = commit; + if (commit.get('rootCommit')) { + this.rootCommit = commit; + } + + var visNode = new VisNode({ + id: id, + commit: commit, + gitVisuals: this, + gitEngine: this.gitEngine + }); + this.visNodeMap[id] = visNode; + + if (this.gitReady) { + visNode.genGraphics(this.paper); + } + return visNode; +}; + +GitVisuals.prototype.addEdge = function(idTail, idHead) { + var visNodeTail = this.visNodeMap[idTail]; + var visNodeHead = this.visNodeMap[idHead]; + + if (!visNodeTail || !visNodeHead) { + throw new Error('one of the ids in (' + idTail + + ', ' + idHead + ') does not exist'); + } + + var edge = new VisEdge({ + tail: visNodeTail, + head: visNodeHead, + gitVisuals: this, + gitEngine: this.gitEngine + }); + this.visEdgeCollection.add(edge); + + if (this.gitReady) { + edge.genGraphics(this.paper); + } +}; + +GitVisuals.prototype.collectionChanged = function() { + // TODO ? +}; + +GitVisuals.prototype.zIndexReflow = function() { + this.visNodesFront(); + this.visBranchesFront(); +}; + +GitVisuals.prototype.visNodesFront = function() { + _.each(this.visNodeMap, function(visNode) { + visNode.toFront(); + }); +}; + +GitVisuals.prototype.visBranchesFront = function() { + this.visBranchCollection.each(function(vBranch) { + vBranch.nonTextToFront(); + }); + + this.visBranchCollection.each(function(vBranch) { + vBranch.textToFront(); + }); +}; + +GitVisuals.prototype.drawTreeFromReload = function() { + this.gitReady = true; + // gen all the graphics we need + this.deferFlush(); + + this.calcTreeCoords(); +}; + +GitVisuals.prototype.drawTreeFirstTime = function() { + this.gitReady = true; + this.calcTreeCoords(); + + _.each(this.visNodeMap, function(visNode) { + visNode.genGraphics(this.paper); + }, this); + + this.visEdgeCollection.each(function(edge) { + edge.genGraphics(this.paper); + }, this); + + this.visBranchCollection.each(function(visBranch) { + visBranch.genGraphics(this.paper); + }, this); + + this.zIndexReflow(); +}; + + +/************************ + * Random util functions, some from liquidGraph + ***********************/ +function blendHueStrings(hueStrings) { + // assumes a sat of 0.7 and brightness of 1 + + var x = 0; + var y = 0; + var totalSat = 0; + var totalBright = 0; + var length = hueStrings.length; + + _.each(hueStrings, function(hueString) { + var exploded = hueString.split('(')[1]; + exploded = exploded.split(')')[0]; + exploded = exploded.split(','); + + totalSat += parseFloat(exploded[1]); + totalBright += parseFloat(exploded[2]); + var hue = parseFloat(exploded[0]); + + var angle = hue * Math.PI * 2; + x += Math.cos(angle); + y += Math.sin(angle); + }); + + x = x / length; + y = y / length; + totalSat = totalSat / length; + totalBright = totalBright / length; + + var hue = Math.atan2(y, x) / (Math.PI * 2); // could fail on 0's + if (hue < 0) { + hue = hue + 1; + } + return 'hsb(' + String(hue) + ',' + String(totalSat) + ',' + String(totalBright) + ')'; +} + +exports.GitVisuals = GitVisuals; + }); require.define("/src/js/visuals/tree.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore'); @@ -10790,6 +10800,16 @@ var VisNode = VisBase.extend({ }, this); }, + finishAnimation: function() { + var circle = this.get('circle'); + + // decide on a speed + var speedMag = 10; + var angle = Math.random() * 2 * Math.PI; + var vx = speedMag * Math.cos(angle); + var vy = speedMap * Math.sin(angle); + }, + genGraphics: function() { var paper = this.gitVisuals.paper; @@ -11088,10 +11108,10 @@ var mainVis = null; /////////////////////////////////////////////////////////////////////// var init = function(){ - var Visuals = require('../visuals'); + var Visualization = require('../visuals/visualization').Visualization; ui = new UI(); - mainVis = new Visuals.Visualization({ + mainVis = new Visualization({ el: $('#canvasWrapper')[0] }); @@ -14100,7 +14120,6 @@ var InteractiveRebaseView = Backbone.View.extend({ }, toggleVisibility: function(toggle) { - console.log('toggling'); $('#dialogHolder').toggleClass('shown', toggle); }, @@ -14579,84 +14598,6 @@ var VisNode = Tree.VisNode; var VisBranch = Tree.VisBranch; var VisEdge = Tree.VisEdge; -var Visualization = Backbone.View.extend({ - initialize: function(options) { - var _this = this; - new Raphael(10, 10, 200, 200, function() { - - // for some reason raphael calls this function with a predefined - // context... - // so switch it - _this.paperInitialize(this, options); - }); - }, - - paperInitialize: function(paper, options) { - options = options || {}; - this.treeString = options.treeString; - this.paper = paper; - - var Main = require('../app'); - this.events = Main.getEvents(); - - this.commitCollection = new CommitCollection(); - this.branchCollection = new BranchCollection(); - - this.gitVisuals = new GitVisuals({ - commitCollection: this.commitCollection, - branchCollection: this.branchCollection, - paper: this.paper - }); - - var GitEngine = require('../git').GitEngine; - this.gitEngine = new GitEngine({ - collection: this.commitCollection, - branches: this.branchCollection, - gitVisuals: this.gitVisuals, - events: this.events - }); - this.gitEngine.init(); - this.gitVisuals.assignGitEngine(this.gitEngine); - - this.myResize(); - $(window).on('resize', _.bind(this.myResize, this)); - this.gitVisuals.drawTreeFirstTime(); - - if (this.treeString) { - this.gitEngine.loadTreeFromString(this.treeString); - } - - this.setTreeOpacity(0); - this.fadeTreeIn(); - }, - - setTreeOpacity: function(level) { - $(this.paper.canvas).css('opacity', 0); - }, - - fadeTreeIn: function() { - $(this.paper.canvas).animate({opacity: 1}, 300); - }, - - myResize: function() { - var smaller = 1; - var el = this.el; - - var left = el.offsetLeft; - var top = el.offsetTop; - var width = el.clientWidth - smaller; - var height = el.clientHeight - smaller; - - $(this.paper.canvas).css({ - left: left + 'px', - top: top + 'px' - }); - this.paper.setSize(width, height); - this.gitVisuals.canvasResize(width, height); - } - -}); - function GitVisuals(options) { this.commitCollection = options.commitCollection; this.branchCollection = options.branchCollection; @@ -14736,7 +14677,7 @@ GitVisuals.prototype.initHeadBranch = function() { this.addBranchFromEvent(this.gitEngine.HEAD); }; -GitVisuals.prototype.getScreenBounds = function() { +GitVisuals.prototype.getScreenPadding = function() { // for now we return the node radius subtracted from the walls return { widthPadding: GRAPHICS.nodeRadius * 1.5, @@ -14748,15 +14689,15 @@ GitVisuals.prototype.toScreenCoords = function(pos) { if (!this.paper.width) { throw new Error('being called too early for screen coords'); } - var bounds = this.getScreenBounds(); + var padding = this.getScreenPadding(); var shrink = function(frac, total, padding) { return padding + frac * (total - padding * 2); }; return { - x: shrink(pos.x, this.paper.width, bounds.widthPadding), - y: shrink(pos.y, this.paper.height, bounds.heightPadding) + x: shrink(pos.x, this.paper.width, padding.widthPadding), + y: shrink(pos.y, this.paper.height, padding.heightPadding) }; }; @@ -15263,10 +15204,8 @@ function blendHueStrings(hueStrings) { return 'hsb(' + String(hue) + ',' + String(totalSat) + ',' + String(totalBright) + ')'; } -exports.Visualization = Visualization; exports.GitVisuals = GitVisuals; - }); require("/src/js/visuals/index.js"); @@ -16022,6 +15961,16 @@ var VisNode = VisBase.extend({ }, this); }, + finishAnimation: function() { + var circle = this.get('circle'); + + // decide on a speed + var speedMag = 10; + var angle = Math.random() * 2 * Math.PI; + var vx = speedMag * Math.cos(angle); + var vy = speedMap * Math.sin(angle); + }, + genGraphics: function() { var paper = this.gitVisuals.paper; @@ -16238,4 +16187,96 @@ exports.VisBranch = VisBranch; }); require("/src/js/visuals/tree.js"); +require.define("/src/js/visuals/visualization.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore'); +// horrible hack to get localStorage Backbone plugin +var Backbone = (!require('../util').isBrowser()) ? Backbone = require('backbone') : Backbone = window.Backbone; + +var Collections = require('../models/collections'); +var CommitCollection = Collections.CommitCollection; +var BranchCollection = Collections.BranchCollection; + +var GitVisuals = require('../visuals').GitVisuals; + +var Visualization = Backbone.View.extend({ + initialize: function(options) { + var _this = this; + new Raphael(10, 10, 200, 200, function() { + + // for some reason raphael calls this function with a predefined + // context... + // so switch it + _this.paperInitialize(this, options); + }); + }, + + paperInitialize: function(paper, options) { + options = options || {}; + this.treeString = options.treeString; + this.paper = paper; + + var Main = require('../app'); + this.events = Main.getEvents(); + + this.commitCollection = new CommitCollection(); + this.branchCollection = new BranchCollection(); + + this.gitVisuals = new GitVisuals({ + commitCollection: this.commitCollection, + branchCollection: this.branchCollection, + paper: this.paper + }); + + var GitEngine = require('../git').GitEngine; + this.gitEngine = new GitEngine({ + collection: this.commitCollection, + branches: this.branchCollection, + gitVisuals: this.gitVisuals, + events: this.events + }); + this.gitEngine.init(); + this.gitVisuals.assignGitEngine(this.gitEngine); + + this.myResize(); + $(window).on('resize', _.bind(this.myResize, this)); + this.gitVisuals.drawTreeFirstTime(); + + if (this.treeString) { + this.gitEngine.loadTreeFromString(this.treeString); + } + + this.setTreeOpacity(0); + this.fadeTreeIn(); + }, + + setTreeOpacity: function(level) { + $(this.paper.canvas).css('opacity', 0); + }, + + fadeTreeIn: function() { + $(this.paper.canvas).animate({opacity: 1}, 300); + }, + + myResize: function() { + var smaller = 1; + var el = this.el; + + var left = el.offsetLeft; + var top = el.offsetTop; + var width = el.clientWidth - smaller; + var height = el.clientHeight - smaller; + + $(this.paper.canvas).css({ + left: left + 'px', + top: top + 'px' + }); + this.paper.setSize(width, height); + this.gitVisuals.canvasResize(width, height); + } +}); + +exports.Visualization = Visualization; + +}); +require("/src/js/visuals/visualization.js"); + })(); diff --git a/src/js/app/index.js b/src/js/app/index.js index d3f43a27..6c1660e6 100644 --- a/src/js/app/index.js +++ b/src/js/app/index.js @@ -11,10 +11,10 @@ var mainVis = null; /////////////////////////////////////////////////////////////////////// var init = function(){ - var Visuals = require('../visuals'); + var Visualization = require('../visuals/visualization').Visualization; ui = new UI(); - mainVis = new Visuals.Visualization({ + mainVis = new Visualization({ el: $('#canvasWrapper')[0] }); diff --git a/src/js/views/miscViews.js b/src/js/views/miscViews.js index b755e5a4..170aa194 100644 --- a/src/js/views/miscViews.js +++ b/src/js/views/miscViews.js @@ -44,7 +44,6 @@ var InteractiveRebaseView = Backbone.View.extend({ }, toggleVisibility: function(toggle) { - console.log('toggling'); $('#dialogHolder').toggleClass('shown', toggle); }, diff --git a/src/js/visuals/index.js b/src/js/visuals/index.js index 762ad2a9..804f84e9 100644 --- a/src/js/visuals/index.js +++ b/src/js/visuals/index.js @@ -16,84 +16,6 @@ var VisNode = Tree.VisNode; var VisBranch = Tree.VisBranch; var VisEdge = Tree.VisEdge; -var Visualization = Backbone.View.extend({ - initialize: function(options) { - var _this = this; - new Raphael(10, 10, 200, 200, function() { - - // for some reason raphael calls this function with a predefined - // context... - // so switch it - _this.paperInitialize(this, options); - }); - }, - - paperInitialize: function(paper, options) { - options = options || {}; - this.treeString = options.treeString; - this.paper = paper; - - var Main = require('../app'); - this.events = Main.getEvents(); - - this.commitCollection = new CommitCollection(); - this.branchCollection = new BranchCollection(); - - this.gitVisuals = new GitVisuals({ - commitCollection: this.commitCollection, - branchCollection: this.branchCollection, - paper: this.paper - }); - - var GitEngine = require('../git').GitEngine; - this.gitEngine = new GitEngine({ - collection: this.commitCollection, - branches: this.branchCollection, - gitVisuals: this.gitVisuals, - events: this.events - }); - this.gitEngine.init(); - this.gitVisuals.assignGitEngine(this.gitEngine); - - this.myResize(); - $(window).on('resize', _.bind(this.myResize, this)); - this.gitVisuals.drawTreeFirstTime(); - - if (this.treeString) { - this.gitEngine.loadTreeFromString(this.treeString); - } - - this.setTreeOpacity(0); - this.fadeTreeIn(); - }, - - setTreeOpacity: function(level) { - $(this.paper.canvas).css('opacity', 0); - }, - - fadeTreeIn: function() { - $(this.paper.canvas).animate({opacity: 1}, 300); - }, - - myResize: function() { - var smaller = 1; - var el = this.el; - - var left = el.offsetLeft; - var top = el.offsetTop; - var width = el.clientWidth - smaller; - var height = el.clientHeight - smaller; - - $(this.paper.canvas).css({ - left: left + 'px', - top: top + 'px' - }); - this.paper.setSize(width, height); - this.gitVisuals.canvasResize(width, height); - } - -}); - function GitVisuals(options) { this.commitCollection = options.commitCollection; this.branchCollection = options.branchCollection; @@ -173,7 +95,7 @@ GitVisuals.prototype.initHeadBranch = function() { this.addBranchFromEvent(this.gitEngine.HEAD); }; -GitVisuals.prototype.getScreenBounds = function() { +GitVisuals.prototype.getScreenPadding = function() { // for now we return the node radius subtracted from the walls return { widthPadding: GRAPHICS.nodeRadius * 1.5, @@ -185,15 +107,15 @@ GitVisuals.prototype.toScreenCoords = function(pos) { if (!this.paper.width) { throw new Error('being called too early for screen coords'); } - var bounds = this.getScreenBounds(); + var padding = this.getScreenPadding(); var shrink = function(frac, total, padding) { return padding + frac * (total - padding * 2); }; return { - x: shrink(pos.x, this.paper.width, bounds.widthPadding), - y: shrink(pos.y, this.paper.height, bounds.heightPadding) + x: shrink(pos.x, this.paper.width, padding.widthPadding), + y: shrink(pos.y, this.paper.height, padding.heightPadding) }; }; @@ -700,6 +622,4 @@ function blendHueStrings(hueStrings) { return 'hsb(' + String(hue) + ',' + String(totalSat) + ',' + String(totalBright) + ')'; } -exports.Visualization = Visualization; exports.GitVisuals = GitVisuals; - diff --git a/src/js/visuals/tree.js b/src/js/visuals/tree.js index 5583587b..f82759a8 100644 --- a/src/js/visuals/tree.js +++ b/src/js/visuals/tree.js @@ -750,6 +750,16 @@ var VisNode = VisBase.extend({ }, this); }, + finishAnimation: function() { + var circle = this.get('circle'); + + // decide on a speed + var speedMag = 10; + var angle = Math.random() * 2 * Math.PI; + var vx = speedMag * Math.cos(angle); + var vy = speedMap * Math.sin(angle); + }, + genGraphics: function() { var paper = this.gitVisuals.paper; diff --git a/todo.txt b/todo.txt index 30b5affa..6f266c06 100644 --- a/todo.txt +++ b/todo.txt @@ -10,6 +10,10 @@ Big Graphic things: Medium things: ~~~~~~~~~~~~~~~~~~~~~~~~~~~ [ ] level finish animation +[ ] check animations +[ ] view for anything above the fold +[ ] rebase styling (get it better. even cuter -- make it like a command window) +[ ] fix multiple rebases Small things to implement: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -29,6 +33,7 @@ Big Bugs to fix: Done things: (I only started this on Dec 17th 2012 to get a better sense of what was done) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +[x] refactor visualization [x] aliases replace when put into commands [x] headless Git for testing (send it commands and expected trees) [x] few tests