|
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
<style> |
|
|
|
body { |
|
background: #222; |
|
} |
|
|
|
|
|
|
|
</style> |
|
<body> |
|
<script src="https://d3js.org/d3.v3.min.js"></script> |
|
<script src="https://d3js.org/d3.geo.projection.v0.min.js"></script> |
|
<script> |
|
|
|
var width = 960, |
|
height = 500; |
|
/* |
|
var projection = d3.geoAzimuthalEquidistant() |
|
.scale(65) |
|
.precision(.1); |
|
*/ |
|
|
|
var projection = d3.geo.projection(d3.geo.hammer.raw(1.75, 2)) |
|
.rotate([-10, -45]) |
|
.scale(130) |
|
.translate([width / 2, height / 2]) |
|
.precision(.1); |
|
|
|
var canvas = d3.select("body").append("canvas") |
|
.attr("width", width) |
|
.attr("height", height); |
|
|
|
var context = canvas.node().getContext("2d"); |
|
|
|
var image = new Image; |
|
image.onload = onload; |
|
image.src = "readme-blue-marble.jpg"; |
|
|
|
|
|
|
|
function onload() { |
|
var dx = image.width, |
|
dy = image.height; |
|
|
|
context.drawImage(image, 0, 0, dx, dy); |
|
|
|
var sourceData = context.getImageData(0, 0, dx, dy).data, |
|
target = context.createImageData(width, height), |
|
targetData = target.data; |
|
|
|
for (var y = 0, i = -1; y < height; ++y) { |
|
for (var x = 0; x < width; ++x) { |
|
|
|
var p = projection.invert([x, y]), λ = p[0], φ = p[1]; |
|
|
|
var pxy = projection(p); |
|
|
|
var tolerance = 0.5; |
|
|
|
if ( λ > 180 || λ < -180 || φ > 90 || φ < -90 ) { i += 4; continue; } |
|
if ( (Math.abs(pxy[0] - x) < tolerance ) && (Math.abs(pxy[1] - y) < tolerance ) ) { |
|
|
|
|
|
|
|
var q = ((90 - φ) / 180 * dy | 0) * dx + ((180 + λ) / 360 * dx | 0) << 2; |
|
targetData[++i] = sourceData[q]; |
|
targetData[++i] = sourceData[++q]; |
|
targetData[++i] = sourceData[++q]; |
|
targetData[++i] = 255; |
|
|
|
} |
|
else { |
|
i += 4; |
|
} |
|
} |
|
} |
|
|
|
context.clearRect(0, 0, width, height); |
|
context.putImageData(target, 0, 0); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
</script> |