MapLibre GL JS第50课:用表达式创建虚线渐变线

📌 学习目标

  • 掌握用表达式创建虚线渐变线的实现方法
  • 理解相关API的使用
  • 能够独立完成类似功能开发

🎯 核心概念

使用表达式创建带虚线的渐变线条。

💻 完 整 代 码

代码示例

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Create a gradient line with dasharray using an expression</title>
    <meta property="og:description" content="同时使用 line-gradient 和 line-dasharray 绘制属性来创建带有渐变颜色的虚线。" />
    <meta property="og:created" content="2025-10-09" />
    <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>
<div id="map"></div>

<script>
    const map = new maplibregl.Map({
        container: 'map',
        style: 'https://tiles.openfreemap.org/styles/bright',
        center: [-77.035, 38.875],
        zoom: 12
    });

    const geojson = {
        'type': 'FeatureCollection',
        'features': [
            {
                'type': 'Feature',
                'properties': {},
                'geometry': {
                    'coordinates': [
                        [-77.044211, 38.852924],
                        [-77.045659, 38.860158],
                        [-77.044232, 38.862326],
                        [-77.040879, 38.865454],
                        [-77.039936, 38.867698],
                        [-77.040338, 38.86943],
                        [-77.04264, 38.872528],
                        [-77.03696, 38.878424],
                        [-77.032309, 38.87937],
                        [-77.030056, 38.880945],
                        [-77.027645, 38.881779],
                        [-77.026946, 38.882645],
                        [-77.026942, 38.885502],
                        [-77.028054, 38.887449],
                        [-77.02806, 38.892088],
                        [-77.03364, 38.892108],
                        [-77.033643, 38.899926]
                    ],
                    'type': 'LineString'
                }
            }
        ]
    };

    map.on('load', () => {
        // 'line-gradient' 只能与GeoJSON源一起使用
        // 并且源必须将'lineMetrics'选项设置为true
        map.addSource('line', {
            type: 'geojson',
            lineMetrics: true,
            data: geojson
        });

        // 图层必须是'line'类型
        map.addLayer({
            type: 'line',
            source: 'line',
            id: 'line',
            paint: {
                'line-color': 'red',
                'line-width': 14,
                // 'line-gradient' 必须使用表达式指定
                // 使用特殊的'line-progress'属性
                'line-gradient': [
                    'interpolate',
                    ['linear'],
                    ['line-progress'],
                    0,
                    'blue',
                    0.1,
                    'royalblue',
                    0.3,
                    'cyan',
                    0.5,
                    'lime',
                    0.7,
                    'yellow',
                    1,
                    'red'
                ],
                // 'line-dasharray' 可以与 'line-gradient' 结合使用
                'line-dasharray': [10, 2.4]
            },
            layout: {
                'line-cap': 'round',
                'line-join': 'round'
            }
        });
    });
</script>
</body>
</html>

🔍 代码解析

初始化地图

使用 new maplibregl.Map() 创建地图实例,配置基本参数。本示例的核心特色是展示如何同时使用 line-gradientline-dasharray 属性创建带虚线的渐变线条。

关键配置项

  • container: 地图容器的 DOM 元素 ID
  • style : 使用 OpenStreetMap 亮色样式 https://tiles.openfreemap.org/styles/bright
  • center : 地图初始中心点 [-77.035, 38.875](美国华盛顿特区)
  • zoom: 初始缩放级别为 12,显示城市级别视图

GeoJSON 数据源配置

javascript 复制代码
map.addSource('line', {
    type: 'geojson',
    lineMetrics: true,  // 必须启用此选项才能使用 line-gradient
    data: geojson
});

虚线渐变线条配置

javascript 复制代码
map.addLayer({
    type: 'line',
    source: 'line',
    id: 'line',
    paint: {
        'line-color': 'red',
        'line-width': 14,
        'line-gradient': [
            'interpolate',
            ['linear'],
            ['line-progress'],
            0, 'blue',
            0.1, 'royalblue',
            0.3, 'cyan',
            0.5, 'lime',
            0.7, 'yellow',
            1, 'red'
        ],
        'line-dasharray': [10, 2.4]  // 虚线模式:10px实线,2.4px空白
    },
    layout: {
        'line-cap': 'round',
        'line-join': 'round'
    }
});

