Skip to content

Commit

Permalink
editor: add focusNode() method
Browse files Browse the repository at this point in the history
This adds Google Maps like animation on focus a given node.
  • Loading branch information
djdeath committed Sep 14, 2014
1 parent 2656c86 commit c7dabd7
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 4 deletions.
3 changes: 2 additions & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"hammerjs": "~1.1.2",
"font-awesome": "~4.1.0",
"react": "~0.11.1",
"klay-js": "~0.1.0"
"klay-js": "~0.1.0",
"react.animate-djdeath": "0bf7a359ac847ebd540d78843728f87433a67179"
},
"license": "MIT",
"ignore": [
Expand Down
6 changes: 4 additions & 2 deletions the-graph-editor/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@

<!-- Bower Libraries -->
<script src="../bower_components/platform/platform.js"></script>
<script src="../bower_components/react/react.js"></script>
<script src="../bower_components/react/react-with-addons.js"></script>
<script src="../bower_components/klay-js/klay.js"></script>
<script src="../bower_components/hammerjs/hammer.min.js"></script>
<script src="../bower_components/ease-djdeath/index.js"></script>
<script src="../bower_components/react.animate-djdeath/react.animate.js"></script>

<!-- Browserify Libraries -->
<script src="../build/noflo.js"></script>

<!-- Custom elements -->
<link rel="import" href="../bower_components/polymer/polymer.html">
<!-- <link rel="import" href="../bower_components/polymer-gestures/polymer-gestures.html"> -->
Expand Down
3 changes: 3 additions & 0 deletions the-graph-editor/the-graph-editor.html
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,9 @@
updateErrorNodes: function () {
this.$.graph.errorNodesChanged();
},
focusNode: function (node) {
this.$.graph.focusNode(node);
},
getComponent: function (name) {
return this.$.graph.getComponent(name);
},
Expand Down
38 changes: 37 additions & 1 deletion the-graph/the-graph-app.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
}

TheGraph.App = React.createClass({
mixins: [React.Animate],
minZoom: 0.15,
getInitialState: function() {
// Autofit
Expand All @@ -80,7 +81,8 @@
tooltipY: 0,
tooltipVisible: false,
contextElement: null,
contextType: null
contextType: null,
focusAnimationDuration: 1000
};
},
zoomFactor: 0,
Expand Down Expand Up @@ -256,6 +258,40 @@
scale: fit.scale
});
},
focusNode: function (node) {
var duration = this.state.focusAnimationDuration;
var fit = TheGraph.findNodeFit(node,
this.state.width,
this.state.height);
var start_point = {
x: -(this.state.x - this.state.width / 2) / this.state.scale,
y: -(this.state.y - this.state.height / 2) / this.state.scale,
}, end_point = {
x: node.metadata.x,
y: node.metadata.y,
};
var graphfit = TheGraph.findAreaFit(start_point,
end_point,
this.state.width,
this.state.height);

var scale_ratio_1 = Math.abs(graphfit.scale - this.state.scale);
var scale_ratio_2 = Math.abs(fit.scale - graphfit.scale);
var scale_ratio_diff = scale_ratio_1 + scale_ratio_2;

// Animate zoom-out then zoom-in
this.animate({
x: graphfit.x,
y: graphfit.y,
scale: graphfit.scale,
}, duration * (scale_ratio_1 / scale_ratio_diff), 'in-quint', function() {
this.animate({
x: fit.x,
y: fit.y,
scale: fit.scale,
}, duration * (scale_ratio_2 / scale_ratio_diff), 'out-quint');
}.bind(this));
},
edgeStart: function (event) {
// Listened from PortMenu.edgeStart() and Port.edgeStart()
this.refs.graph.edgeStart(event);
Expand Down
3 changes: 3 additions & 0 deletions the-graph/the-graph.html
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,9 @@
forceSelection: this.forceSelection
});
},
focusNode: function (node) {
this.appView.focusNode(node);
},
menusChanged: function () {
// Only if the object itself changes,
// otherwise builds menu from reference every time menu shown
Expand Down
69 changes: 69 additions & 0 deletions the-graph/the-graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,75 @@
};
};

TheGraph.findAreaFit = function (point1, point2, width, height) {
var limits = {
minX: point1.x < point2.x ? point1.x : point2.x,
minY: point1.y < point2.y ? point1.y : point2.y,
maxX: point1.x > point2.x ? point1.x : point2.x,
maxY: point1.y > point2.y ? point1.y : point2.y
};

limits.minX -= TheGraph.config.nodeSize;
limits.minY -= TheGraph.config.nodeSize;
limits.maxX += TheGraph.config.nodeSize * 2;
limits.maxY += TheGraph.config.nodeSize * 2;

var gWidth = limits.maxX - limits.minX;
var gHeight = limits.maxY - limits.minY;

var scaleX = width / gWidth;
var scaleY = height / gHeight;

var scale, x, y;
if (scaleX < scaleY) {
scale = scaleX;
x = 0 - limits.minX * scale;
y = 0 - limits.minY * scale + (height-(gHeight*scale))/2;
} else {
scale = scaleY;
x = 0 - limits.minX * scale + (width-(gWidth*scale))/2;
y = 0 - limits.minY * scale;
}

return {
x: x,
y: y,
scale: scale
};
};

TheGraph.findNodeFit = function (node, width, height) {
var limits = {
minX: node.metadata.x - TheGraph.config.nodeSize,
minY: node.metadata.y - TheGraph.config.nodeSize,
maxX: node.metadata.x + TheGraph.config.nodeSize * 2,
maxY: node.metadata.y + TheGraph.config.nodeSize * 2
};

var gWidth = limits.maxX - limits.minX;
var gHeight = limits.maxY - limits.minY;

var scaleX = width / gWidth;
var scaleY = height / gHeight;

var scale, x, y;
if (scaleX < scaleY) {
scale = scaleX;
x = 0 - limits.minX * scale;
y = 0 - limits.minY * scale + (height-(gHeight*scale))/2;
} else {
scale = scaleY;
x = 0 - limits.minX * scale + (width-(gWidth*scale))/2;
y = 0 - limits.minY * scale;
}

return {
x: x,
y: y,
scale: scale
};
};

// SVG arc math
var angleToX = function (percent, radius) {
return radius * Math.cos(2*Math.PI * percent);
Expand Down

0 comments on commit c7dabd7

Please sign in to comment.