atchain-mapbox-vue
Version:
A Vue 3 MapBox component library with subway lines, stations, markers and polygons support. Zero dependencies except Vue 3 and Mapbox GL JS.
185 lines (155 loc) • 3.88 kB
text/typescript
/**
* MapBox 组件默认样式定义
* 提供独立的 CSS 样式,不依赖外部框架
*/
// 基础样式类名
export const STYLE_CLASSES = {
// MapBox 容器样式
mapBox: 'mapbox-container',
mapContainer: 'mapbox-map-container',
mapSlot: 'mapbox-slot',
// Marker 样式
marker: 'mapbox-marker',
markerImage: 'mapbox-marker-image',
// 通用样式
fullSize: 'mapbox-full-size',
absolute: 'mapbox-absolute',
relative: 'mapbox-relative',
pointer: 'mapbox-pointer'
} as const
// 默认 CSS 样式
export const DEFAULT_CSS = `
/* MapBox 容器样式 */
.mapbox-container {
position: relative;
width: 100%;
height: 100%;
}
.mapbox-map-container {
position: absolute;
width: 100%;
height: 100%;
}
.mapbox-slot {
position: absolute;
inset: 0;
z-index: 10;
pointer-events: none;
}
.mapbox-slot > * {
pointer-events: auto;
}
/* Marker 样式 */
.mapbox-marker {
position: absolute;
cursor: pointer;
width: 1rem;
height: 1rem;
display: flex;
justify-content: center;
align-items: center;
}
.mapbox-marker-image {
width: 100%;
height: 100%;
object-fit: cover;
}
/* 通用工具样式 */
.mapbox-full-size {
width: 100%;
height: 100%;
}
.mapbox-absolute {
position: absolute;
}
.mapbox-relative {
position: relative;
}
.mapbox-pointer {
cursor: pointer;
}
/* 自定义标记样式 */
.mapbox-custom-marker {
width: 117px;
height: 71px;
cursor: pointer;
background-size: contain;
background-repeat: no-repeat;
}
.mapbox-jinling-marker {
background-image: url('./images/mapbox/jinling.png');
}
.mapbox-jiali-marker {
background-image: url('./images/mapbox/jiali.png');
}
`
// 样式配置接口
export interface StyleConfig {
// 容器样式
containerClass?: string
containerStyle?: Record<string, string>
// 地图容器样式
mapContainerClass?: string
mapContainerStyle?: Record<string, string>
// 插槽样式
slotClass?: string
slotStyle?: Record<string, string>
}
// 标记样式配置接口
export interface MarkerStyleConfig {
// 标记容器样式
markerClass?: string
markerStyle?: Record<string, string>
// 图片样式
imageClass?: string
imageStyle?: Record<string, string>
// 尺寸配置
width?: string
height?: string
}
// 默认样式配置
export const DEFAULT_STYLE_CONFIG: StyleConfig = {
containerClass: STYLE_CLASSES.mapBox,
mapContainerClass: `${STYLE_CLASSES.mapContainer} ${STYLE_CLASSES.fullSize}`,
slotClass: STYLE_CLASSES.mapSlot
}
export const DEFAULT_MARKER_CONFIG: MarkerStyleConfig = {
markerClass: `${STYLE_CLASSES.marker} ${STYLE_CLASSES.absolute} ${STYLE_CLASSES.pointer}`,
imageClass: `${STYLE_CLASSES.markerImage}`,
width: '1rem',
height: '1rem'
}
/**
* 合并样式类名
*/
export const mergeClasses = (...classes: (string | undefined)[]): string => {
return classes.filter(Boolean).join(' ')
}
/**
* 合并样式对象
*/
export const mergeStyles = (...styles: (Record<string, string> | undefined)[]): Record<string, string> => {
return Object.assign({}, ...styles.filter(Boolean))
}
/**
* 注入默认样式到页面
*/
export const injectDefaultStyles = (): void => {
// 检查是否已经注入过样式
if (document.getElementById('mapbox-default-styles')) {
return
}
const styleElement = document.createElement('style')
styleElement.id = 'mapbox-default-styles'
styleElement.textContent = DEFAULT_CSS
document.head.appendChild(styleElement)
}
/**
* 移除默认样式
*/
export const removeDefaultStyles = (): void => {
const styleElement = document.getElementById('mapbox-default-styles')
if (styleElement) {
styleElement.remove()
}
}