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.
single HTML file · CDN dependencies onlyinterface may contain Chinese labels
Source
<!--
示例:瓦片图层
核心逻辑: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.