← Examples
countries · geometry · overlay · art

Every country, one bloom

Take all ~195 national outlines, scale each to the same size, and stack them on a single point — tinted by continent, drawn in ink that darkens where the lines overlap. The borders you know dissolve; what's left is a composite of every shape on Earth at once, deepest where the world's countries most agree on a silhouette.

API Call

https://api.mapjson.com/v1/geo?layer=countries&filter=world&detail=low&properties=name,continent

Code

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <script src="https://cdn.jsdelivr.net/npm/d3@7/dist/d3.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/topojson-client@3/dist/topojson-client.min.js"></script>
  <style>
    body { margin: 0; background: #f7f4ec; }
    svg { width: 100%; height: auto; display: block; }
    #map path { mix-blend-mode: multiply; }
  </style>
</head>
<body>
  <svg id="map"></svg>
  <script>
  const W = 860, H = 760, TARGET = 470;
  const svg = d3.select("#map").attr("viewBox", `0 0 ${W} ${H}`);
  // deeper, saturated hues so they read on paper and darken where they overlap
  const CC = {"Africa":"#e08a1e","Asia":"#e23b46","Europe":"#2f7ad0","North America":"#1fa85f","South America":"#a63fd0","Oceania":"#159e97","Antarctica":"#8a97a5"};
  const projection = d3.geoNaturalEarth1().rotate([-11, 0]).scale(150).translate([0,0]);
  const path = d3.geoPath(projection);
  d3.json("https://api.mapjson.com/v1/geo?layer=countries&filter=world&detail=low&properties=name,continent&format=geojson").then(fc=>{
    const g = svg.append("g");
    fc.features.forEach(f=>{
      const c = CC[f.properties.continent] || "#8a8f99";
      const b = path.bounds(f); const w = b[1][0]-b[0][0], h = b[1][1]-b[0][1];
      if (!isFinite(w) || !isFinite(h) || w<=0 || h<=0) return;
      if (Math.max(w,h)/Math.min(w,h) > 12) return;                 // drop antimeridian-wrapped shapes
      const s = TARGET / Math.max(w,h), cx = (b[0][0]+b[1][0])/2, cy = (b[0][1]+b[1][1])/2;
      g.append("path").attr("d", path(f))
        .attr("transform", `translate(${W/2},${H/2}) scale(${s}) translate(${-cx},${-cy})`)
        .attr("fill","none").attr("stroke", c).attr("stroke-width", 1.1)
        .attr("vector-effect","non-scaling-stroke").attr("stroke-opacity", 0.55).attr("stroke-linejoin","round");
    });
    const legend = document.getElementById("legend");
    if (legend) Object.entries(CC).forEach(([k,c])=>{ const el=document.createElement("div"); el.className="legend-item";
      el.innerHTML=`<div class="legend-swatch" style="background:${c}"></div><span>${k}</span>`; legend.appendChild(el); });
  });
  </script>
</body>
</html>