Transforming geographic shapes into circles with the help of polymorph. Code written in livescript.
Built with blockbuilder.org
| license: mit |
Transforming geographic shapes into circles with the help of polymorph. Code written in livescript.
Built with blockbuilder.org
| <!DOCTYPE html> | |
| <head> | |
| <meta charset="utf-8"> </meta> | |
| <script src='https://d3js.org/d3.v3.min.js' charset="utf-8"></script> | |
| <script src="https://d3js.org/topojson.v1.min.js" charset="utf-8"></script> | |
| <script src='https://polyshrink.s3.amazonaws.com/polymorph.js' charset='utf-8'></script> | |
| <script src="https://polyshrink.s3.amazonaws.com/countries.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/livescript/1.5.0/livescript.js"></script> | |
| <script type="text/ls"> | |
| pageWidth = window.innerWidth | |
| pageHeight = window.innerHeight | |
| proj = new d3.geo.mercator! | |
| .center [-105,51] | |
| .rotate [0,0,0] | |
| .translate [(pageWidth/2),pageHeight/2] | |
| .scale 1 .<<. 8 | |
| zoomed = -> | |
| transform = "translate(#{zoom.translate!}) scale(#{zoom.scale!})" | |
| d3.select 'svg#map-canvas g' | |
| .attr 'transform', transform | |
| .selectAll 'path' | |
| .style 'stroke-width', -> 3 / zoom.scale! | |
| zoom = new d3.behavior.zoom!on 'zoom', zoomed | |
| g = d3.select 'div#map' | |
| .append 'svg' | |
| .attr 'id', 'map-canvas' | |
| .call zoom | |
| .append 'g' | |
| path = d3.geo.path().projection(proj) # Path generating function | |
| # Transpose a shape onto a circle | |
| circleIt = (it,x,y,r) -> | |
| from = path it # The coastline boundary | |
| # A simple circle path of two arcs | |
| circle = "m #{x - r} #y | |
| a #r #r 0 1 0 #{2*r} 0 | |
| a #r #r 0 1 0 #{-2*r} 0" | |
| polymorph.transpose from, circle | |
| randomCircle = -> | |
| p = 20 # padding | |
| w = pageWidth - (2 * p) | |
| h = pageHeight - (2 * p) | |
| x = (Math.random! * w) + p | |
| y = (Math.random! * h) + p | |
| r = (Math.log it.properties.AREA) * 3 | |
| circleIt it, x, y, r | |
| colours = | |
| Canada: '#CACACA' | |
| Mexico: '#8C8787' | |
| 'United States': '#4E4E4E' | |
| cstGeoJson = topojson.feature countries,countries.objects.countries | |
| g.selectAll 'path' | |
| .data cstGeoJson.features.filter -> # Let's be selective | |
| name = it.properties.name | |
| area = it.properties.AREA # Filter out small island | |
| reg = /(Canada|Mexico|United States)/ # Only NA for now | |
| if name.match reg and area > 1 then yes else no | |
| .enter! | |
| .append 'path' | |
| .attr 'd', randomCircle | |
| .style 'fill', -> colours[it.properties.name] | |
| toDots = -> | |
| l = d3.selectAll('path')[0].length | |
| i = 1 | |
| d3.selectAll 'path' | |
| .transition! | |
| .delay -> Math.random! * 1000 | |
| .duration 5000 | |
| .attr 'd', randomCircle | |
| .each 'end', -> toCountries! if l is i++ | |
| toCountries = -> | |
| l = d3.selectAll('path')[0].length | |
| i = 1 | |
| d3.selectAll 'path' | |
| .transition! | |
| .delay -> Math.random! * 1000 | |
| .duration 5000 | |
| .attr 'd', path | |
| .each 'end', -> toDots! if l is i++ | |
| toCountries! | |
| </script> | |
| <style> | |
| body,html,svg,div#map { | |
| width: 100%; | |
| height: 100%; | |
| padding: 0px; | |
| margin: 0px; | |
| overflow: hidden; | |
| } | |
| body { | |
| background-color: #ffffff; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div id='map'></div> | |
| <script> | |
| var LiveScript = require("livescript"); | |
| LiveScript.go(); | |
| </script> | |
| </body> |