<script setup name="BMapComp" lang="ts">
import { useElementBounding } from '@vueuse/core'
// import { loadBMap } from '.'
import { ref, onMounted, onBeforeUnmount } from 'vue';
const props = defineProps({
options: {
type: Object as PropType<Partial<{ center: { lng: number, lat: number }, zoom: number }>>,
default: () => ({}),
},
showNavigation: {
type: Boolean,
default: true,
},
showScale: {
type: Boolean,
default: true,
},
mapStyle: {
type: String,
default: '',
},
})
const emits = defineEmits(['init'])
let locMap: any = null
const mapviewRef = ref<HTMLDivElement>()
const defaultOptions = {
// center: { lng: 117.227267, lat: 31.820567 },
center: { lng: 116.404, lat: 39.915 },
zoom: 15,
}
const { width, height } = useElementBounding(mapviewRef)
watch([width, height], ([w, h]) => {
if (w * h === 0) return
if (locMap) locMap.checkResize()
})
async function loadBMap(): Promise<void> {
if (window.BMap) return;
const script = document.createElement('script');
script.src = `https://api.map.baidu.com/api?v=3.0&ak=8dkvITEPnYO7zxUsZ35yoZ5Hs1cVEP3u&callback=onBMapCallback`
document.body.appendChild(script);
}
// 创建扩散圆marker
function createSpreadSymbol(BMap: any, size = 100): any {
function SpreadSymbol(_size: any, _anchor: any) {
BMap.Symbol.call(this, _size, _anchor);
this.width = _size.width;
this.height = _size.height;
this.isReDraw = true;
}
SpreadSymbol.prototype = new BMap.Symbol();
SpreadSymbol.prototype.constructor = SpreadSymbol;
SpreadSymbol.prototype.add = function () {
const canvas = document.createElement('canvas');
canvas.width = this.width * 2;
canvas.height = this.height * 2;
this.context = canvas.getContext('2d');
this.isReDraw = false;
};
SpreadSymbol.prototype.render = function () {
const duration = 1500;
const t = (performance.now() % duration) / duration;
const radius = (this.width / 2) * 0.1;
const outerRadius = (this.width / 2) * 0.5 * t + radius;
const context = this.context;
context.save();
context.scale(2, 2);
context.clearRect(0, 0, this.width, this.height);
// 扩散圆
context.beginPath();
context.arc(this.width / 2, this.height / 2, outerRadius, 0, Math.PI * 2);
context.fillStyle = `rgba(38,1,252,${1 - t})`;
context.fill();
// 中间圆
context.beginPath();
context.arc(this.width / 2, this.height / 2, radius, 0, Math.PI * 2);
context.fillStyle = 'rgba(38,1,252, 1)';
context.strokeStyle = 'rgba(38,1,252, .1)';
context.lineWidth = 2 + 4 * (1 - t);
context.fill();
context.stroke();
context.restore();
this.data = context.getImageData(0, 0, this.context.canvas.width, this.context.canvas.height);
return true;
};
return SpreadSymbol;
}
// 初始化地图
async function initMap(): Promise<void> {
await loadBMap();
if (!mapviewRef.value) return;
const BMap = window.BMap;
const opts = { ...defaultOptions };
locMap = new BMap.Map(mapviewRef.value);
const point = new BMap.Point(opts.center.lng, opts.center.lat);
locMap.centerAndZoom(point, opts.zoom);
// 启用鼠标滚轮缩放功能
locMap.enableScrollWheelZoom(true);
// 添加扩散圆marker
const SpreadSymbol = createSpreadSymbol(BMap, 100);
const spreadSymbol = new SpreadSymbol(new BMap.Size(100, 100), new BMap.Size(50, 50));
const marker = new BMap.Marker(point, { icon: spreadSymbol, enableDragging: false });
locMap.addOverlay(marker);
}
// async function initMap() {
// await loadBMap()
// if (!mapviewRef.value) return
// const BMap = window.BMap
// const opts = { ...defaultOptions, ...props.options }
// locMap = new BMap.Map(mapviewRef.value)
// const point = new BMap.Point(opts.center.lng, opts.center.lat)
// locMap.centerAndZoom(point, opts.zoom)
// // 添加控件
// props.showNavigation && locMap.addControl(new BMap.NavigationControl())
// props.showScale && locMap.addControl(new BMap.ScaleControl())
// // 设置地图样式
// if (props.mapStyle) {
// locMap.setMapStyleV2({ styleId: props.mapStyle })
// }
// emits('init', locMap)
// }
onMounted(() => {
if (window.BMap) {
initMap()
} else {
const script = document.createElement('script')
script.src = `https://api.map.baidu.com/api?v=3.0&ak=8dkvITEPnYO7zxUsZ35yoZ5Hs1cVEP3u&callback=onBMapCallback`
window.onBMapCallback = initMap
document.body.appendChild(script)
}
})
onBeforeUnmount(() => {
if (locMap) {
locMap.clearOverlays()
locMap = null
}
})
</script>
<template>
<div
id="mapview"
ref="mapviewRef"
:style="{ ...($attrs.style as Recordable<string>) }"
/>
</template>
<style scoped>
.BMap_cpyCtrl,
.anchorBL {
display: none;
}
</style> 结局动态扩散圆marker未生效