Skip to content

Instantly share code, notes, and snippets.

@kheremos
Last active September 11, 2015 21:02
Show Gist options
  • Save kheremos/ae9628c3b95e9ab6ed7d to your computer and use it in GitHub Desktop.
Save kheremos/ae9628c3b95e9ab6ed7d to your computer and use it in GitHub Desktop.
d3.js Geodesic Rainbow
<div id="subdivision">
<input type="range" min="1" max="12" value="8">
<output name="subdivision"></output>
</div>
/** Updated: Fri Noon **/
// TODO: Update gradients based on tile's projection
var width = 800,
missingCount = 0,
idCounter = 0,
height = 475;
var loggedCount = [0,11];
var faceCounter;
var gradients = {};
var velocity = [.023, .004],
t0 = Date.now();
var projection = d3.geo.orthographic()
.scale(height / 2 - 10);
var canvas = d3.select("body").append("canvas")
.attr("width", width)
.attr("height", height);
console.log(" ** canvas: ")
console.log(canvas);
var context = canvas.node().getContext("2d");
var gradient = context.createLinearGradient(0,0,100,500);
console.log(' ** context'); console.log(context);
context.strokeStyle = "#000";
context.lineWidth = .2;
var faces;
var output = d3.select("output");
var input = d3.select("input")
.on("change", function() { geodesic(+this.value); })
.each(function() { geodesic(+this.value); });
d3.timer(function() {
var time = Date.now() - t0;
projection.rotate([time * velocity[0], time * velocity[1]]);
redraw( );
});
function newGradient(d){
logLimited("New Gradient for object:");
logLimited(d);
var x0, y0, r0, x1, y1, r1;
c0={x: d[0][0], y: d[2][1], r: 100};
c1={x: d[1][0], y: d[2][1], r: 329};
clr1 = {h:d[0][1], s:.75, l:0}
var tempGradient = context.createRadialGradient(c0.x,c0.y,c0.r,c1.x,c1.y,c1.r);
color1 = d3.hsl(clr1.h, clr1.s, clr1.l).darker(d.id/200).rgb().toString();
// Creates string like #AABBCC .darker(d.id)
color2 = d3.hsl(d[0][0], .75, .5).rgb().toString();
tempGradient.addColorStop(.2, color1);
tempGradient.addColorStop(.9, color2);
return tempGradient;
}
function redraw() {
context.clearRect(0, 0, width, height);
faces.forEach(function(d) {
d.polygon[0] = projection(d[0]);
d.polygon[1] = projection(d[1]);
d.polygon[2] = projection(d[2]);
if (d.visible = d.polygon.area() > 0) {
context.fillStyle = d.fill;
context.beginPath();
centr=drawTriangle(d.polygon, d.id);
context.fill();
context.fillStyle="#111111";
// context.fillText(d.id,centr.x-200, centr.y);
}
});
context.beginPath();
faces.forEach(function(d) {
if (d.visible) {
context.fillStyle = d.fill;
// Change gradient before drawing
centr=drawTriangle(d.polygon);
// context.beginPath();
context.fillStyle="#111111";
context.fillText(d.id,centr.x-2, centr.y);
}
});
context.stroke();
}
function drawTriangle(triangle, txt) {
x=(triangle[0][0]+triangle[1][0]+triangle[2][0])/3
y=(triangle[0][1]+triangle[1][1]+triangle[2][1])/3
context.moveTo(triangle[0][0], triangle[0][1]);
context.lineTo(triangle[1][0], triangle[1][1]);
context.lineTo(triangle[2][0], triangle[2][1]);
context.closePath();
return {
x:(triangle[0][0]+triangle[1][0]+triangle[2][0])/3,
y:(triangle[0][1]+triangle[1][1]+triangle[2][1])/3
};
}
function geodesic(subdivision) {
output.text("◫"+subdivision);
faceCounter = 0;
idCounter = 0;
faces = d3.geodesic.polygons(subdivision).map(function(d) {
d = d.coordinates[0];
// logLimited("Logging an element of polygon map:");
// logLimited(d);
d.pop(); // use an open polygon
d.id=idCounter++;
if (!gradients[d.id]) {
missingCount++;
gradients[d.id]=newGradient(d);
context.clearRect(0, 0, width, height);
}
d.fill = gradients[d.id];
d.polygon = d3.geom.polygon(d.map(projection));
return d;
});
console.log("faceCounter: "+faceCounter);
output.text(subdivision+" ◫ "+faces.length);
console.log(" ** faces[2]");
console.log(faces[2]);
console.log("New gradient count: "+missingCount);
redraw();
}
function logLimited(thingToLog){
if (loggedCount[0] < loggedCount[1]){
loggedCount[0]++;
console.dir(thingToLog);
}
}
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/d3.geodesic.v0.min.js"></script>
#subdivision {
position: absolute;
top: 20px;
left: 20px;
}
#subdivision input {
width: 200px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment