mirror of
https://github.com/pcottle/learnGitBranching.git
synced 2025-07-16 09:34:28 +02:00
big design update, bugs, etc
This commit is contained in:
parent
ff4312ba49
commit
9378254f0a
8 changed files with 259 additions and 17 deletions
|
@ -21,12 +21,13 @@ var Animation = Backbone.Model.extend({
|
||||||
|
|
||||||
var AnimationQueue = Backbone.Model.extend({
|
var AnimationQueue = Backbone.Model.extend({
|
||||||
defaults: {
|
defaults: {
|
||||||
animations: [],
|
animations: null,
|
||||||
index: 0,
|
index: 0,
|
||||||
callback: null
|
callback: null
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize: function(options) {
|
initialize: function(options) {
|
||||||
|
this.set('animations', []);
|
||||||
if (!options.callback) {
|
if (!options.callback) {
|
||||||
console.warn('no callback');
|
console.warn('no callback');
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,6 @@ var CommandView = Backbone.View.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
wasChanged: function(model, changeEvent) {
|
wasChanged: function(model, changeEvent) {
|
||||||
console.log('command changed', model, changeEvent);
|
|
||||||
// for changes that are just comestic, we actually only want to toggle classes
|
// for changes that are just comestic, we actually only want to toggle classes
|
||||||
// with jquery rather than brutally delete a html of HTML
|
// with jquery rather than brutally delete a html of HTML
|
||||||
var changes = changeEvent.changes;
|
var changes = changeEvent.changes;
|
||||||
|
|
|
@ -13,6 +13,10 @@ var TIME = {
|
||||||
reflowGuess: 100
|
reflowGuess: 100
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var GRAPHICS = {
|
||||||
|
nodeRadius: 15
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Graphics style
|
* Graphics style
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -816,7 +816,7 @@ var Commit = Backbone.Model.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
addNodeToVisuals: function() {
|
addNodeToVisuals: function() {
|
||||||
var visNode = gitVisuals.addNode(this.get('id'));
|
var visNode = gitVisuals.addNode(this.get('id'), this);
|
||||||
this.set('visNode', visNode);
|
this.set('visNode', visNode);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
17
src/main.js
17
src/main.js
|
@ -40,7 +40,12 @@ $(document).ready(function(){
|
||||||
$('#commandTextField').focus();
|
$('#commandTextField').focus();
|
||||||
|
|
||||||
// make the canvas for us
|
// make the canvas for us
|
||||||
paper = Raphael(10, 10, 200, 200);
|
Raphael(10, 10, 200, 200, function() {
|
||||||
|
paper = this;
|
||||||
|
// needs to be called before raphael ready
|
||||||
|
windowResize();
|
||||||
|
events.trigger('raphaelReady');
|
||||||
|
});
|
||||||
|
|
||||||
$(window).resize(windowResize);
|
$(window).resize(windowResize);
|
||||||
windowResize();
|
windowResize();
|
||||||
|
@ -48,19 +53,23 @@ $(document).ready(function(){
|
||||||
});
|
});
|
||||||
|
|
||||||
function windowResize() {
|
function windowResize() {
|
||||||
|
var smaller = 10;
|
||||||
|
|
||||||
if (paper && paper.canvas) {
|
if (paper && paper.canvas) {
|
||||||
var el = $('#canvasWrapper')[0];
|
var el = $('#canvasWrapper')[0];
|
||||||
|
|
||||||
var left = el.offsetLeft;
|
var left = el.offsetLeft;
|
||||||
var top = el.offsetTop;
|
var top = el.offsetTop;
|
||||||
var width = el.clientWidth;
|
var width = el.clientWidth - smaller;
|
||||||
var height = el.clientHeight;
|
var height = el.clientHeight - smaller;
|
||||||
|
|
||||||
|
console.log('setting to', left, top, width, height);
|
||||||
$(paper.canvas).css({
|
$(paper.canvas).css({
|
||||||
left: left + 'px',
|
left: left + 'px',
|
||||||
top: top + 'px'
|
top: top + 'px'
|
||||||
});
|
});
|
||||||
paper.setSize(width, height);
|
paper.setSize(width, height);
|
||||||
|
events.trigger('canvasResize', width, height);
|
||||||
}
|
}
|
||||||
events.trigger('windowResize');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,8 @@ div.horizontal {
|
||||||
}
|
}
|
||||||
|
|
||||||
#canvasWrapper {
|
#canvasWrapper {
|
||||||
box-shadow: 0px 0px 3px black inset;
|
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.8) inset;
|
||||||
|
background-color: #4183C4;
|
||||||
}
|
}
|
||||||
|
|
||||||
#interfaceWrapper {
|
#interfaceWrapper {
|
||||||
|
@ -84,7 +85,8 @@ div.horizontal {
|
||||||
|
|
||||||
#controls {
|
#controls {
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
background: #4183C4;
|
/* background: #4183C4; */
|
||||||
|
background: #EEE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#canvasWrapper {
|
#canvasWrapper {
|
||||||
|
|
73
src/tree.js
73
src/tree.js
|
@ -1,5 +1,78 @@
|
||||||
var VisNode = Backbone.Model.extend({
|
var VisNode = Backbone.Model.extend({
|
||||||
|
defaults: {
|
||||||
|
id: null,
|
||||||
|
pos: null,
|
||||||
|
commit: null
|
||||||
|
},
|
||||||
|
|
||||||
|
validateAtInit: function() {
|
||||||
|
if (!this.get('id')) {
|
||||||
|
throw new Error('need id for mapping');
|
||||||
|
}
|
||||||
|
if (!this.get('commit')) {
|
||||||
|
throw new Error('need commit for linking');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.get('pos')) {
|
||||||
|
this.set('pos', {
|
||||||
|
x: Math.random(),
|
||||||
|
y: Math.random(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize: function() {
|
||||||
|
this.validateAtInit();
|
||||||
|
},
|
||||||
|
|
||||||
|
calcPositionInTree: function() {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
getScreenCoords: function() {
|
||||||
|
var pos = this.get('pos');
|
||||||
|
return gitVisuals.toScreenCoords(pos);
|
||||||
|
},
|
||||||
|
|
||||||
|
genGraphics: function(paper) {
|
||||||
|
var pos = this.getScreenCoords();
|
||||||
|
//var circle = paper.circle(pos.x, pos.y, GRAPHICS.nodeRadius);
|
||||||
|
var circle = cuteSmallCircle(paper, pos.x, pos.y, {
|
||||||
|
radius: GRAPHICS.nodeRadius
|
||||||
|
});
|
||||||
|
this.set('circle', circle);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var VisEdge = Backbone.Model.extend({
|
var VisEdge = Backbone.Model.extend({
|
||||||
|
defaults: {
|
||||||
|
tail: null,
|
||||||
|
head: null
|
||||||
|
},
|
||||||
|
|
||||||
|
validateAtInit: function() {
|
||||||
|
required = ['tail', 'head'];
|
||||||
|
_.each(required, function(key) {
|
||||||
|
if (!this.get(key)) {
|
||||||
|
throw new Error(key + ' is required!');
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize: function() {
|
||||||
|
this.validateAtInit();
|
||||||
|
},
|
||||||
|
|
||||||
|
genGraphics: function(paper) {
|
||||||
|
var tailPos = this.get('tail').getScreenCoords();
|
||||||
|
var headPos = this.get('head').getScreenCoords();
|
||||||
|
var pathString = constructPathStringFromCoords([tailPos, headPos]);
|
||||||
|
var path = cutePath(paper, pathString);
|
||||||
|
this.set('path', path);
|
||||||
|
},
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
var VisEdgeCollection = Backbone.Collection.extend({
|
||||||
|
model: VisEdge
|
||||||
});
|
});
|
||||||
|
|
170
src/visuals.js
170
src/visuals.js
|
@ -1,22 +1,80 @@
|
||||||
function GitVisuals(options) {
|
function GitVisuals(options) {
|
||||||
this.collection = options.collection;
|
// the
|
||||||
this.nodeMap = {};
|
this.commitCollection = options.collection;
|
||||||
|
this.visNodeMap = {};
|
||||||
|
this.edgeCollection = new VisEdgeCollection();
|
||||||
|
|
||||||
this.collection.on('change', _.bind(this.collectionChanged, this));
|
this.commitMap = {};
|
||||||
|
this.rootCommit = null;
|
||||||
|
|
||||||
|
this.paperReady = false;
|
||||||
|
this.paperWidth = null;
|
||||||
|
this.paperHeight = null;
|
||||||
|
|
||||||
|
this.commitCollection.on('change', this.collectionChanged, this);
|
||||||
|
|
||||||
|
events.on('canvasResize', _.bind(
|
||||||
|
this.canvasResize, this
|
||||||
|
));
|
||||||
|
events.on('raphaelReady', _.bind(
|
||||||
|
this.drawTreeFirstTime, this
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
GitVisuals.prototype.addNode = function(id) {
|
GitVisuals.prototype.getScreenBounds = function() {
|
||||||
|
// for now we return the node radius subtracted from the walls
|
||||||
|
return {
|
||||||
|
minWidth: GRAPHICS.nodeRadius,
|
||||||
|
widthSubtract: GRAPHICS.nodeRadius,
|
||||||
|
minHeight: GRAPHICS.nodeRadius,
|
||||||
|
heightSubtract: GRAPHICS.nodeRadius
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
GitVisuals.prototype.toScreenCoords = function(pos) {
|
||||||
|
if (!this.paperWidth) {
|
||||||
|
throw new Error('being called too early for screen coords');
|
||||||
|
}
|
||||||
|
var bounds = this.getScreenBounds();
|
||||||
|
|
||||||
|
return {
|
||||||
|
x: pos.x * (this.paperWidth - bounds.widthSubtract) + bounds.minWidth,
|
||||||
|
y: pos.y * (this.paperHeight - bounds.heightSubtract) + bounds.minHeight,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
GitVisuals.prototype.calculateTreeCoords = function() {
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
GitVisuals.prototype.canvasResize = function(width, height) {
|
||||||
|
this.paperWidth = width;
|
||||||
|
this.paperHeight = height;
|
||||||
|
};
|
||||||
|
|
||||||
|
GitVisuals.prototype.addNode = function(id, commit) {
|
||||||
|
this.commitMap[id] = commit;
|
||||||
|
if (commit.get('roomCommit')) {
|
||||||
|
this.rootCommit = commit;
|
||||||
|
}
|
||||||
|
|
||||||
var visNode = new VisNode({
|
var visNode = new VisNode({
|
||||||
id: id
|
id: id,
|
||||||
|
commit: commit
|
||||||
});
|
});
|
||||||
this.nodeMap[id] = visNode;
|
this.visNodeMap[id] = visNode;
|
||||||
|
|
||||||
|
if (this.paperReady) {
|
||||||
|
visNode.genGraphics(paper);
|
||||||
|
}
|
||||||
|
|
||||||
return visNode;
|
return visNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
GitVisuals.prototype.addEdge = function(idTail, idHead) {
|
GitVisuals.prototype.addEdge = function(idTail, idHead) {
|
||||||
var visNodeTail = this.nodeMap[idTail];
|
var visNodeTail = this.visNodeMap[idTail];
|
||||||
var visNodeHead = this.nodeMap[idHead];
|
var visNodeHead = this.visNodeMap[idHead];
|
||||||
|
|
||||||
if (!visNodeTail || !visNodeHead) {
|
if (!visNodeTail || !visNodeHead) {
|
||||||
throw new Error('one of the ids in (' + idTail +
|
throw new Error('one of the ids in (' + idTail +
|
||||||
|
@ -27,9 +85,105 @@ GitVisuals.prototype.addEdge = function(idTail, idHead) {
|
||||||
tail: visNodeTail,
|
tail: visNodeTail,
|
||||||
head: visNodeHead
|
head: visNodeHead
|
||||||
});
|
});
|
||||||
|
this.edgeCollection.add(edge);
|
||||||
|
|
||||||
|
if (this.paperReady) {
|
||||||
|
edge.genGraphics(paper);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
GitVisuals.prototype.collectionChanged = function() {
|
GitVisuals.prototype.collectionChanged = function() {
|
||||||
|
console.log('git visuals... collection was changed');
|
||||||
// redo stuff
|
// redo stuff
|
||||||
};
|
};
|
||||||
|
|
||||||
|
GitVisuals.prototype.drawTreeFirstTime = function() {
|
||||||
|
this.calculateTreeCoords();
|
||||||
|
this.paperReady = true;
|
||||||
|
_.each(this.visNodeMap, function(visNode) {
|
||||||
|
visNode.genGraphics(paper);
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.edgeCollection.each(function(edge) {
|
||||||
|
edge.genGraphics(paper);
|
||||||
|
}, this);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/************************
|
||||||
|
* Random util functions, adapted from liquidGraph
|
||||||
|
***********************/
|
||||||
|
function constructPathStringFromCoords(points,wantsToClose) {
|
||||||
|
var pathString = "M" + String(Math.round(points[0].x)) + "," + String(Math.round(points[0].y));
|
||||||
|
var lp = points[0];
|
||||||
|
|
||||||
|
_.each(points, function(point) {
|
||||||
|
var s = " L" + String(Math.round(point.x)) + "," + String(Math.round(point.y));
|
||||||
|
pathString = pathString + s;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (wantsToClose) {
|
||||||
|
pathString = pathString + " Z";
|
||||||
|
}
|
||||||
|
return pathString;
|
||||||
|
};
|
||||||
|
|
||||||
|
function randomHueString() {
|
||||||
|
var hue = Math.random();
|
||||||
|
var str = 'hsb(' + String(hue) + ',0.7,1)';
|
||||||
|
return str;
|
||||||
|
};
|
||||||
|
|
||||||
|
function randomGradient() {
|
||||||
|
var hue = Math.random()*0.8;
|
||||||
|
var color1 = 'hsb(' + String(hue) + ',0.7,1)';
|
||||||
|
var color2 = 'hsb(' + String(hue + 0.2) + ',0.9,1)';
|
||||||
|
|
||||||
|
var gradient = String(Math.round(Math.random()*180)) + '-' + color1 + '-' + color2;
|
||||||
|
return gradient;
|
||||||
|
};
|
||||||
|
|
||||||
|
function cutePath(paper, pathString, options) {
|
||||||
|
options = options || {};
|
||||||
|
var wantsToFill = options.wantsToFill;
|
||||||
|
var strokeColor = options.strokeColor;
|
||||||
|
var fillColor = options.fillColor;
|
||||||
|
|
||||||
|
var path = paper.path(pathString);
|
||||||
|
|
||||||
|
if (!strokeColor) {
|
||||||
|
strokeColor = randomHueString();
|
||||||
|
}
|
||||||
|
if (!fillColor) {
|
||||||
|
fillColor = randomHueString();
|
||||||
|
}
|
||||||
|
path.attr({
|
||||||
|
'stroke-width': 2,
|
||||||
|
'stroke': strokeColor,
|
||||||
|
'stroke-linecap': 'round',
|
||||||
|
'stroke-linejoin': 'round'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (wantsToFill) {
|
||||||
|
path.attr('fill',fillColor);
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
};
|
||||||
|
|
||||||
|
function cuteSmallCircle(paper, x, y, options) {
|
||||||
|
var options = options || {};
|
||||||
|
var wantsSameColor = options.sameColor;
|
||||||
|
var radius = options.radius || 4;
|
||||||
|
|
||||||
|
var c = paper.circle(x, y, radius, radius);
|
||||||
|
if (!wantsSameColor) {
|
||||||
|
c.attr("fill","hsba(0.5,0.8,0.7,1)");
|
||||||
|
} else {
|
||||||
|
c.attr("fill","hsba(" + String(Math.random()) + ",0.8,0.7,1)");
|
||||||
|
}
|
||||||
|
|
||||||
|
c.attr("stroke","#FFF");
|
||||||
|
c.attr("stroke-width",2);
|
||||||
|
return c;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue