这篇博客假定你对three.js有一定的了解。例如相机,透视,分组,材质等,不了解的换可以先到three官网山学习一下,看看他们的例子。动画对TweenMax有了解,会使用。
实现思路
1.three可以用一系列的二维点生成一个平面图,然后对平面图添加高度,生成3D图像。
2.three里面文字是贴图,将文字生成ttf格式的文件,用three的ttf加载工具加载进来,以贴图的方式放到地图上。
3.使用TweenMax添加入场动画。
4.对河南地图添加点击事件,加载各县市的地图。
实现结果效果图如下:
首先第一步要有行政区划数据。
获取数据的网址:datav.aliyun.com/portal/scho… 但是获取到数据以后获取到的是经纬度数据,没法直接使用。需要将经纬度数据转化为three所能识别的格式。获取的的数据格式如下:
{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"adcode":411402,"name":"梁园区","center":[115.65459,34.436553],"centroid":[115.597968,34.477146],"childrenNum":0,"level":"district","parent":{"adcode":411400},"subFeatureIndex":0,"acroutes":[100000,410000,411400]},"geometry":{"type":"MultiPolygon","coordinates":[[[[115.695315,34.337921],[115.690588,34.34178],[115.689275,34.344233],[115.688727,34.348011],[115.690297,34.365676],[115.691939,34.379239],[115.691939,34.385133],[115.690315,34.388391],[115.685589,34.391268],[115.681209,34.393122],[115.679476,34.394848],[115.678235,34.405771],[115.67526,34.410409],[115.67214,34.411168],[115.663144,34.411721],[115.657943,34.413827],[115.655845,34.415863],[115.655133,34.423228],[115.653874,34.424068],[115.645006,34.424171],[115.641009,34.42508],[115.635462,34.425288],[115.604113,34.425817],[115.582489,34.424931],[115.579058,34.424252],[115.579058,34.420673],[115.585226,34.414747],
怎么转换了,这里需要使用坐标系转换,将经纬度投影到平面上。具体转化方法我我写到了:gitee.com/feng-lianxi… 得到数据结果如下:[{"cityCenter":{"x":-4.279,"y":-0.889,"z":-0.255},"cityName":"中原区","bounder":[-3.053,0.778,0,-3.122,0.968,0,-3.234,1.162,0,-3.515,1.557,0,-3.682,1.758,0,-3.813,1.78,0,-3.929,1.736,0,-4.052,1.888,0,-4.238,1.899,0,-4.31,2.013,0,-4.225,2.119,0,-4.253,2.293,0,-4.449,2.431,0,-4.511,2.689,0,-4.556,2.773,0,-5.102,3.456,0,-5.136,3.476,0,-5.489,3.428,0,-5.603,3.487,0,-5.867,3.778,0,-5.926,3.952,0,-5.758,4.025,0,-5.853,4.167,0,-5.989,4.221,0,-6.406,4.14,0,-6.654,4.206,0,-6.731,4.312,0,-6.832,4.304,0,-6.82,4.489,0,-6.933,4.645,0,-6.951,4.894,0,-6.821,5.128,0,-6.898,5.317,0,-6.858,5.446,0,-6.891,5.635,0,-6.83,5.791,0,-7.016,6.214,0,-7.061,6.446,0,-7.859,7.181,0,-8.221,7.657,0,-8.434,8.233,0,-9.338,8.555,0,-9.811,8.733,0,-10.284,9.378,0,-10.615,9.355,0,-10.891,8.978,0,-11.16,8.714,0,-12.022,8.871,0,-12.594,9.217,0,-13.965,9.055,0,-14.48,8.664,0,-15.599,8.807,0,-15.658,8.439,0,-15.595,8.213,0,-15.363,7.799,0,-15.346,7.588,0,-15.564,7.364,0,-15.838,7.365,0,-16.276,7.288,0,-16.503,7.274,0,-16.85,7.347,0,-17.153,7.475,0,-17.391,7.554,0,-17.657,7.441,0,-17.756,7.315,0,-17.91,7.304,0,-18.103,7.332,0,-18.264,7.3,0,-18.542,7.149,0,-19.052,7.119,0,-19.309,7.016,0,-19.363,6.853,0,-19.34,6.622,0,-19.327,6.113,0,-19.445,5.84,
然后基于这些坐标点使用three就可以画出河南地图了,主要代码如下:
可以看到three将左边点处理成二维点,用这些二维的点生成形状,使用extrudesSetting,将这个形状添加高度,然后加上材质,就形成了三维的地图。
第二步将文字转化为ttf格式的文件
可以:pdfmall.com/zh/txt-to-t… 这个网站将txt文本转化为ttf。也可以自己从npm上找个生成包。这里有一点麻烦的地方。例如河南省有洛阳市,南阳市,里面都有“阳”字,生成字体文件的时候用一个阳字就行了。这是比较麻烦的需要一个一个排除。
我的办法是:将所有的各地市区名字写道一个文本里面,然后写一个脚本将这些文字去重。
import { TTFLoader } from '../examples/jsm/loaders/TTFLoader.js';
var ttfLoader = new TTFLoader();
这样文字就能贴到地图上。
第三步加入入场动画
就比较简单了。只要改变旋转和缩放就行了。
第四步添加点击事件
再three中点击事件是不好添加的,主要是通过点击的坐标点,判断是否选中了了某个实体。好在three.js给过了方法。raycaster = new THREE.Raycaster();用这个方法可以找到用户选中的目标。
找到位置后,确定要画的是哪一个地图,重新将步骤1-3运行一下就行了。代码地址:gitee.com/feng-lianxi… 。很抱歉代码跑不起来,因为我没法将所有的依赖都上传,最近用流量工作。有需要的可以加我微信联系:lianxiang_No1