高德地图嵌入到threejs全景中的踩坑指南

本文探讨了THREE.js的OrbitControls与内嵌高德地图的触摸事件冲突问题。通过修改OrbitControls的事件处理,实现触摸事件在三维场景与地图间的正确传递,避免了事件阻止的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目中用到了THREE.OrbitControls, 还要内嵌HTML结构(高德地图), 我这边采用的是THREE.CSS3DObject. 这导致了一个问题--由于OrbitControls必须将事件绑定到container及以上的DOM中, 这样就将CSS3DObject中的DOM的触摸事件被阻止了.

经过思考及测试, 只需将OrbitControlsonTouchMoveevent.preventDefault()event.stopPropagation()注释掉, 并为CSS3DObject.element添加两个事件处理程序


// 必须将OrbitControls中的onTouchMove中的event.preventDefault()和event.stopPropagation()去掉, 猜测是因为高德将移动事件绑定到了document或window

css3dObject.element.addEventListener("touchstart", e => {
  // 这儿必须阻止冒泡, 否则会导致网页和整个场景(Scene)一起动作
  // 但由于这儿不能preventDefault()的同时还stopPropagation(), 导致不能阻止该节点上移动端浏览器的滑动默认前进/后退动作.
  e.stopPropagation()
})

复制代码

转载于:https://juejin.im/post/5c4974f2e51d4505171c81cc

### 集成three.js 3D模型到高德地图 为了在高德地图中引入并展示three.js创建的3D模型,需先完成必要的环境搭建工作。这涉及到安装所需的库文件以及配置开发环境。 #### 安装依赖包 确保项目环境中已安装`three`、`@tweenjs/tween.js`用于动画效果处理、针对不同类型的3D模型加载器如`three-obj-mtl-loader`以及其他特定需求下的额外插件[^3]。对于高德地图API的支持,则通过安装`@amap/amap-jsapi-loader`实现。 ```bash npm install three @tweenjs/tween.js three-obj-mtl-loader @amap/amap-jsapi-loader ``` #### 初始化地图容器与Three场景设置 接下来,在HTML页面内定义一个DOM元素作为地图显示区域的同时也为Three.js准备渲染上下文。JavaScript代码部分负责初始化Amap实例并将之绑定至上述提到的地图容器上;与此同时构建Three.js的核心组件——Scene(场景)、Camera(相机)和Renderer(渲染器),以便后续操作能够顺利进行[^1]。 ```javascript import * as THREE from 'three'; // 导入其他必要模块... const container = document.getElementById('mapContainer'); AMapLoader.load({ key: "Your_AMap_API_Key", version: "2.0" }).then((AMap) => { const map = new AMap.Map(container, { ... }); // Three.js setup... }); ``` #### 创建自定义图层类继承于`THREE.Object3D` 为了让Three.js的对象可以无缝嵌入高德地图当中,建议编写一个继承自`THREE.Object3D`的新类,该类内部维护着指向对应地理坐标的属性,并重写其更新矩阵的方法以适应地理位置变化带来的影响。 ```typescript class GeoObject extends THREE.Object3D { private lnglat: number[]; constructor(lnglat: number[]) { super(); this.lnglat = lnglat; } updateMatrix() { // 更新逻辑基于lnglat转换为WebGL坐标系下位置向量... super.updateMatrix(); } } ``` #### 将GeoObject实例放置于适当的位置 当有了上述准备工作之后就可以把具体的三维物体比如建筑物、车辆或者其他任何想要呈现出来的对象转化为`GeoObject`的形式再添加进scene里去了。记得调用各自的`updateMatrix()`方法使它们能够在正确的地方显现出来。 #### 动态加载外部资源 如果计划导入由第三方工具制作好的复杂几何体或角色模型的话,那么就不得不提及到之前所提到过的那些专门用来解析OBJ/MTL/GTLF等格式数据流的loader们了。这里给出一段简单的例子说明怎样异步获取远程服务器上的gltf文件并将其内容注入到当前运行中的程序之中去[^2]: ```javascript const loader = new GLTFLoader(); loader.load( '/models/myModel.gltf', function (gltf) { scene.add(gltf.scene); }, undefined, function (error) { console.error(error); } ); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值