Playing with clipAngle(x -> 0).
forked from Fil's block: Vanishing Earth
forked from Fil's block: Vanishing Earth [UNLISTED]
license: gpl-3.0 |
Playing with clipAngle(x -> 0).
forked from Fil's block: Vanishing Earth
forked from Fil's block: Vanishing Earth [UNLISTED]
<!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> |