Last active
March 14, 2016 20:49
-
-
Save mitch-seymour/284943058903f05e5e97 to your computer and use it in GitHub Desktop.
Geodesic satellites
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
height: 660 | |
license: mit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
var width = 960, | |
height = 700, | |
scale = 240, | |
progress = 0, | |
inner_radius = (scale / 3.428); | |
var velocity = [-.003, .003]; | |
var projection = d3.geo.orthographic() | |
.scale(scale) | |
.translate([width / 2, height / 2]); | |
var path = d3.geo.path() | |
.projection(projection); | |
// append the svg to the body | |
var g = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height) | |
.append("g") | |
.attr("transform", "translate(0,0)") | |
.attr("class", "container"); | |
// append the inner circles | |
g.append("circle") | |
.attr("class", "middle") | |
.attr("r", scale / 1.29) | |
.attr("cx", width / 2) | |
.attr("cy", height / 2); | |
g.append("circle") | |
.attr("class", "inner") | |
.attr("r", scale / 2) | |
.attr("cx", width / 2) | |
.attr("cy", height / 2); | |
// append the geodesic globe | |
var globeLines = g.append("path") | |
.attr("class", "lines") | |
.datum(d3.geodesic.multilinestring(6)); | |
// append the innermost circle | |
g.append("circle") | |
.attr("class", "inner-most") | |
.attr("r", inner_radius) | |
.attr("cx", width / 2) | |
.attr("cy", height / 2); | |
// append the small circles with letters | |
var labels = ['V', 'P', 'D', 'S']; | |
for (var i = 0; i < 4; i++) { | |
var offset = scale / 2.86, | |
w = width / 2 + (scale / 4.8 * i) + offset; | |
var container = g.append('g') | |
.attr("class", function() { | |
return i == 0 ? "dc active" : "dc"; | |
}) | |
.attr("transform", "translate(" + w + "," + height / 2 + ")"); | |
container.append("circle") | |
.attr("r", scale / 12); | |
container.append("text") | |
.attr("text-anchor", "middle") | |
.attr("dy", "4px") | |
.text(labels[i]); | |
} | |
// append the arc | |
var arc = d3.svg.arc() | |
.startAngle(0) | |
.innerRadius(scale / 4.53) | |
.outerRadius(scale / 4.21); | |
var arc_bg = g.append("g") | |
.attr("class", "arc-container") | |
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); | |
arc_bg.append("path") | |
.attr("class", "arc-background") | |
.attr("d", arc.endAngle(2 * Math.PI)); | |
var foreground = arc_bg.append("path") | |
.attr("class", "arc-foreground"); | |
var text = arc_bg.append("text") | |
.attr("class", "arc-text top") | |
.attr("text-anchor", "middle") | |
.attr("dy", "-3px") | |
.text("40"); | |
arc_bg.append("text") | |
.attr("class", "arc-text bottom") | |
.attr("text-anchor", "middle") | |
.attr("dy", "15px") | |
.text("MB"); | |
function addSatellite(angle) { | |
(function() { | |
var satellite_radius = 40, | |
offset = 90, | |
radius = scale + (satellite_radius * 2) + offset, | |
x1 = Math.cos((angle) * (Math.PI / 180)) * inner_radius + width / 2, | |
y1 = Math.sin((angle) * (Math.PI / 180)) * inner_radius + height / 2, | |
x2 = Math.cos((angle) * (Math.PI / 180)) * radius + width / 2, | |
y2 = Math.sin((angle) * (Math.PI / 180)) * radius + height / 2, | |
x2_line = Math.cos((angle) * (Math.PI / 180)) * (radius - satellite_radius) + width / 2, | |
y2_line = Math.sin((angle) * (Math.PI / 180)) * (radius - satellite_radius) + height / 2; | |
var satellite = g.append("g") | |
.attr("class", "satellite") | |
.attr("height", 100) | |
.attr("width", 100); | |
satellite | |
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")") | |
.transition().duration(1000) | |
.attr("transform", "translate(" + parseInt(x2) + "," + parseInt(y2) + ")"); | |
// the line that connects the inner circle to the satellite circle | |
var line = g.append("line") | |
.attr("class", "satellite-connector") | |
.attr("x1", x1) | |
.attr("y1", y1) | |
.attr("x2", x1) | |
.attr("y2", y1); | |
line | |
.transition().duration(2000) | |
.attr("x2", x2_line) | |
.attr("y2", y2_line); | |
satellite.append("circle") | |
.attr("class", "satellite-circle") | |
.attr("r", 0) | |
.transition().duration(2400) | |
.attr("r", satellite_radius); | |
var _projection = d3.geo.orthographic() | |
.scale(80) | |
.translate([x2, y2]); | |
var _path = d3.geo.path() | |
.projection(_projection); | |
var _lines = g.append("path") | |
.attr("class", "satellite-path") | |
.datum(d3.geodesic.multilinestring(4)); | |
d3.timer(function(elapsed) { | |
_projection.rotate([elapsed * velocity[0], elapsed * velocity[1]]); | |
_lines.attr("d", _path); | |
}); | |
})(); | |
} | |
function randomNumberBetween(min, max) { | |
return Math.floor(Math.random() * (max - min + 1) + min); | |
} | |
function rotate() { | |
d3.timer(function(elapsed) { | |
projection.rotate([elapsed * velocity[0], elapsed * velocity[1]]); | |
d3.selectAll('.lines').attr("d", path); | |
}); | |
} | |
function updateProgress(num) { | |
var num = num / 100, | |
i = d3.interpolate(progress, num); | |
d3.transition().duration(1000).tween("progress", function() { | |
return function(t) { | |
progress = i(t); | |
foreground.attr("d", arc.endAngle((2 * Math.PI) * progress)); | |
text.text(d3.round(num * 100, 2)); | |
}; | |
}); | |
} | |
// demo | |
updateProgress(10); | |
addSatellite(-35); | |
setInterval(function() { | |
updateProgress(randomNumberBetween(0, 100)); | |
}, 1500); | |
rotate(); | |
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://github.com/d3/d3-plugins | |
!function(){function n(n){return d3.merge(e.map(function(t){var o=r(t[0],t[1]),u=r(t[0],t[2]),i=[];i.push([t[0],o(1/n),u(1/n)]);for(var a=1;n>a;++a){for(var e=r(o(a/n),u(a/n)),c=r(o((a+1)/n),u((a+1)/n)),f=0;a>=f;++f)i.push([e(f/a),c(f/(a+1)),c((f+1)/(a+1))]);for(var f=0;a>f;++f)i.push([e(f/a),c((f+1)/(a+1)),e((f+1)/a)])}return i}))}function t(t){function r(n,t){var r;(n[0]<t[0]||n[0]==t[0]&&(n[1]<t[1]||n[1]==t[1]&&n[2]<t[2]))&&(r=n,n=t,t=r),u[n.map(o)+" "+t.map(o)]=[n,t]}function o(n){return d3.round(n,4)}var u={};return n(t).forEach(function(n){r(n[0],n[1]),r(n[1],n[2]),r(n[2],n[0])}),d3.values(u)}function r(n,t){var r=n[0],o=n[1],u=n[2],i=t[0]-r,a=t[1]-o,e=t[2]-u;return function(n){return[r+n*i,o+n*a,u+n*e]}}function o(n){var t=n[0],r=n[1],o=n[2];return[Math.atan2(r,t)*i,Math.acos(o/Math.sqrt(t*t+r*r+o*o))*i-90]}var u=1.618033988749895,i=180/Math.PI,a=[[1,u,0],[-1,u,0],[1,-u,0],[-1,-u,0],[0,1,u],[0,-1,u],[0,1,-u],[0,-1,-u],[u,0,1],[-u,0,1],[u,0,-1],[-u,0,-1]],e=[[0,1,4],[1,9,4],[4,9,5],[5,9,3],[2,3,7],[3,2,5],[7,10,2],[0,8,10],[0,4,8],[8,2,10],[8,4,5],[8,5,2],[1,0,6],[11,1,6],[3,9,11],[6,10,7],[3,11,7],[11,6,7],[6,0,10],[9,1,11]].map(function(n){return n.map(function(n){return a[n]})});d3.geodesic={multipolygon:function(t){return{type:"MultiPolygon",coordinates:n(~~t).map(function(n){return n=n.map(o),n.push(n[0]),n=[n]})}},polygons:function(n){return d3.geodesic.multipolygon(~~n).coordinates.map(function(n){return{type:"Polygon",coordinates:n}})},multilinestring:function(n){return{type:"MultiLineString",coordinates:t(~~n).map(function(n){return n.map(o)})}}}}(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html> | |
<head> | |
<title>Geodesic satellites</title> | |
</head> | |
<body> | |
<style> | |
path { | |
fill: none; | |
stroke: rgba(139, 188, 253, .4); | |
} | |
.satellite-circle { | |
fill: #50D3C1; | |
fill-opacity: .88; | |
stroke: #50D3C1; | |
stroke-width: 2px; | |
} | |
.satellite-symbol { | |
fill: #fff; | |
fill-opacity: 1; | |
stroke: #50D3C1; | |
stroke-width: 2px; | |
} | |
.satellite-connector { | |
stroke: #50D3C1; | |
stroke-width: 2px; | |
} | |
.satellite-path { | |
stroke: #50D3C1; | |
stroke-opacity: .5; | |
} | |
.arc-background { | |
fill: #A8C3CE; | |
} | |
.dc circle { | |
fill: rgba(255, 255, 255, .7); | |
stroke: rgb(125, 181, 252); | |
stroke-width: 2px; | |
} | |
.dc.active circle { | |
fill: rgba(255, 255, 255, .98); | |
stroke: #02425F; | |
stroke-width: 3px; | |
} | |
.dc text { | |
fill: rgb(125, 181, 252); | |
font-family: Helvetica; | |
font-size: 12px; | |
} | |
.dc.active text { | |
fill: #02425F; | |
} | |
.arc-foreground { | |
fill: #fff; | |
} | |
.arc-text { | |
fill: #fff; | |
font-family: Helvetica; | |
} | |
.arc-text.bottom { | |
fill: #ccc; | |
font-style: italic; | |
font-size: 11px; | |
} | |
circle.outer { | |
fill: none; | |
stroke: rgba(139, 188, 253, .6); | |
stroke-width: 1px; | |
} | |
circle.middle { | |
fill: rgba(139, 188, 253, .6); | |
stroke: rgba(139, 188, 253, .8); | |
stroke-width: 2px; | |
} | |
circle.inner { | |
fill: rgba(124, 168, 246, .8); | |
stroke: rgba(124, 168, 246, .85); | |
stroke-width: 2px; | |
} | |
circle.inner-most { | |
fill: rgb(24, 95, 125); | |
} | |
</style> | |
<!-- scripts --> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.12/d3.min.js"></script> | |
<script src="geodesic.min.js"></script> | |
<script src="geodesic-satellites.js"></script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment