前端3D地球的实现方式

您所在的位置:网站首页 三维立体地球旋转手表 前端3D地球的实现方式

前端3D地球的实现方式

2024-01-14 13:34| 来源: 网络整理| 查看: 265

     想到3D,我最想想到的是WebGL,但是通过对WebGL的学习了解,实现地球效果很难达到。

1、用echarts gl实现

    其次还有echarts GL,做过图表的应该知道echarts,echarts是一个不错的做图表的框架,他安装简单,使用便捷。echarts GL是echarts用来实现三维图标的工具,他是可以实现3D的效果的。

实现步骤如下:

1、从官网上下载echarts.min.js和echarts-gl.min.js文件,引入到html 页面中

//后续会用到,这里先引入

2、为地球创建一个id为earth的div容器

3、下面就是关键的js代码实现功能了,我们先创建一个地球

var dom = document.getElementById("earth") //关键的三步:创建一个echarts实例、设置属性option、将实例和option联动 var myChart = echarts.init(dom); option = { globe:{ show:true, shading:"color", //视角控制: viewControl:{ //projection:"orthographic", rotateSensitivity:0, //鼠标旋转灵敏度 zoomSensitivity:0,//鼠标缩放灵敏度 autoRotate:true,//地球是否自传 autoRotateAfterStill:0.001,//鼠标停止后多久恢复旋转(为0时暂停后不恢复旋转) //alpha:160,//视角绕 x 轴,即上下旋转的角度 //beta:-20,//视角绕 y 轴,即左右旋转的角度。 targetCoord: [116.46, 39.92]//定位到哪里 } }, }; if (option && typeof option === "object") { myChart.setOption(option, true); }

4、现在只是创建了一个球,但是没有地图信息,echarts还提供了一些地图信息,有世界地图和中国地球等,我们将这些信息绘制到地球上。现在我们有了球了,还差一个贴图,我们可以自由通过canvas绘制。

// 使用 echarts 绘制世界地图的实例作为纹理 var canvas = document.createElement('canvas'); var mapChart = echarts.init(canvas, null, { width: 4096, height: 2048 }); mapChart.setOption({ series : [ { type: 'map', map: 'world',//world是html页面引入的地图文件名字 // 绘制完整尺寸的 echarts 实例 top: 0, left: 0, right: 0, bottom: 0, silent:true,//图形是否不响应和触发鼠标事件,默认为 false,即响应和触发鼠标事件。 boundingCoords: [[-180, 90], [180, -90]], label:{ textStyle:{ color:"#fff", fontSize:50 } }, emphasis:{ itemStyle:{ color:"#2038cc" } } } ] });

5、把自己写的地图贴图效果放到地球上,完整代码如下

var dom = document.getElementById("earth") var myChart = echarts.init(dom); // 使用 echarts 绘制世界地图的实例作为纹理 var canvas = document.createElement('canvas'); var mapChart = echarts.init(canvas, null, { width: 4096, height: 2048 }); mapChart.setOption({ series : [ { type: 'map', map: 'world', // 绘制完整尺寸的 echarts 实例 top: 0, left: 0, right: 0, bottom: 0, silent:true,//图形是否不响应和触发鼠标事件,默认为 false,即响应和触发鼠标事件。 boundingCoords: [[-180, 90], [180, -90]], label:{ textStyle:{ color:"#fff", fontSize:50 } }, emphasis:{ itemStyle:{ color:"#2038cc" } } } ] }); option = { globe:{ show:true, baseTexture: mapChart, //heightTexture:mapChart, shading:"color", //视角控制 viewControl:{ //projection:"orthographic", /*damping:0,*/ rotateSensitivity:0, //鼠标旋转灵敏度 zoomSensitivity:0,//鼠标缩放灵敏度 autoRotate:true, autoRotateAfterStill:0.001,//鼠标停止后多久恢复旋转(为0时暂停后不恢复旋转) //alpha:160,//视角绕 x 轴,即上下旋转的角度 //beta:-20,//视角绕 y 轴,即左右旋转的角度。 targetCoord: [116.46, 39.92]//定位到哪里 } }, }; if (option && typeof option === "object") { myChart.setOption(option, true); }

此时实现的效果如下:

              

如果你想要修改地球上区域颜色,可以直接在创建地图的series中添加 

itemStyle:{ normal:{ areaColor:"rgba(0,0,152,0.5)" } } 2、用cesium实现

   用echarts GL实现的效果不是很满意,继续尝试,发现了cesium,cesium可以直接调用地图。

 1、cesium引入的框架相对比较繁琐,可以下载了cesium后把Build\CesiumUnminified的内容全部拷贝到你的项目里。这个时候你会发现改文件很大,不是很适合,其实里面有很大是用不到的,可以删除。(怎么保留自己有用的呢?当你功能实现后,你可以把cesium.js文件先移出项目,运行后通过控制台看找不到的文件,把这些文件移入项目,多次执行,一直都没有错误为止)。

2、开始实现功能,先在html页面引入cesium.js文件,引入Widgets/widgets.css样式,并创建一个id为cesiumEarth的div容器。

3、下面开始创建地球,cesium的优点是可以引入地图文件,这里引入了天地图

var viewer = new Cesium.Viewer( 'cesiumEarth', { //需要进行可视化的数据源的集合 animation: false, //是否显示动画控件 homeButton : false,//是否显示Home按钮 fullscreenButton : false,//是否显示全屏按钮 baseLayerPicker: false, //是否显示图层选择控件 geocoder: false, //是否显示地名查找控件 timeline: false, //是否显示时间线控件 sceneModePicker: false, //是否显示投影方式控件 navigationHelpButton: false, //是否显示帮助信息控件 infoBox: false, //是否显示点击要素之后显示的信息 //天地图是官方开元的地图,不需要密钥 imageryProvider: new Cesium.WebMapTileServiceImageryProvider({ url: "http://{s}.tianditu.com/img_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles", layer: "img", style: "default", format: "tiles", tileMatrixSetID: "w", credit:new Cesium.Credit('天地图全球影像服务'), subdomains:['t0',"t1","t2","t3","t4","t5","t6","t7"], maximumLevel:18, show: false }) } );

 

//(根据太阳/月亮位置启用照明) /*scene.globe.enableLighting = true;*/

注:地图服务有矢量图和影像服务可以根据你的需求选择,上面引入的是影像服务,下面是矢量图服务

imageryProvider : new Cesium.WebMapTileServiceImageryProvider({ url: "http://t0.tianditu.com/vec_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=vec&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles", layer: "tdtVecBasicLayer", style: "default", format: "image/jpeg", tileMatrixSetID: "GoogleMapsCompatible", show: false })

4、这个时候你会发现,只有一个地球,没有地名的标注,我们还需要引入中文地名标注。

//全球影像中文注记服务 viewer.imageryLayers.addImageryProvider(new Cesium.WebMapTileServiceImageryProvider({ url: "http://t0.tianditu.com/cia_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=cia&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default.jpg", layer: "tdtAnnoLayer", style: "default", format: "image/jpeg", tileMatrixSetID: "GoogleMapsCompatible", show: false })); //全球矢量中文标注服务 viewer.imageryLayers.addImageryProvider(new Cesium.WebMapTileServiceImageryProvider({ url: "http://t0.tianditu.com/cva_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=cva&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default.jpg", layer: "tdtAnnoLayer", style: "default", format: "image/jpeg", tileMatrixSetID: "GoogleMapsCompatible" }));

5、这个时候看着比较美观了。框架中有很多控件,如果不需要可以通过上面3中设置为false,就不在显示。但是左下角的logo和连接是没办法去掉的,但是可以通过修改css样式进行修改

.cesium-viewer-bottom{ display: none; }

6、项目本身就有鼠标操作的事件,有时候我们会需要取消这些事件自己定义。

// 禁用默认的事件处理程序 // 如果为真,则允许用户旋转相机。如果为假,相机将锁定到当前标题。此标志仅适用于2D和3D。 scene.screenSpaceCameraController.enableRotate = false; // 如果为true,则允许用户平移地图。如果为假,相机将保持锁定在当前位置。此标志仅适用于2D和Columbus视图模式。 scene.screenSpaceCameraController.enableTranslate = false; // 如果为真,允许用户放大和缩小。如果为假,相机将锁定到距离椭圆体的当前距离 scene.screenSpaceCameraController.enableZoom = false; // 如果为真,则允许用户倾斜相机。如果为假,相机将锁定到当前标题。这个标志只适用于3D和哥伦布视图。 scene.screenSpaceCameraController.enableTilt = false; // 如果为true,则允许用户使用免费外观。如果错误,摄像机视图方向只能通过转换或旋转进行更改。此标志仅适用于3D和哥伦布视图模式。 scene.screenSpaceCameraController.enableLook = false; //自定义鼠标事件 var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); // 接收用户鼠标(手势)事件 // 处理鼠标按下事件 handler.setInputAction(function(movement) { // movement: 接收值为一个对象,含有鼠标单击的x,y坐标 // 设置鼠标当前位置 mousePosition = startMousePosition = Cesium.Cartesian3.clone(movement.position); }, Cesium.ScreenSpaceEventType.LEFT_DOWN); // 处理鼠标移动事件 handler.setInputAction(function(movement) { // 更新鼠标位置 mousePosition = movement.endPosition; }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); // 处理鼠标左键弹起事件 handler.setInputAction(function(position) { //此时鼠标位置position }, Cesium.ScreenSpaceEventType.LEFT_UP);

7、控制相机运动

camera.flyTo( { destination : Cesium.Cartesian3.fromDegrees(nowPoint.lng, nowPoint.lat, cameraH ),//使用WGS84 orientation : { heading : Cesium.Math.toRadians( 0 ), pitch : Cesium.Math.toRadians( -90 ), roll : Cesium.Math.toRadians( 0 ) }, duration : 3,//动画持续时间 complete : function()//飞行完毕后执行的动作 { // addEntities(); canCont=true; canFly=true; }, pitchAdjustHeight: -90, // 如果摄像机飞越高于该值,则调整俯仰俯仰的俯仰角度,并将地球保持在视口中。 maximumHeight:5000 // 相机最大飞行高度 } );

8、通过点击获取位置,并将相机移动过去

function flyToPoint(point) { //将屏幕坐标转换为世界坐标 var pick= new Cesium.Cartesian2(point.x,point.y); var cartesian = scene.globe.pick(viewer.camera.getPickRay(pick), scene); //世界坐标转地理坐标(弧度) var cartographic = scene.globe.ellipsoid.cartesianToCartographic(cartesian); //地理坐标(弧度)转经纬度坐标 var nowPoint={lng:cartographic.longitude / Math.PI * 180, lat:cartographic.latitude / Math.PI * 180}; //获取当前相机高度 var cameraH=Math.ceil(viewer.camera.positionCartographic.height); if(cameraH>1000000){ cameraH=Math.ceil(cameraH/5); }else if(cameraH>10000){ cameraH=Math.ceil(cameraH/4); }else if(cameraH>2000){ cameraH=cameraH-2500 } if(cameraH>=2000 && canFly){ canFly=false; camera.flyTo( { destination : Cesium.Cartesian3.fromDegrees(nowPoint.lng, nowPoint.lat, cameraH ),//使用WGS84 orientation : { heading : Cesium.Math.toRadians( 0 ), pitch : Cesium.Math.toRadians( -90 ), roll : Cesium.Math.toRadians( 0 ) }, duration : 3,//动画持续时间 complete : function()//飞行完毕后执行的动作 { }, pitchAdjustHeight: -90, // 如果摄像机飞越高于该值,则调整俯仰俯仰的俯仰角度,并将地球保持在视口中。 maximumHeight:5000 // 相机最大飞行高度 } ); } }

创建的3D地球效果图如下:  



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3