Atlaslog
Atlaslog / Examples / deck.gl / Tile
deck.gl · Runnable Example

Tile

Runnable deck.gl example: Tile. Open the live demo, read the complete source, and copy the file into your project. No build step or API key.

Open standalone → Chinese notes All deck.gl examples
/demos/deckgl-tile.htmlLIVE
single HTML file · CDN dependencies onlyinterface may contain Chinese labels

Source

demos/deckgl-tile.html
<!--
  示例:瓦片图层
  核心逻辑:TileLayer 按视口切瓦片,getTileData 现场生成图片,renderSubLayers 交给 BitmapLayer
  数据:canvas 生成的彩色瓦片,替代远程 XYZ 瓦片服务,接口形状与真实瓦片一致
  依赖:deck.gl 9.0 · jsDelivr CDN
-->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta name="robots" content="noindex,follow">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>瓦片图层</title>
<style>
  html,body{height:100%;margin:0;background:#0d1117}
  body{display:flex;flex-direction:column;overflow:hidden;
       font:13px/1.6 -apple-system,"Segoe UI","PingFang SC",sans-serif;color:#e6e8ec}
  .bar{position:relative;z-index:5;flex:0 0 auto;padding:8px 12px;background:#161b22;border-bottom:1px solid #252c36;
       display:flex;gap:14px;align-items:center;font-size:12px;color:#8b93a1;flex-wrap:wrap}
  .bar b{color:#58a6ff;font-weight:600}
  .bar input[type=range]{width:110px}
  #cv{flex:1 1 auto;min-height:0;width:100%}
</style>
</head>
<body>
<div class="bar">
  <span>已生成瓦片 <b id="n">0</b></span>
  <span>最大级别 <b id="zv">5</b></span>
  <label><input id="z" type="range" min="2" max="7" step="1" value="5"> 缩放</label>
  <span>瓦片内容按 z/x/y 现场绘制</span>
</div>
<canvas id="cv"></canvas>
<script src="https://cdn.jsdelivr.net/npm/deck.gl@9.0.35/dist.min.js"></script>
<script>
(function () {
  'use strict';

  if (typeof deck === 'undefined') {
    document.body.innerHTML =
      '<div style="padding:24px;color:#ff8c74">deck.gl 加载失败,请检查能否访问 cdn.jsdelivr.net</div>';
    return;
  }

  var made = 0;
  var counter = document.getElementById('n');

  /* 每张瓦片画成一张小图:底色随级别变化,右上角标 z/x/y */
  function tileImage(z, x, y) {
    var S = 256;
    var c = document.createElement('canvas');
    c.width = S;
    c.height = S;
    var g = c.getContext('2d');

    var hue = (x * 12 + y * 7 + z * 24) % 360;
    g.fillStyle = 'hsl(' + hue + ', 32%, 26%)';
    g.fillRect(0, 0, S, S);

    /* 网格线让人一眼看出瓦片边界 */
    g.strokeStyle = 'rgba(255,255,255,0.22)';
    g.lineWidth = 2;
    g.strokeRect(1, 1, S - 2, S - 2);

    /* 几条随机折线,模拟道路纹理 */
    g.strokeStyle = 'rgba(180,220,255,0.35)';
    g.lineWidth = 3;
    for (var i = 0; i < 3; i++) {
      g.beginPath();
      g.moveTo(Math.random() * S, Math.random() * S);
      g.lineTo(Math.random() * S, Math.random() * S);
      g.stroke();
    }

    g.fillStyle = 'rgba(255,255,255,0.85)';
    g.font = 'bold 26px monospace';
    g.fillText(z + '/' + x + '/' + y, 14, 40);

    made++;
    counter.textContent = made;

    return c.toDataURL('image/png');
  }

  var tileLayer = new deck.TileLayer({
    id: 'tiles',
    /* data 只提供模板形状,真正的字节由 getTileData 给出 */
    data: 'inline://{z}/{x}/{y}.png',
    minZoom: 0,
    maxZoom: 5,
    tileSize: 256,
    getTileData: function (tile) {
      return tileImage(tile.index.z, tile.index.x, tile.index.y);
    },
    renderSubLayers: function (props) {
      var b = props.tile.bbox;
      return new deck.BitmapLayer({
        image: props.data,
        bounds: [[b.west, b.south], [b.east, b.north]],
        opacity: 0.92,
        pickable: true
      });
    }
  });

  var deckgl = new deck.Deck({
    canvas: document.getElementById('cv'),
    width: '100%',
    height: '100%',
    initialViewState: {
      longitude: 110,
      latitude: 34,
      zoom: 3,
      pitch: 0,
      bearing: 0
    },
    controller: true,
    layers: [tileLayer],
    getTooltip: function (info) {
      if (!info.coordinate) return null;
      return info.coordinate[0].toFixed(1) + ', ' + info.coordinate[1].toFixed(1);
    }
  });

  document.getElementById('z').addEventListener('input', function () {
    var v = parseInt(this.value, 10);
    document.getElementById('zv').textContent = v;
    /* 上限提高后要重建图层,缓存才会按新范围取瓦片 */
    deckgl.setProps({
      layers: [
        new deck.TileLayer({
          id: 'tiles-' + v,
          data: 'inline://{z}/{x}/{y}.png',
          minZoom: 0,
          maxZoom: v,
          tileSize: 256,
          getTileData: function (tile) {
            return tileImage(tile.index.z, tile.index.x, tile.index.y);
          },
          renderSubLayers: function (props) {
            var b = props.tile.bbox;
            return new deck.BitmapLayer({
              image: props.data,
              bounds: [[b.west, b.south], [b.east, b.north]],
              opacity: 0.92,
              pickable: true
            });
          }
        })
      ]
    });
  });

  window.__deck = deckgl;
})();
</script>
</body>
</html>
Language: the code and this page are in English; the full tutorial and API notes for this example are in Chinese. The demo itself is the authoritative version — it runs exactly as shown.

More deck.gl examples

deck.gl · EXAMPLETransitions deck.gl · EXAMPLETrip deck.gl · EXAMPLETrip Trail