pcottle.learnGitBranching/src/js/visuals/visualization.js
2013-05-26 15:18:36 -07:00

207 lines
5.6 KiB
JavaScript

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 EventBaton = require('../util/eventBaton').EventBaton;
var GitVisuals = require('../visuals').GitVisuals;
var Visualization = Backbone.View.extend({
initialize: function(options) {
options = options || {};
this.options = options;
this.customEvents = _.clone(Backbone.Events);
this.containerElement = options.containerElement;
var _this = this;
// we want to add our canvas somewhere
var container = options.containerElement || $('#canvasHolder')[0];
new Raphael(container, 200, 200, function() {
// raphael calls with paper as this for some inane reason...
var paper = this;
// use process.nextTick to go from sync to async
process.nextTick(function() {
_this.paperInitialize(paper, options);
});
});
},
paperInitialize: function(paper, options) {
this.treeString = options.treeString;
this.paper = paper;
var Main = require('../app');
// if we dont want to receive keyoard input (directly),
// make a new event baton so git engine steals something that no one
// is broadcasting to
this.eventBaton = (options.noKeyboardInput) ?
new EventBaton():
Main.getEventBaton();
this.commitCollection = new CommitCollection();
this.branchCollection = new BranchCollection();
this.gitVisuals = new GitVisuals({
commitCollection: this.commitCollection,
branchCollection: this.branchCollection,
paper: this.paper,
noClick: this.options.noClick,
smallCanvas: this.options.smallCanvas,
visualization: this
});
var GitEngine = require('../git').GitEngine;
this.gitEngine = new GitEngine({
collection: this.commitCollection,
branches: this.branchCollection,
gitVisuals: this.gitVisuals,
eventBaton: this.eventBaton
});
this.gitEngine.init();
this.gitVisuals.assignGitEngine(this.gitEngine);
this.myResize();
$(window).on('resize', _.bind(function() {
this.myResize();
}, this));
this.gitVisuals.drawTreeFirstTime();
if (this.treeString) {
this.gitEngine.loadTreeFromString(this.treeString);
}
if (this.options.zIndex) {
this.setTreeIndex(this.options.zIndex);
}
this.shown = false;
this.setTreeOpacity(0);
// reflow needed
process.nextTick(_.bind(this.fadeTreeIn, this));
this.customEvents.trigger('gitEngineReady');
this.customEvents.trigger('paperReady');
},
makeOrigin: function(options) {
// oh god, here we go. We basically do a bizarre form of composition here,
// where this visualization actually contains another one of itself.
this.originVis = new Visualization(_.extend(
{},
// copy all of our options over, except...
this.options,
{
// never accept keyboard input or clicks
noKeyboardInput: true,
noClick: true,
treeString: JSON.stringify(options.tree)
}
));
// return the newly created gitEngine
return this.originVis.gitEngine;
},
setTreeIndex: function(level) {
$(this.paper.canvas).css('z-index', level);
},
setTreeOpacity: function(level) {
if (level === 0) {
this.shown = false;
}
$(this.paper.canvas).css('opacity', level);
},
getAnimationTime: function() { return 300; },
fadeTreeIn: function() {
this.shown = true;
$(this.paper.canvas).animate({opacity: 1}, this.getAnimationTime());
},
fadeTreeOut: function() {
this.shown = false;
$(this.paper.canvas).animate({opacity: 0}, this.getAnimationTime());
},
hide: function() {
this.fadeTreeOut();
// remove click handlers by toggling visibility
setTimeout(_.bind(function() {
$(this.paper.canvas).css('visibility', 'hidden');
}, this), this.getAnimationTime());
},
show: function() {
$(this.paper.canvas).css('visibility', 'visible');
setTimeout(_.bind(this.fadeTreeIn, this), 10);
},
showHarsh: function() {
$(this.paper.canvas).css('visibility', 'visible');
this.setTreeOpacity(1);
},
resetFromThisTreeNow: function(treeString) {
this.treeString = treeString;
},
reset: function(tree) {
var treeString = tree || this.treeString;
this.setTreeOpacity(0);
if (this.treeString) {
this.gitEngine.loadTreeFromString(treeString);
} else {
this.gitEngine.defaultInit();
}
this.fadeTreeIn();
},
tearDown: function() {
this.gitEngine.tearDown();
this.gitVisuals.tearDown();
delete this.paper;
},
die: function() {
this.fadeTreeOut();
setTimeout(_.bind(function() {
if (!this.shown) {
this.tearDown();
}
}, this), this.getAnimationTime());
},
myResize: function() {
if (!this.paper) { return; }
var smaller = 1;
var el = this.el;
var width = el.clientWidth - smaller;
var height = el.clientHeight - smaller;
// if we don't have a container, we need to set our
// position absolutely to whatever we are tracking
if (!this.containerElement) {
var left = el.offsetLeft;
var top = el.offsetTop;
$(this.paper.canvas).css({
position: 'absolute',
left: left + 'px',
top: top + 'px'
});
}
this.paper.setSize(width, height);
this.gitVisuals.canvasResize(width, height);
}
});
exports.Visualization = Visualization;