Skip to content

Instantly share code, notes, and snippets.

@osoken
Last active April 24, 2018 15:06
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 osoken/d4a2b8a53882f0b053d058a25724318a to your computer and use it in GitHub Desktop.
Save osoken/d4a2b8a53882f0b053d058a25724318a to your computer and use it in GitHub Desktop.
See-Through Globe with Drop Shadow

See-Through Globe with Drop Shadow

<!DOCTYPE html>
<meta charset='utf-8'>
<script src='//d3js.org/d3.v4.min.js'></script>
<script src='//d3js.org/topojson.v1.min.js'></script>
<body>
<style>
</style>
<script>
var width = 960,
height = 500;
var scale = 120;
var projection = d3.geoOrthographic()
.translate([0, 0])
.scale(scale);
var shadowProjection = d3.geoOrthographic()
.translate([0, 0])
.scale(-scale);
var angle = 12;
var hue = 210;
var path = d3.geoPath()
.projection(projection);
var shadowPath = d3.geoPath()
.projection(shadowProjection);
var velocity = 0.02;
var frequency = 0.0006;
var graticuleGeom = d3.geoGraticule()();
var sphereGeom = {type: 'Sphere'};
var svg = d3.select('body').append('svg')
.attr('width', width)
.attr('height', height);
var fog = svg.append('defs')
.append('linearGradient')
.attr('id', 'fog')
.attr('gradientTransform', 'rotate(90)');
fog.append('stop')
.attr('offset', 0)
.attr('stop-color', '#FFF');
fog.append('stop')
.attr('offset', 0.55)
.attr('stop-color', '#FFF');
fog.append('stop')
.attr('offset', 0.65)
.attr('stop-color', 'hsl(' + hue + ', 90%, 92%)');
fog.append('stop')
.attr('offset', 1.0)
.attr('stop-color', 'hsl(' + hue + ', 90%, 92%)');
svg.append('rect')
.attr('width', width)
.attr('height', height)
.attr('x', 0)
.attr('y', 0)
.attr('fill', 'url(#fog)');
var drawLayer = svg.append('g')
.attr(
'transform',
'translate(' + (0.5 * width) + ', ' + (0.5 * height + 50)+ ')'
);
d3.json(
'/osoken/raw/f141a4f3faed8cedf8a73aaf6344cf0f/ne_110m_land.json',
function(error, world) {
if (error) throw error;
var geom = topojson.feature(world, world.objects.ne_110m_land);
var filter = svg.append('filter')
.attr('id', 'shadowFilter')
.attr('filterUnits', 'userSpaceOnUse')
.attr('x', -0.5 * width)
.attr('y', -0.5 * height)
.attr('width', width).attr('height', height);
var blur = filter.append('feGaussianBlur')
.attr('in', 'SourceGraphic')
.attr('stdDeviation', 0);
var shadowLayer = drawLayer.append('g')
.datum(geom)
.attr('stroke', 'none')
.attr(
'transform',
'translate(0, ' + scale + ') ' +
'scale(1.0, ' + (Math.sin(angle * Math.PI / 180)) + ')'
).attr('filter', 'url(#shadowFilter)');
shadowProjection.clipAngle(180);
var shadowBack = shadowLayer.append('path')
.attr('d', shadowPath);
shadowProjection.clipAngle(90);
var shadowFront = shadowLayer.append('path')
.attr('d', shadowPath);
var earthLayer = drawLayer.append('g');
projection.clipAngle(180);
var landBack = earthLayer.append('path')
.datum(geom)
.attr('fill', '#BABABA')
.attr('stroke', 'none')
.attr('d', path);
projection.clipAngle(90);
var sphere = earthLayer.append('path')
.datum(sphereGeom)
.attr('stroke', 'none')
.attr('fill', 'rgba(255, 255, 255, 0.4)')
.attr('d', path);
var graticule = earthLayer.append('path')
.datum(graticuleGeom)
.attr('fill', 'none')
.attr('stroke', '#F7F7F7')
.attr('stroke-width', 1.0)
.attr('d', path);
var landFront = earthLayer.append('path')
.datum(geom)
.attr('fill', '#BABABA')
.attr('stroke', 'none')
.attr('d', path);
d3.timer(function(elapsed) {
var r = velocity * elapsed;
var y = -Math.sin(frequency * elapsed);
blur.attr('stdDeviation', 10 + 6 * y);
shadowLayer.attr('fill', 'hsl(' + hue + ', 20%, ' + (70 + 1 * y) + '%)');
shadowProjection.rotate([r, -90]).scale(scale + 30 * (1 + y))
.clipAngle(180);
shadowBack.attr('d', shadowPath);
shadowProjection.clipAngle(90);
shadowFront.attr('d', shadowPath);
projection.rotate([r, -angle]).translate([0, -75 * (1 + y)])
.clipAngle(180);
landBack.attr('d', path);
projection.clipAngle(90);
sphere.attr('d', path);
graticule.attr('d', path);
landFront.attr('d', path);
});
}
);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment