一、效果说明

本文将实现一个有趣的小功能:
-
🖱️ 点击地图 → 播放点击音效
-
🗺️ 拖动地图 → 播放循环音效
-
⛔ 停止拖动 → 停止音效
适用于:
-
GIS系统交互增强
-
无人机巡检系统
-
可视化项目体验优化
二、技术栈
-
Vue3(Composition API)
-
OpenLayers
-
原生 Audio API
三、实现思路
核心逻辑非常简单:
| 操作 | 触发事件 | 行为 |
|---|---|---|
| 点击地图 | click |
播放音效 |
| 开始拖动 | movestart |
播放循环音效 |
| 结束拖动 | moveend |
停止音效 |
四、完整代码
javascript
<!--
* @Author: 彭麒
* @Date: 2026/3/30
* @Email: 1062470959@qq.com
* @Description: 此源码版权归吉檀迦俐所有,可供学习和借鉴或商用。
-->
<template>
<div class="container">
<div class="w-full flex justify-center flex-wrap">
<div class="font-bold text-[24px]">
Vue3 + Openlayers:点击/拖动播放音频
</div>
</div>
<div id="map"></div>
</div>
</template>
<script setup>
import { onMounted, ref } from 'vue'
import 'ol/ol.css'
import { Map, View } from 'ol'
import Tile from 'ol/layer/Tile'
import XYZ from 'ol/source/XYZ'
const map = ref(null)
const clickAudio = new Audio('https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3')
const moveAudio = new Audio('https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3')
// 循环播放(拖动用)
moveAudio.loop = true
const initMap = () => {
const raster = new Tile({
source: new XYZ({
url: 'https://www.google.com/maps/vt?lyrs=m&gl=en&x={x}&y={y}&z={z}',
crossOrigin: 'anonymous'
})
})
map.value = new Map({
target: 'map',
layers: [raster],
view: new View({
projection: 'EPSG:3857',
center: [2617200, 5951081],
zoom: 5
})
})
// ✅ 点击播放音效
map.value.on('click', () => {
clickAudio.currentTime = 0 // 关键:支持连续点击
clickAudio.play()
})
// ✅ 开始拖动
map.value.on('movestart', () => {
if (moveAudio.paused) {
moveAudio.currentTime = 0
moveAudio.play()
}
})
// ✅ 拖动结束
map.value.on('moveend', () => {
moveAudio.pause()
moveAudio.currentTime = 0
})
}
onMounted(() => {
initMap()
})
</script>
<style scoped>
.container {
width: 840px;
height: 590px;
margin: 50px auto;
border: 1px solid #42b983;
}
#map {
width: 800px;
height: 460px;
margin: 0 auto;
border: 1px solid #42b983;
}
</style>
五、关键知识点解析
1️⃣ Vue3 Composition API
const map = ref(null)
-
使用
ref替代data -
使用
onMounted替代mounted
2️⃣ OpenLayers 事件机制
map.value.on('click', handler)
map.value.on('movestart', handler)
map.value.on('moveend', handler)
说明:
-
click:点击地图 -
movestart:开始拖动 -
moveend:拖动结束
3️⃣ Audio API 使用
const audio = new Audio('xxx.mp3')
audio.play()
audio.pause()
六、常见问题
❗ 1. 连续点击没有声音
clickAudio.currentTime = 0
👉 必须重置播放时间
❗ 2. 音频叠加播放
if (moveAudio.paused)
👉 防止重复触发播放
❗ 3. 浏览器不播放音频
原因:
-
浏览器限制自动播放
-
必须用户交互(点击/拖动)
👉 本案例已符合要求 ✔
❗ 4. 报错:NotSupportedError
The element has no supported sources
原因:
-
音频链接失效
-
被跨域拦截
-
不是 MP3 文件
👉 建议:
✔ 使用本地音频
✔ 或使用稳定 HTTPS 音频资源
七、进阶优化
✅ 1. 使用本地音频(生产环境)
import clickMp3 from '@/assets/audio/click.mp3'
const clickAudio = new Audio(clickMp3)
✅ 2. 封装音频 Hook
const useAudio = () => {
const play = (audio) => {
audio.currentTime = 0
audio.play()
}
return { play }
}
✅ 3. 场景升级(推荐方向)
-
🚁 无人机飞行音效
-
📡 雷达扫描音
-
📢 AI语音播报
八、总结
本文实现了一个简单但非常实用的功能:
👉 让地图"有声音"
提升点:
-
交互更真实
-
系统更有沉浸感
-
非常适合 GIS / 可视化系统
九、后续拓展
如果你正在做:
-
巡检系统
-
三维 GIS(Cesium)
-
数字孪生
👉 可以进一步结合:
-
空间音效
-
事件驱动音频
-
语音播报系统
如果觉得有帮助,欢迎点赞 👍 收藏 ⭐ 关注 🚀
后续会持续更新 Vue3 + GIS 实战内容!