UI 组件
本页记录 Mapbox GL JS 提供的用户界面组件。这些组件通过添加允许用户导航、定位自己、显示信息等的交互元素来增强地图可用性。有关 markers 和 popups 的具体信息,请参阅 Markers and Popups,有关详细的 control 文档,请参阅 Controls,有关交互的详细信息,请参阅 Interaction and Events。
UI 组件概述
Mapbox GL JS 提供三个主要类别的 UI 组件:
组件定位系统
Mapbox GL JS 中的 UI 组件遵循结构化的定位系统,允许在地图上精确放置。
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:
Navigation Control
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,该接口需要 onAdd 和 onRemove 方法:
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: 方向指针
Popup 锚定
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 的整体架构集成:
Mapbox GL JS 中的 UI Components 系统提供了一套全面的交互元素,在保持一致的外观和感觉的同时增强地图可用性。这些组件可以广泛自定义和定位以满足特定的应用程序要求。