Markers 标记

丰富的标记系统,支持弹窗、提示和标签。使用声明式组件构建复杂的标记 UI。

默认标记

最简单的标记——一个蓝色圆点:

MapWithMarker.tsx
12345678910111213
import { Map, MapMarker, MarkerContent } from class="tk-string">"@/components/ui/map";

export function MapWithMarker() {
  return (
    <div className=class="tk-string">"h-[320px] overflow-hidden rounded-lg">
      <Map center={[-74.006, 40.7128]} zoom={11}>
        <MapMarker longitude={-74.006} latitude={40.7128}>
          <MarkerContent />
        </MapMarker>
      </Map>
    </div>
  );
}

自定义标记

使用 MarkerContent 的 children 自定义标记外观:

1234567
<MapMarker longitude={-74.006} latitude={40.7128}>
  <MarkerContent className=class="tk-string">"bg-blue-500 text-white rounded-full p-2">
    <svg className=class="tk-string">"w-4 h-4" viewBox=class="tk-string">"0 0 24 24" fill=class="tk-string">"currentColor">
      <path d=class="tk-string">"M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z" />
    </svg>
  </MarkerContent>
</MapMarker>

标记标签

使用 MarkerLabel 在标记上方或下方显示文字标签:

12345
<MapMarker longitude={-74.006} latitude={40.7128}>
  <MarkerContent>
    <MarkerLabel position=class="tk-string">"top">纽约市</MarkerLabel>
  </MarkerContent>
</MapMarker>

标记弹窗

使用 MarkerPopup 附加点击弹窗:

123456789
<MapMarker longitude={-74.006} latitude={40.7128}>
  <MarkerContent />
  <MarkerPopup closeButton>
    <div className=class="tk-string">"p-2">
      <h3 className=class="tk-string">"font-semibold">纽约市</h3>
      <p className=class="tk-string">"text-sm text-muted-foreground">美国人口最多的城市</p>
    </div>
  </MarkerPopup>
</MapMarker>

标记提示

使用 MarkerTooltip 添加悬停提示:

1234
<MapMarker longitude={-74.006} latitude={40.7128}>
  <MarkerContent />
  <MarkerTooltip>点击查看详情</MarkerTooltip>
</MapMarker>

可拖拽标记

MapMarker 继承了 MapLibre GL 的 MarkerOptions,支持拖拽:

DraggableMarker.tsx
1234567891011121314151617181920212223242526272829303132
import { Map, MapMarker, MarkerContent } from class="tk-string">"@/components/ui/map";
import { useState } from class="tk-string">"react";

export function DraggableMarker() {
  const [pos, setPos] = useState({
    longitude: -74.006,
    latitude: 40.7128,
  });

  return (
    <>
      <div className=class="tk-string">"h-[320px] overflow-hidden rounded-lg">
        <Map center={[pos.longitude, pos.latitude]} zoom={11}>
          <MapMarker
            longitude={pos.longitude}
            latitude={pos.latitude}
            draggable
            onDragEnd={(lngLat) => setPos({
              longitude: lngLat.lng,
              latitude: lngLat.lat,
            })}
          >
            <MarkerContent />
          </MapMarker>
        </Map>
      </div>
      <p className=class="tk-string">"mt-2 text-sm">
        位置:{pos.latitude.toFixed(4)}, {pos.longitude.toFixed(4)}
      </p>
    </>
  );
}

组件结构

1234567891011
<MapMarker longitude={...} latitude={...}>
  <MarkerContent>          {class=class="tk-string">"tk-comment">/* 标记视觉内容 */}
    <MarkerLabel />        {class=class="tk-string">"tk-comment">/* 文字标签 */}
  </MarkerContent>
  <MarkerPopup>            {class=class="tk-string">"tk-comment">/* 点击弹窗 */}
    弹窗内容
  </MarkerPopup>
  <MarkerTooltip>          {class=class="tk-string">"tk-comment">/* 悬停提示 */}
    提示文字
  </MarkerTooltip>
</MapMarker>

属性

MapMarker

继承了 MapLibre GL 的 MarkerOptions(排除 element)。

属性类型描述
longitudenumber标记经度
latitudenumber标记纬度
childrenReactNode标记子组件
onClick(e: MouseEvent) => void点击回调
onMouseEnter(e: MouseEvent) => void鼠标进入回调
onMouseLeave(e: MouseEvent) => void鼠标离开回调
onDragStart(lngLat: {lng, lat}) => void拖拽开始回调
onDrag(lngLat: {lng, lat}) => void拖拽中回调
onDragEnd(lngLat: {lng, lat}) => void拖拽结束回调

MarkerContent

属性类型描述
childrenReactNode自定义标记内容,默认为蓝色圆点
classNamestring标记容器的额外 CSS 类名

MarkerPopup

继承了 MapLibre GL 的 PopupOptions(排除 classNamecloseButton)。

属性类型描述
childrenReactNode弹窗内容
classNamestring弹窗容器的额外 CSS 类名
closeButtonboolean显示关闭按钮

MarkerTooltip

属性类型描述
childrenReactNode提示内容
classNamestring提示容器的额外 CSS 类名

MarkerLabel

属性类型默认值描述
childrenReactNode标签文字
classNamestring标签的额外 CSS 类名
position"top" | "bottom""top"标签相对于标记的位置

下一步

弹窗

MapPopup 组件