Skip to content

UI 组件

本页记录 Mapbox GL JS 提供的用户界面组件。这些组件通过添加允许用户导航、定位自己、显示信息等的交互元素来增强地图可用性。有关 markers 和 popups 的具体信息,请参阅 Markers and Popups,有关详细的 control 文档,请参阅 Controls,有关交互的详细信息,请参阅 Interaction and Events

UI 组件概述

Mapbox GL JS 提供三个主要类别的 UI 组件:

SVG
100%

组件定位系统

Mapbox GL JS 中的 UI 组件遵循结构化的定位系统,允许在地图上精确放置。

SVG
100%

CSS 定位元素

地图容器包含八个定位容器,用于确定 UI controls 出现的位置:

Position Class位置CSS 选择器
Top顶部中心.mapboxgl-ctrl-top
Top Right右上角.mapboxgl-ctrl-top-right
Right右侧中心.mapboxgl-ctrl-right
Bottom Right右下角.mapboxgl-ctrl-bottom-right
Bottom底部中心.mapboxgl-ctrl-bottom
Bottom Left左下角.mapboxgl-ctrl-bottom-left
Left左侧中心.mapboxgl-ctrl-left

内置 Controls

Mapbox GL JS 提供几个可以添加到地图的内置 controls:

NavigationControl 向地图添加缩放和旋转按钮。通常位于左上角。

map.addControl(new mapboxgl.NavigationControl());

关键 CSS classes:

  • .mapboxgl-ctrl-zoom-in: 放大按钮
  • .mapboxgl-ctrl-zoom-out: 缩小按钮
  • .mapboxgl-ctrl-compass: 用于重置旋转的指南针按钮

Geolocate Control

GeolocateControl 添加一个按钮,使用浏览器的 geolocation API 在地图上定位和跟踪用户。

map.addControl(new mapboxgl.GeolocateControl({
    positionOptions: {
        enableHighAccuracy: true
    },
    trackUserLocation: true,
    showUserLocation: true,
    showUserHeading: true,
    fitBoundsOptions: {
        maxZoom: 20
    }
}));

关键 CSS classes:

  • .mapboxgl-ctrl-geolocate: geolocate 按钮的基类
  • .mapboxgl-ctrl-geolocate-active: 在主动跟踪位置时应用
  • .mapboxgl-ctrl-geolocate-background: 在后台跟踪时应用
  • .mapboxgl-user-location-dot: 用户位置指示器

Scale Control

ScaleControl 向地图添加距离比例指示器,通常在左下角。

map.addControl(new mapboxgl.ScaleControl());
// 带选项
map.addControl(new mapboxgl.ScaleControl({
    unit: 'nautical'
}));

关键 CSS classes:

  • .mapboxgl-ctrl-scale: 比例指示器

Fullscreen Control

FullscreenControl 添加一个按钮来切换地图的 fullscreen 模式。

map.addControl(new mapboxgl.FullscreenControl());

关键 CSS classes:

  • .mapboxgl-ctrl-fullscreen: 全屏按钮
  • .mapboxgl-ctrl-shrink: 处于全屏模式时的按钮

Attribution Control

AttributionControl 显示地图数据的归属信息。默认情况下会自动添加到地图。

关键 CSS classes:

  • .mapboxgl-ctrl-attrib: 归属信息的容器
  • .mapboxgl-ctrl-attrib-button: 用于紧凑模式的切换按钮
  • .mapboxgl-ctrl-attrib-inner: 归属文本的容器

创建自定义 Controls

你可以通过实现 IControl 接口来创建自定义 controls,该接口需要 onAddonRemove 方法:

class CustomControl {
    onAdd(map) {
        this._map = map;
        this._container = document.createElement('div');
        this._container.className = 'mapboxgl-ctrl';
        // 向 this._container 添加内容和事件处理程序
        return this._container;
    }

    onRemove() {
        this._container.parentNode.removeChild(this._container);
        this._map = undefined;
    }
}

map.addControl(new CustomControl(), 'top-right');

Markers

Markers 是在地图上特定地理坐标定位的视觉指示器。

基本 Markers

const marker = new mapboxgl.Marker()
    .setLngLat([-77.03, 38.90])
    .addTo(map);

关键 CSS classes:

  • .mapboxgl-marker: markers 的基类

自定义 Markers

你可以使用自己的 HTML 元素自定义 markers:

const el = document.createElement('div');
el.className = 'custom-marker';
// 根据需要自定义元素

const marker = new mapboxgl.Marker(el)
    .setLngLat([-77.03, 38.90])
    .addTo(map);

用户位置 Markers

GeolocateControl 在激活时自动添加用户位置 marker:

关键 CSS classes:

  • .mapboxgl-user-location-dot: 用户的位置点
  • .mapboxgl-user-location-accuracy-circle: 精度半径圆
  • .mapboxgl-user-location-heading: 方向指示器

Popups

Popups 在附加到地图上特定位置或 marker 的浮动容器中显示信息。

创建 Popups

你可以通过多种方式创建 popups:

// 独立的 popup
const popup = new mapboxgl.Popup()
    .setLngLat(map.unproject(e.point))
    .setHTML("<h1>Hello World!</h1>")
    .addTo(map);

// 附加到 marker 的 popup
const marker = new mapboxgl.Marker()
    .setLngLat([-77.03, 38.90])
    .setPopup(new mapboxgl.Popup().setHTML("<h1>Marker Popup</h1>"))
    .addTo(map);

