JSFiddle - React, Tailwind, and code Playground
by Denis Tverdokhlebov
CSS
html,
body
background: #000 url('//s3-us-west-2.amazonaws.com/s.cdpn.io/68727/bg-stars.svg') center repeat
overflow: hidden
canvas
display: block
JavaScript
// -------------------------------------
// Setup
// -------------------------------------
var height = window.innerHeight,
radius = height / 4,
velocity = 0.002,
width = window.innerWidth;
var canvas = d3.select('body').append('canvas')
.attr('height', height)
.attr('width', width);
var ctx = canvas.node().getContext('2d');
ctx.globalCompositeOperation = 'hard-light';
var projection = d3.geo.orthographic()
.clipAngle(180)
.scale(radius + 50)
.translate([width / 2, height / 2]);
var path = d3.geo.path()
.projection(projection)
.context(ctx);
// -------------------------------------
// Load
// -------------------------------------
d3.json('//s3-us-west-2.amazonaws.com/s.cdpn.io/68727/random.json', function(error, land) {
var land1 = topojson.merge(land, land.objects.land1.geometries);
var land2 = topojson.merge(land, land.objects.land2.geometries);
d3.timer(function(elapsed) {
ctx.clearRect(0, 0, width, height);
projection.rotate([velocity * elapsed, 0, velocity * elapsed * 0.5]);
ctx.beginPath();
ctx.arc(width / 2, height / 2, radius, 0, 2 * Math.PI, true);
ctx.shadowColor = 'rgba(80, 0, 199, 0.9)';
ctx.shadowBlur = 300;
ctx.fillStyle = 'rgba(40, 40, 40, 0.9)';
ctx.fill();
ctx.beginPath();
path(land2);
ctx.shadowColor = '#9e73df';
ctx.shadowBlur = 30;
ctx.fillStyle = 'rgba(117, 61, 202, 0.125)';
ctx.fill();
ctx.beginPath();
path(land1);
ctx.fillStyle = 'rgba(158, 115, 223, 0.1)';
ctx.fill();
ctx.beginPath();
ctx.arc(width / 2, height / 2, radius + 50, 0, 2 * Math.PI, true);
ctx.shadowColor = 'transparent';
ctx.lineWidth = 1;
ctx.strokeStyle = 'rgba(117, 61, 202, 0.1)';
ctx.stroke();
ctx.beginPath();
ctx.arc(width / 2, height / 2, radius + 100, 0, 2 * Math.PI, true);
ctx.lineWidth = 1.5;
ctx.strokeStyle = 'rgba(0, 0, 0, 0.2)';
ctx.stroke();
});
});