diameter = 600 radius = diameter / 2 velocity = 0.01 past = Date.now() projection = d3.geo.orthographic() .scale(radius - 2) .translate([document.width / 2, document.height / 2]) .clipAngle(90) .precision(0) .scale(350) zoom = d3.behavior.zoom() .scale(projection.scale()) .scaleExtent([100, 800]) .on 'zoom', -> if d3.event && d3.event.scale projection.scale(d3.event.scale) canvas = d3.select('body').selectAll('canvas') .data(d3.range(1)) .enter().append('canvas') .attr('width', document.width) .attr('height', document.height) .call(zoom) path = d3.geo.path() .projection(projection) d3.json "world-110m.json", (error, world) -> land = topojson.object(world, world.objects.land) globe = type: "Sphere" d3.timer -> angle = velocity * (Date.now() - past) angle += 250 angle = angle - 360 if angle > 360 canvas.each (i) -> rotate = [0, -10, 0] context = @getContext('2d') rotate[i] = angle * -1 projection.rotate(rotate) context.clearRect(0, 0, document.width, document.height) context.beginPath() path.context(context)(land) context.fill() context.beginPath() path(globe) context.stroke() null