// 响应地图点击的 popup
map.on('click', function(e) {
    new mapboxgl.Popup()
        .setLngLat(map.unproject(e.point))
        .setHTML("<h1>Click Location</h1>")
        .addTo(map);
});

关键 CSS classes:

  • .mapboxgl-popup: popups 的基容器
  • .mapboxgl-popup-content: 内容容器
  • .mapboxgl-popup-close-button: 关闭按钮
  • .mapboxgl-popup-tip: 方向指针

Popups 可以相对于其坐标锚定在不同的位置:

const popup = new mapboxgl.Popup({
    anchor: 'bottom' // 可以是 'top'、'bottom'、'left'、'right'、'top-left' 等。
});

CSS 根据锚定位置应用特定样式:

.mapboxgl-popup-anchor-top,
.mapboxgl-popup-anchor-top-left,
.mapboxgl-popup-anchor-top-right {
    flex-direction: column;
}

.mapboxgl-popup-anchor-bottom,
.mapboxgl-popup-anchor-bottom-left,
.mapboxgl-popup-anchor-bottom-right {
    flex-direction: column-reverse;
}

Control 分组样式

可以使用 .mapboxgl-ctrl-group 类将多个 controls 分组在一起,并具有一致的样式:

// 这些 controls 将一起显示
map.addControl(new mapboxgl.NavigationControl(), 'top-right');
map.addControl(new mapboxgl.GeolocateControl(), 'top-right');

关键 CSS classes:

  • .mapboxgl-ctrl-group: 分组 controls 的容器
  • .mapboxgl-ctrl: 所有 controls 的基类

国际化

Mapbox GL JS 通过 locale 字符串支持 UI 组件的国际化:

const map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/streets-v11',
    locale: {
        'NavigationControl.ZoomIn': 'Zoom in',
        'NavigationControl.ZoomOut': 'Zoom out',
        'NavigationControl.ResetBearing': 'Reset bearing to north',
        'GeolocateControl.FindMyLocation': 'Find my location',
        'GeolocateControl.LocationNotAvailable': 'Location not available',
        'FullscreenControl.Enter': 'Enter fullscreen',
        'FullscreenControl.Exit': 'Exit fullscreen',
        'ScaleControl.Feet': 'ft',
        'ScaleControl.Meters': 'm'
        // 其他 locale 字符串...
    }
});

库中定义了默认的 locale 字符串:

const defaultLocale = {
    'AttributionControl.ToggleAttribution': 'Toggle attribution',
    'FullscreenControl.Enter': 'Enter fullscreen',
    'FullscreenControl.Exit': 'Exit fullscreen',
    'GeolocateControl.FindMyLocation': 'Find my location',
    'GeolocateControl.LocationNotAvailable': 'Location not available',
    'LogoControl.Title': 'Mapbox homepage',
    'Map.Title': 'Map',
    'NavigationControl.ResetBearing': 'Reset bearing to north',
    'NavigationControl.ZoomIn': 'Zoom in',
    'NavigationControl.ZoomOut': 'Zoom out',
    'ScaleControl.Feet': 'ft',
    'ScaleControl.Meters': 'm',
    'ScaleControl.Kilometers': 'km',
    'ScaleControl.Miles': 'mi',
    'ScaleControl.NauticalMiles': 'nm',
    'ScrollZoomBlocker.CtrlMessage': 'Use ctrl + scroll to zoom the map',
    'ScrollZoomBlocker.CmdMessage': 'Use ⌘ + scroll to zoom the map',
    'TouchPanBlocker.Message': 'Use two fingers to move the map'
};

交互行为和事件

UI 组件可以响应各种交互事件:

// Marker 交互
const marker = new mapboxgl.Marker()
    .setLngLat([-77.03, 38.90])
    .addTo(map);

marker.getElement().addEventListener('click', () => {
    console.log('Marker clicked!');
});

// Layer 交互
map.on('mouseenter', 'marker', function(e) {
    map.setFilter('marker-hover', ['==', 'name', e.features[0].properties.name]);
    map.getCanvas().style.cursor = 'pointer';
});

map.on('mouseleave', 'marker', function(e) {
    map.setFilter('marker-hover', ['==', 'name', '']);
    map.getCanvas().style.cursor = '';
});

地图元素对于不同的交互状态具有特定的光标样式:

.mapboxgl-canvas-container.mapboxgl-interactive,
.mapboxgl-ctrl-group button.mapboxgl-ctrl-compass {
    cursor: grab;
}

.mapboxgl-canvas-container.mapboxgl-interactive.mapboxgl-track-pointer {
    cursor: pointer;
}

.mapboxgl-canvas-container.mapboxgl-interactive:active,
.mapboxgl-ctrl-group button.mapboxgl-ctrl-compass:active {
    cursor: grabbing;
}

协作手势和阻挡器

Mapbox GL JS 在某些手势被阻止或需要修饰符时提供 UI 反馈:

const map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/streets-v11',
    cooperativeGestures: true
});

关键 CSS classes:

  • .mapboxgl-touch-pan-blocker: 触摸平移被阻止时显示
  • .mapboxgl-scroll-zoom-blocker: 滚动缩放被阻止时显示

组件系统集成

下图展示了 UI 组件如何与 Mapbox GL JS 的整体架构集成:

SVG
100%

Mapbox GL JS 中的 UI Components 系统提供了一套全面的交互元素,在保持一致的外观和感觉的同时增强地图可用性。这些组件可以广泛自定义和定位以满足特定的应用程序要求。