⚙️ 参数说明

参数 类型 必填 默认值 说明
container string - 地图容器元素的 ID
style string/object - 地图样式 URL 或内联样式对象
center number, number [0, 0] 初始中心点坐标
zoom number 0 初始缩放级别

line-dasharray 属性

参数 类型 必填 说明
dashArray number\[\] 虚线模式数组,交替表示实线和空白的长度

示例:

  • [10, 2.4]: 10px 实线,2.4px 空白
  • [5, 5]: 5px 实线,5px 空白(均匀虚线)
  • [10, 2, 2, 2]: 10px 实线,2px 空白,2px 实线,2px 空白(点划线)

🎨 效果说明

运行代码后,地图上会显示一条彩虹渐变的虚线路径:

  • 起点 : 坐标 [-77.0442, 38.8529],颜色为蓝色
  • 终点 : 坐标 [-77.0336, 38.8999],颜色为红色
  • 渐变过渡: 蓝 → 皇家蓝 → 青 → 石灰绿 → 黄 → 红
  • 虚线模式: 10px 实线段,2.4px 空白间隔

视觉效果:

  • 每个虚线段都呈现完整的颜色渐变
  • 虚线在拐角处平滑连接(line-join: round
  • 虚线端点圆润(line-cap: round

💡 常 见 问 题

Q1: line-dasharray 如何工作?

A: line-dasharray 接受一个数字数组,定义虚线的模式。数组元素交替表示实线长度和空白长度。例如 [10, 2.4] 表示 10px 实线、2.4px 空白、10px 实线、2.4px 空白,以此类推。

Q2: line-gradient 和 line-dasharray 可以一起使用吗?

A: 可以。如本示例所示,两者可以组合使用,创建带有渐变效果的虚线。

Q3: 虚线间距如何影响渐变效果?

A: 每个虚线段都会呈现完整的颜色渐变。较小的虚线间距会让渐变看起来更连续,较大的间距会让渐变效果更分散。

Q4: 如何创建点划线效果?

A: 使用四个元素的数组,如 [10, 2, 2, 2],表示实线、长空白、短实线、短空白的重复模式。

📝 练习任务

  1. 基础练习:修改虚线间距和渐变颜色
  2. 进阶挑战:创建点划线效果(实线+点+空白)
  3. 拓展思考:如何实现虚线动画效果?

🌟 最佳实践

  1. 虚线比例: 虚线间距和实线长度要协调,避免过于密集或稀疏
  2. 视觉一致性: 虚线样式应与整体设计风格保持一致
  3. 性能考虑: 复杂的虚线模式可能影响渲染性能
  4. 线宽配合: 较宽的线条更能展示虚线效果
  5. 端点处理 : 使用 line-cap: round 使虚线端点更平滑
  6. 语义使用: 虚线通常表示次要路径、规划路线或边界

🔗 延伸阅读


本文是MapLibre GL JS实践课程系列的一部分,欢迎关注收藏

相关推荐
石山代码2 小时前
变量与解构
开发语言·前端·javascript
888CC++3 小时前
箭头函数(ES6)
前端·javascript·es6
qq_419854053 小时前
css filter
前端·javascript·css
大家的林语冰3 小时前
npm 不忍了,正式上线“阶段式发布“的新功能,进一步对抗频繁的供应链攻击!
前端·javascript·node.js
葛兰岱尔4 小时前
从 SolidWorks 到 Three.js,从 Inventor 到 Unity——制造业CAD模型“几何-语义一体化“转换,不再是天方夜谭!
开发语言·javascript·unity
zzqssliu4 小时前
基于Laravel + Express.js的代购系统多语言多货币架构设计
javascript·express·laravel
水煮白菜王4 小时前
高德地图"未获得商用授权"水印临时移除方案
前端·javascript
chushiyunen4 小时前
vue el-pagination实现分页
javascript·vue.js·elementui
by————组态4 小时前
Ricon组态可视化编辑器 - 所见即所得的工业画布
前端·javascript·物联网·架构·编辑器·组态