Skip to content

Instantly share code, notes, and snippets.

@Fil
Last active February 28, 2018 11:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Fil/779ba73998272d55bccef3d00713d502 to your computer and use it in GitHub Desktop.
Save Fil/779ba73998272d55bccef3d00713d502 to your computer and use it in GitHub Desktop.
Projection Paint [UNLISTED]
license: gpl-3.0
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="https://unpkg.com/d3@4"></script>
<script src="https://unpkg.com/d3-geo-projection"></script>
<script src="https://unpkg.com/topojson"></script>
<script>
var width = 960,
height = 500;
var radius = height / 2 - 20,
scale = radius,
velocity = .015;
var projection = d3.geoOrthographic()
.fitExtent([[0,0],[300,300]], {type:"Sphere"});
var projection2 = d3.geoPolyhedralWaterman().fitExtent([[300,0],[960,500]], {type:"Sphere"});
var canvas = d3.select("body").append("canvas")
.attr("width", width)
.attr("height", height);
var context = canvas.node().getContext("2d");
// retina display
var devicePixelRatio = window.devicePixelRatio || 1;
canvas.style('width', canvas.attr('width')+'px');
canvas.style('height', canvas.attr('height')+'px');
canvas.attr('width', canvas.attr('width') * devicePixelRatio);
canvas.attr('height', canvas.attr('height') * devicePixelRatio);
context.scale(devicePixelRatio,devicePixelRatio);
var path = d3.geoPath()
.projection(projection)
.context(context);
var path2 = d3.geoPath()
.projection(projection2)
.context(context);
var backprojection = d3.geoProjection(function(a,b) {
return d3.geoOrthographicRaw(-a,b);
}).clipAngle(90)
.translate(projection.translate())
.scale(projection.scale())
var backpath = d3.geoPath()
.projection(backprojection)
.context(context);
d3.json("https://unpkg.com/world-atlas/world/110m.json", function(error, world) {
if (error) throw error;
var land = topojson.feature(world, world.objects.land);
var points = (d3.merge(d3.merge(land.features[0].geometry.coordinates)))
//points = points.sort((a,b) => -a[0]+b[0])
d3.timer(function(elapsed) {
context.clearRect(0, 0, width, height);
var rotate = [velocity * elapsed, -30];
projection.rotate(rotate);
//projection2.rotate([rotate[0] + 180, rotate[1]]);
backprojection.rotate([rotate[0] + 180, -rotate[1]]);
context.beginPath();
backpath(land);
context.fillStyle = '#f4f4f4f4';
context.fill();
context.beginPath();
path(land);
//path2(land);
context.lineWidth = 1;
context.strokeStyle = 'black';
context.stroke();
context.fillStyle = '#eee';
context.fill();
context.beginPath();
path2(d3.geoGraticule()());
//path2(land);
context.lineWidth = 0.1;
context.strokeStyle = 'black';
context.stroke();
var N = points.length,
periode = N * 1.5,
t = (elapsed * velocity * 20 + periode - 0.1*N) % periode;
points.forEach(function(point,i){
var A = projection(point),
B = projection2(point),
segment = [A,B],
bout = 1;
var ti = t - i;
if (ti < 0) return;
if (ti > 0.8 * N) return;
if (ti > 0.3 * N) {
segment = [B,B];
bout = 1;
} else
if (ti < 0.1 * N) {
var p = ((0.1 * N) - ti) / (0.1 * N),
C = [p * A[0] + (1-p) * B[0], p * A[1] + (1-p)*B[1]];
segment = [A,C];
bout = 0.5;
} else
if (ti > 0.2 * N && ti < 0.3 * N) {
var p = (0.3 * N - ti) / (0.1 * N),
C = [p * A[0] + (1-p) * B[0], p * A[1] + (1-p)*B[1]];
segment = [C,B];
bout = 1;
}
context.beginPath();
context.moveTo(...segment[0]);
context.lineTo(...segment[1]);
context.lineWidth = 1;
context.strokeStyle = 'rgba(40,40,90,0.03)';
context.stroke();
if (bout < 1) {
context.beginPath();
context.lineWidth = bout * 3;
context.moveTo(...segment[0]);
context.lineTo(segment[0][0]+bout*2, segment[0][1]+bout);
context.strokeStyle = 'white';
context.stroke();
}
context.beginPath();
context.lineWidth = bout * 3;
context.moveTo(...segment[1]);
context.lineTo(segment[1][0]+bout*2, segment[1][1]+bout);
context.strokeStyle = 'red';
context.stroke();
})
context.beginPath();
path({type: "Sphere"});
context.lineWidth = 1.5;
context.strokeStyle = 'black';
context.stroke();
});
});
d3.select(self.frameElement).style("height", height + "px");
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment