block by wboykinm 98b6579dd95985d7fb49

98b6579dd95985d7fb49

Full Screen

index.html

<!DOCTYPE html>
<html>
<head>
  <title>Canvas Layer!</title>
  <meta charset="utf-8">

  <link rel="stylesheet" type="text/css" href="//cdn.leafletjs.com/leaflet-0.7.3/leaflet.css">
  <link rel="stylesheet" type="text/css" href="main.css">
</head>
<body>

<div id="map"></div>

<script src="https://cdn.rawgit.com/jondavidjohn/hidpi-canvas-polyfill/master/dist/hidpi-canvas.js"></script>
<script src="//cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
<script src="//d3js.org/d3.v3.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>

<script src="fancyCanvas.js"></script>
<script src="layer.js"></script>
</body>
</html>

fancyCanvas.js

L.tileLayer.fancyCanvas = function(url){
  var layer = L.tileLayer.canvas();
  layer.setUrl(url);

  var dataSource = function(x, y, z, done){
    var url = layer.getTileUrl({x: x, y: y, z: z});
    d3.json(url, done);
  };

  layer.data = function(fn){
    dataSource = fn;
    return layer;
  };

  var dataTransformer = function(d){return d};
  layer.transform = function(transformer){
    dataTransformer = transformer;
    return layer;
  };

  var renderer = function(context, d){
    console.error('No renderer specified, defaulting to black on black');
    context.fill();
    context.stroke();
  };

  layer.renderer = function(fn){
    renderer = fn;
    return layer;
  };

  layer.drawTile = function(canvas, tilePoint, zoom) {
    var context = canvas.getContext('2d');

    dataSource(tilePoint.x, tilePoint.y, zoom, function(err, data){
      data = dataTransformer(data);

      var tileOffset = {
        x: parseInt(d3.select(canvas).style('left').slice(0, -2)),
        y: parseInt(d3.select(canvas).style('top').slice(0, -2))
      };

      var projection = d3.geo.transform({
        point: function(y, x) {
          var point = map.latLngToLayerPoint(new L.LatLng(x, y));
          this.stream.point(point.x-tileOffset.x, point.y-tileOffset.y);
        }
      });

      var path = d3.geo.path()
        .projection(projection)
        .context(context);

      if (typeof renderer == 'function') {
        data.features.forEach(function(feature){
          context.beginPath();
          path(feature);
          context.closePath();
          renderer(context, feature, data);
        });
      } else if (Array.isArray(renderer)) {
        renderer.forEach(function(fn){
          data.features.forEach(function(feature){
            context.beginPath();
            path(feature);
            context.closePath();
            fn(context, feature, data);
          });
        });
      } else {
        throw new Error('wtf');
      }
    });
  };

  return layer;
};

layer.js

var map = L.map('map', {
  center: [37.81291, -122.36448],
  zoom: 12,
  minZoom: 3,
  maxZoom: 16
});

L.tileLayer('http://{s}.tile.stamen.com/terrain-background/{z}/{x}/{y}.jpg').addTo(map);

var url = 'http://{s}.tile.openstreetmap.us/vectiles-highroad/{z}/{x}/{y}.topojson';

var roadSizes = {
  "highway": 5,
  "major_road": 3,
  "minor_road": 1,
  "rail": 0,
  "path": 0.5
};

L.tileLayer.fancyCanvas(url)
  .transform(function(d){
    if (d.objects) {
      return topojson.feature(d, d.objects.vectile);
    } else {
      return {
        type: 'FeatureCollection',
        features: []
      }
    }
  })
  .renderer([function(context, d){
    context.lineCap = 'round';
    context.lineJoin = 'round';
    context.strokeStyle = '#e9f2e1';
    context.lineWidth = roadSizes[d.properties.kind]+2;
    context.stroke();
  }, function(context, d){
    context.lineCap = 'round';
    context.lineJoin = 'round';
    context.strokeStyle = '#5e2f62';
    context.lineWidth = roadSizes[d.properties.kind];
    context.stroke();
  }]).addTo(map);

main.css

html, body {
  height: 100%;
  padding: 0;
  margin: 0;
}

#map {
  width: 100%;
  height: 100%;
}