much better

This commit is contained in:
Peter Cottle 2012-12-19 11:09:32 -08:00
parent 8280f4379d
commit 9bdcedae12
5 changed files with 597 additions and 590 deletions

View file

@ -1,15 +1,6 @@
var _ = require('underscore');
// horrible hack to get localStorage Backbone plugin
var Backbone = require('backbone');
var GRAPHICS = require('../util/constants').GRAPHICS;
var randomHueString = function() {
var hue = Math.random();
var str = 'hsb(' + String(hue) + ',0.7,1)';
return str;
};
var VisBase = Backbone.Model.extend({
removeKeys: function(keys) {
_.each(keys, function(key) {
@ -20,181 +11,4 @@ var VisBase = Backbone.Model.extend({
}
});
var VisEdge = VisBase.extend({
defaults: {
tail: null,
head: null,
animationSpeed: GRAPHICS.defaultAnimationTime,
animationEasing: GRAPHICS.defaultEasing
},
validateAtInit: function() {
var required = ['tail', 'head'];
_.each(required, function(key) {
if (!this.get(key)) {
throw new Error(key + ' is required!');
}
}, this);
},
getID: function() {
return this.get('tail').get('id') + '.' + this.get('head').get('id');
},
initialize: function() {
this.validateAtInit();
// shorthand for the main objects
this.gitVisuals = this.get('gitVisuals');
this.gitEngine = this.get('gitEngine');
this.get('tail').get('outgoingEdges').push(this);
},
remove: function() {
this.removeKeys(['path']);
this.gitVisuals.removeVisEdge(this);
},
genSmoothBezierPathString: function(tail, head) {
var tailPos = tail.getScreenCoords();
var headPos = head.getScreenCoords();
return this.genSmoothBezierPathStringFromCoords(tailPos, headPos);
},
genSmoothBezierPathStringFromCoords: function(tailPos, headPos) {
// we need to generate the path and control points for the bezier. format
// is M(move abs) C (curve to) (control point 1) (control point 2) (final point)
// the control points have to be __below__ to get the curve starting off straight.
var coords = function(pos) {
return String(Math.round(pos.x)) + ',' + String(Math.round(pos.y));
};
var offset = function(pos, dir, delta) {
delta = delta || GRAPHICS.curveControlPointOffset;
return {
x: pos.x,
y: pos.y + delta * dir
};
};
var offset2d = function(pos, x, y) {
return {
x: pos.x + x,
y: pos.y + y
};
};
// first offset tail and head by radii
tailPos = offset(tailPos, -1, this.get('tail').getRadius());
headPos = offset(headPos, 1, this.get('head').getRadius());
var str = '';
// first move to bottom of tail
str += 'M' + coords(tailPos) + ' ';
// start bezier
str += 'C';
// then control points above tail and below head
str += coords(offset(tailPos, -1)) + ' ';
str += coords(offset(headPos, 1)) + ' ';
// now finish
str += coords(headPos);
// arrow head
var delta = GRAPHICS.arrowHeadSize || 10;
str += ' L' + coords(offset2d(headPos, -delta, delta));
str += ' L' + coords(offset2d(headPos, delta, delta));
str += ' L' + coords(headPos);
// then go back, so we can fill correctly
str += 'C';
str += coords(offset(headPos, 1)) + ' ';
str += coords(offset(tailPos, -1)) + ' ';
str += coords(tailPos);
return str;
},
getBezierCurve: function() {
return this.genSmoothBezierPathString(this.get('tail'), this.get('head'));
},
getStrokeColor: function() {
return GRAPHICS.visBranchStrokeColorNone;
},
setOpacity: function(opacity) {
opacity = (opacity === undefined) ? 1 : opacity;
this.get('path').attr({opacity: opacity});
},
genGraphics: function(paper) {
var pathString = this.getBezierCurve();
var path = paper.path(pathString).attr({
'stroke-width': GRAPHICS.visBranchStrokeWidth,
'stroke': this.getStrokeColor(),
'stroke-linecap': 'round',
'stroke-linejoin': 'round',
'fill': this.getStrokeColor()
});
path.toBack();
this.set('path', path);
},
getOpacity: function() {
var stat = this.gitVisuals.getCommitUpstreamStatus(this.get('tail'));
var map = {
'branch': 1,
'head': GRAPHICS.edgeUpstreamHeadOpacity,
'none': GRAPHICS.edgeUpstreamNoneOpacity
};
if (map[stat] === undefined) { throw new Error('bad stat'); }
return map[stat];
},
getAttributes: function() {
var newPath = this.getBezierCurve();
var opacity = this.getOpacity();
return {
path: {
path: newPath,
opacity: opacity
}
};
},
animateUpdatedPath: function(speed, easing) {
var attr = this.getAttributes();
this.animateToAttr(attr, speed, easing);
},
animateFromAttrToAttr: function(fromAttr, toAttr, speed, easing) {
// an animation of 0 is essentially setting the attribute directly
this.animateToAttr(fromAttr, 0);
this.animateToAttr(toAttr, speed, easing);
},
animateToAttr: function(attr, speed, easing) {
if (speed === 0) {
this.get('path').attr(attr.path);
return;
}
this.get('path').toBack();
this.get('path').stop().animate(
attr.path,
speed !== undefined ? speed : this.get('animationSpeed'),
easing || this.get('animationEasing')
);
}
});
var VisEdgeCollection = Backbone.Collection.extend({
model: VisEdge
});
exports.VisEdgeCollection = VisEdgeCollection;
exports.VisEdge = VisEdge;
exports.VisBase = VisBase;