mosaicmap/app/map-context.tsx
2025-07-17 22:57:07 +08:00

106 lines
2.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client'
import React, { createContext, useContext, useRef, useState, ReactNode } from 'react'
import type { Map } from 'maplibre-gl'
// 定义MapContext的类型
interface MapContextType {
mapRef: React.RefObject<Map | null>
setMap: (map: Map) => void
flyTo: (options: { center: [number, number]; zoom: number; duration?: number }) => void
zoomIn: () => void
zoomOut: () => void
zoomTo: (zoom: number) => void
reset: () => void
isMapReady: boolean
}
// 创建Context
const MapContext = createContext<MapContextType | undefined>(undefined)
// Provider组件的Props类型
interface MapProviderProps {
children: ReactNode
}
// MapProvider组件
export function MapProvider({ children }: MapProviderProps) {
const mapRef = useRef<Map | null>(null)
const [isMapReady, setIsMapReady] = useState(false)
const setMap = (map: Map) => {
mapRef.current = map;
setIsMapReady(true);
}
const flyTo = (options: { center: [number, number]; zoom: number; duration?: number }) => {
if (mapRef.current) {
mapRef.current.flyTo({
...options,
duration: options.duration || 1000
})
}
}
const zoomIn = () => {
if (mapRef.current) {
mapRef.current.zoomIn()
}
}
const zoomOut = () => {
if (mapRef.current) {
mapRef.current.zoomOut()
}
}
const zoomTo = (zoom: number) => {
if (mapRef.current) {
mapRef.current.zoomTo(zoom)
}
}
const reset = () => {
if (mapRef.current) {
mapRef.current.flyTo({
center: [103.851959, 1.290270],
zoom: 11,
duration: 1000
})
}
}
const value: MapContextType = {
mapRef,
setMap,
flyTo,
zoomIn,
zoomOut,
zoomTo,
reset,
isMapReady
}
return (
<MapContext.Provider value={value}>
{children}
</MapContext.Provider>
)
}
// 自定义Hook用于使用MapContext
export function useMap() {
const context = useContext(MapContext)
if (context === undefined) {
throw new Error('useMap必须在MapProvider内部使用')
}
return context
}
// 便捷的Hook直接返回map实例
export function useMapInstance() {
const { mapRef } = useMap()
return mapRef.current
}