📌 学习目标
- 掌握根据缩放级别改变建筑颜色的实现方法
- 理解相关API的使用
- 能够独立完成类似功能开发
🎯 核心概念
根据缩放级别改变建筑颜色。
💻 完 整 代 码
代码示例
js
const map = new maplibregl.Map({
container: 'map',
style: 'https://tiles.openfreemap.org/styles/bright',
center: [-90.73414, 14.55524],
zoom: 13
});
map.on('load', () => {
map.setPaintProperty('building-top', 'fill-color', [
'interpolate',
['exponential', 0.5],
['zoom'],
15,
'#e2714b',
22,
'#eee695'
]);
map.setPaintProperty('building-top', 'fill-opacity', [
'interpolate',
['exponential', 0.5],
['zoom'],
15,
0,
22,
1
]);
});
document.getElementById('zoom').addEventListener('click', () => {
map.zoomTo(19, {duration: 9000});
});
代码示例
html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Change building color based on zoom level</title>
<meta property="og:description" content="使用插值表达式缓入建筑物图层,并在两种颜色之间平滑过渡。" />
<meta property="og:created" content="2023-06-27" />
<meta charset='utf-8'>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel='stylesheet' href='https://unpkg.com/maplibre-gl@5.24.0/dist/maplibre-gl.css' />
<script src='https://unpkg.com/maplibre-gl@5.24.0/dist/maplibre-gl.js'></script>
<style>
body { margin: 0; padding: 0; }
html, body, #map { height: 100%; }
</style>
</head>
<body>
<style>
#zoom {
display: block;
position: absolute;
top: 20px;
left: 50%;
transform: translate(-50%);
width: 50%;
height: 40px;
padding: 10px;
border: none;
border-radius: 3px;
font-size: 12px;
text-align: center;
color: #fff;
background: #ee8a65;
}
</style>
<div id="map"></div>
<button id="zoom">Zoom to buildings</button>
<script>
const map = new maplibregl.Map({
container: 'map',
style: 'https://tiles.openfreemap.org/styles/bright',
center: [-90.73414, 14.55524],
zoom: 13
});
map.on('load', () => {
map.setPaintProperty('building-top', 'fill-color', [
'interpolate',
['exponential', 0.5],
['zoom'],
15,
'#e2714b',
22,
'#eee695'
]);
map.setPaintProperty('building-top', 'fill-opacity', [
'interpolate',
['exponential', 0.5],
['zoom'],
15,
0,
22,
1
]);
});
document.getElementById('zoom').addEventListener('click', () => {
map.zoomTo(19, {duration: 9000});
});
</script>
</body>
</html>
🔍 代码解析
初始化地图
使用 new maplibregl.Map() 创建地图实例,配置基本参数。本示例的核心特色是展示如何根据缩放级别动态改变建筑物颜色和透明度。
关键配置项
- container: 地图容器的 DOM 元素 ID
- style : 使用 MapLibre 官方样式
https://tiles.openfreemap.org/styles/bright - center : 地图初始中心点
[-90.73414, 14.55524](洪都拉斯附近) - zoom: 初始缩放级别为 13,显示城市级别视图
插值表达式配置
javascript
map.on('load', () => {
map.setPaintProperty('building-top', 'fill-color', [
'interpolate',
['exponential', 0.5],
['zoom'],
15,
'#e2714b',
22,
'#eee695'
]);
map.setPaintProperty('building-top', 'fill-opacity', [
'interpolate',
['exponential', 0.5],
['zoom'],
15,
0,
22,
1
]);
});
缩放动画按钮
javascript
document.getElementById('zoom').addEventListener('click', () => {
map.zoomTo(19, {duration: 9000});
});
⚙️ 参数说明
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| container | string | 是 | - | 地图容器元素的 ID |
| style | string/object | 是 | - | 地图样式 URL 或内联样式对象 |
| center | number, number | 否 | [0, 0] |
初始中心点坐标,格式为 [经度, 纬度] |
| zoom | number | 否 | 0 |
初始缩放级别,范围 0-22 |
interpolate 表达式
| 参数 | 类型 | 说明 |
|---|---|---|
| type | string | 插值类型:linear 或 exponential |
| base | number | 指数插值的底数(仅 exponential 类型需要) |
| input | expression | 输入值(通常是 ['zoom']) |
| stop1 | number | 第一个停止点的输入值 |
| output1 | any | 第一个停止点的输出值 |
| stop2 | number | 第二个停止点的输入值 |
| output2 | any | 第二个停止点的输出值 |
🎨 效果说明
运行代码后,页面显示一个交互式地图,建筑物颜色和透明度随缩放级别变化:
- 缩放级别 15 以下 : 建筑物完全透明(
fill-opacity: 0) - 缩放级别 15-22 : 建筑物从透明渐变为完全不透明,颜色从橙色(
#e2714b)渐变为浅黄色(#eee695) - 缩放级别 22 以上: 建筑物完全不透明,显示浅黄色
页面顶部有一个 "Zoom to buildings" 按钮,点击后会在9秒内平滑缩放到级别19,可以清楚看到建筑物颜色渐变效果。
💡 常 见 问 题
Q1: 插值表达式的工作原理是什么?
A: 插值表达式根据输入值(如缩放级别)在指定的停止点之间进行插值计算。linear 插值是线性的,exponential 插值是非线性的,底数越大变化越陡峭。
Q2: 可以使用哪些插值类型?
A: MapLibre 支持 linear(线性插值)和 exponential(指数插值)两种类型。线性插值变化均匀,指数插值在高缩放级别变化更快。
Q3: 如何添加更多停止点?
A: 在插值表达式中添加更多的 stop, output 对即可。例如:
javascript
['interpolate', ['linear'], ['zoom'], 10, '#fff', 15, '#ccc', 20, '#000']
Q4: 插值表达式可以用于哪些属性?
A: 大多数 paint 属性都支持插值表达式,包括颜色、透明度、宽度等。
📝 练习任务

- 基础练习:修改颜色值,尝试不同的颜色渐变效果
- 进阶挑战:添加更多停止点,实现更复杂的颜色变化
- 拓展思考:如何根据缩放级别改变建筑物的高度(3D效果)?
🌟 最佳实践
- 表达式复用: 将复杂的表达式提取为变量,便于维护
- 性能优化 : 使用
exponential插值可以在高缩放级别提供更好的性能 - 视觉设计: 确保颜色渐变在整个缩放范围内都清晰可见
- 测试验证: 在不同缩放级别测试效果,确保过渡平滑
- 文档说明: 添加注释说明插值表达式的含义和预期效果
- 用户体验: 提供缩放动画按钮帮助用户观察效果变化
🔗 延伸阅读
-
下一课预告:将继续学习地图图层的基础知识
本文是MapLibre GL JS实践课程系列的一部分,欢迎关注收藏