概况如下:

1、SphereGeometry实现自转的地球;

2、THREE.CatmullRomCurve3实现球体线条地图点确定;

3、THREE.Math.degToRadMath.sinMath.cos实现地图经纬度与三位坐标x,y,z之间的转换;

4、MeshLine用于绘制线条;

5、canvas用于绘制球体世界地图贴图,通过THREE.CanvasTexture引入。

效果图如下:

预览地址:three.js通过canvas实现球体世界平面地图

初始化场景、相机、渲染器,设置相机位置,初始化光源,光源采用HemisphereLight,设置光源位置为场景中心位置,并将光源加入场景中。

  1. // 初始化场景
  2. var scene = new THREE.Scene();
  3. // 初始化相机,第一个参数为摄像机视锥体垂直视野角度,第二个参数为摄像机视锥体长宽比,
  4. // 第三个参数为摄像机视锥体近端面,第四个参数为摄像机视锥体远端面
  5. var camera = new THREE.PerspectiveCamera(20, dom.clientWidth / dom.clientHeight, 1, 100000);
  6. // 设置相机位置,对应参数分别表示x,y,z位置
  7. camera.position.set(0, 0, 200);
  8. var renderer = new THREE.WebGLRenderer({
  9. alpha: true,
  10. antialias: true
  11. });
  12. // 设置光照
  13. scene.add(new THREE.HemisphereLight('#ffffff', '#ffffff', 1));

设置场景窗口尺寸,并且初始化控制器,窗口尺寸默认与浏览器窗口尺寸保持一致,最后将渲染器加载到dom中。

  1. // 设置窗口尺寸,第一个参数为宽度,第二个参数为高度
  2. renderer.setSize(dom.clientWidth, dom.clientHeight);
  3. // 初始化控制器
  4. var orbitcontrols = new THREE.OrbitControls(camera,renderer.domElement);
  5. // 将渲染器加载到dom中
  6. dom.appendChild(renderer.domElement);

通过canvas定义地球材质。

  1. // canvas画地图函数,因为性能问题,线条不再canvas中实现,w表示宽度,h表示高度,worldPos表示世界地图经纬度信息
  2. var createCanvas = function (w, h, worldPos) {
  3. var canvas = document.createElement('canvas');
  4. canvas.width = w;
  5. canvas.height = h;
  6. var context = canvas.getContext('2d');
  7. var centerX = w / 2;
  8. var centerY = h / 2;
  9. var average = w / 360;
  10. // 绘制背景颜色
  11. context.fillStyle = earthBallColor;
  12. context.fillRect(0, 0, w, h);
  13. // canvas中绘制地图方法
  14. function canvasLineFun (childrenPosition) {
  15. context.fillStyle = earthBallPlaneColor;
  16. context.moveTo(centerX + childrenPosition[0][0] * average, centerY - childrenPosition[0][1] * average);
  17. childrenPosition.forEach(function (posItem) {
  18. context.lineTo(centerX + posItem[0] * average, centerY - posItem[1] * average);
  19. })
  20. context.closePath();
  21. context.fill();
  22. }
  23. worldPos.forEach(function (item) {
  24. canvasLineFun(item);
  25. })
  26. return canvas;
  27. }

定义地球及其材质,地球通过SphereGeometry来实现,通过THREE.CanvasTexture来引入canvas创建的贴图。

  1. // 创建地球
  2. earthBall = new THREE.Mesh(new THREE.SphereGeometry(earthBallSize, 50, 50), new THREE.MeshBasicMaterial({
  3. map: new THREE.CanvasTexture(createCanvas(2048, 1024, worldGeometry)),
  4. side: THREE.FrontSide
  5. }));
  6. scene.add(earthBall);

标记地点经纬度坐标与三维x,y,z坐标转换方法。

  1. // 经纬度转换函数,longitude表示经度,latitude表示唯独,radius表示球体半径
  2. var getPosition = function (longitude, latitude, radius) {
  3. // 将经度,纬度转换为rad坐标
  4. var lg = THREE.Math.degToRad(longitude);
  5. var lt = THREE.Math.degToRad(latitude);
  6. var temp = radius * Math.cos(lt);
  7. // 获取x,y,z坐标
  8. var x = temp * Math.sin(lg);
  9. var y = radius * Math.sin(lt);
  10. var z = temp * Math.cos(lg);
  11. return {
  12. x: x,
  13. y: y,
  14. z: z
  15. }
  16. }

绘制世界地图线条方法

  1. // 绘制世界地图线条函数
  2. var drawWorldLine = function (pos, identify) {
  3. var posArray = [];
  4. pos.forEach(function (item) {
  5. var pointPosition = getPosition(item[0] + 90, item[1], earthBallSize);
  6. posArray.push(new THREE.Vector3(pointPosition.x, pointPosition.y, pointPosition.z));
  7. })
  8. // 绘制的线条需要关闭,第二个参数默认为false,表示不关闭
  9. var curve = new THREE.CatmullRomCurve3(posArray, true);
  10. var points = curve.getPoints(500);
  11. var geometry = new THREE.Geometry().setFromPoints(points);
  12. // 定义线条
  13. var line = new MeshLine();
  14. line.setGeometry(geometry);
  15. // 定义线条材质
  16. var material = new MeshLineMaterial({
  17. color: worldLineColor,
  18. lineWidth: worldLineWidth
  19. })
  20. // 绘制地图
  21. lineGeometryObj['lineGeometry' + identify] = new THREE.Mesh(line.geometry, material);
  22. // 将地图加入场景
  23. scene.add(lineGeometryObj['lineGeometry' + identify])
  24. }

获取世界地图经纬度信息及计算绘制球体地图参数方法

  1. // 获取世界经纬度信息函数
  2. var getWorldGeometry = function () {
  3. $.ajax({
  4. type : "GET", //提交方式
  5. url : "./code/world.json",
  6. async: false,
  7. success : function(response) {//返回数据根据结果进行相应的处理
  8. worldGeometry = [];
  9. // 绘制世界地图
  10. response.features.forEach(function (worldItem, worldItemIndex) {
  11. var length = worldItem.geometry.coordinates.length;
  12. var multipleBool = length > 1 ? true : false;
  13. worldItem.geometry.coordinates.forEach(function (worldChildItem, worldChildItemIndex) {
  14. if (multipleBool) {
  15. // 值界可以使用的经纬度信息
  16. if (worldChildItem.length && worldChildItem[0].length == 2) {
  17. worldGeometry.push(worldChildItem);
  18. }
  19. // 需要转换才可以使用的经纬度信息
  20. if (worldChildItem.length && worldChildItem[0].length > 2) {
  21. worldChildItem.forEach(function (countryItem, countryItenIndex) {
  22. worldGeometry.push(countryItem);
  23. })
  24. }
  25. } else {
  26. var countryPos = null;
  27. if (worldChildItem.length > 1) {
  28. countryPos = worldChildItem;
  29. } else {
  30. countryPos = worldChildItem[0];
  31. }
  32. if (countryPos) {
  33. worldGeometry.push(countryPos);
  34. }
  35. }
  36. })
  37. })
  38. }
  39. })
  40. }

球体地图线条通过position值来实现位置的确认,动画使用requestAnimationFrame来实现。

  1. // 执行函数
  2. var render = function () {
  3. scene.rotation.y -= 0.01;
  4. renderer.render(scene, camera);
  5. orbitcontrols.update();
  6. requestAnimationFrame(render);
  7. }

three.js通过canvas实现球体世界平面地图的更多相关文章

  1. three.js实现世界3d地图

    概况如下: 1.THREE.Shape绘制世界地图平面地图: 2.THREE.ExtrudeGeometry将绘制的平面沿着Z轴拉伸,实现3d效果: 效果图如下: 预览地址:three.js实现世界3 ...

  2. Three.js - 走进3D的奇妙世界

    本文将通过Three.js的介绍及示例带我们走进3D的奇妙世界. 文章来源:宜信技术学院 & 宜信支付结算团队技术分享第6期-支付结算部支付研发团队前端研发高级工程师-刘琳<three. ...

  3. Particles.js基于Canvas画布创建粒子原子颗粒效果

    文章目录 使用方法 自定义参数 相关链接 Particles.js是一款基于HTML5 Canvas画布的轻量级粒子动画插件,可以设置粒子的形状.旋转.分布.颜色等属性,还可以动态添加粒子,效果非常炫 ...

  4. 原生js实现canvas气泡冒泡效果

    说明: 本文章主要分为ES5和ES6两个版本 ES5版本是早期版本,后面用ES6重写优化的,建议使用ES6版本. 1, 原生js实现canvas气泡冒泡效果的插件,api丰富,使用简单2, 只需引入J ...

  5. captcha.js一个生成验证码的插件,使用js和canvas生成

    一.captcha`captcha.js`是一个生成验证码的插件,使用js和canvas生成的,确保后端服务被暴力攻击,简单判断人机以及系统的安全性,体积小,功能多,支持配置. 验证码插件内容,包含1 ...

  6. Qt的QWebChannel和JS、HTML通信/交互驱动百度地图

    Qt的QWebChannel和JS.HTML通信/交互驱动百度地图 0 前言 我一个研究嵌入式的,不知道怎么就迷上了上位机,接了几个项目都是关于Qt,这个项目还是比较经典的,自己没事儿的时候也进行研究 ...

  7. Python 绘制2016世界GDP地图

    2016世界GDP地图 从https://datahub.io/core/gdp#data下载得到json文件. # country_code.py 获取国家二字代码 # 从pygal.maps.wo ...

  8. Three.js基础探寻四——立方体、平面与球体

    前面简单介绍了webGL和Three.js的背景以及照相机的设定,接下来介绍一些Three.js中的几何形状. 1.立方体 虽然这一形状的名字叫立方体(CubeGeometry),但它其实是长方体,也 ...

  9. three.js学习:纹理Texture之平面纹理

    index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

随机推荐

  1. Linux常见指令大全

    转载自https://www.cnblogs.com/caozy/p/9261224.html 前言 本文特点 授之以渔:了解命令学习方法.用途:不再死记硬背,拒绝漫无目的: 准确无误:所有命令执行通 ...

  2. 集群环境下,你不得不注意的ASP.NET Core Data Protection 机制

    引言 最近线上环境遇到一个问题,就是ASP.NET Core Web应用在单个容器使用正常,扩展多个容器无法访问的问题.查看容器日志,发现以下异常: System.Security.Cryptogra ...

  3. Asp.Net MVC Web API 中Swagger教程,使用Swagger创建Web API帮助文件

    什么是Swagger? Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件的方法 ...

  4. C# List集合 GroupBy分组

    var grpBalance = listBalance.GroupBy(m => new { m.MerChantId, m.Name}).Distinct().Select(t => ...

  5. Java生鲜电商平台-生鲜系统中商品订单系统售后系统设计

    Java生鲜电商平台-生鲜系统中商品订单系统售后系统设计(服务订单履约系统) 说明: 电商之下,我们几乎能从电商平台上买到任何我们日常需要的商品,但是对于很多商品来说,用户购买发货后,只是整个交易流程 ...

  6. oop面向对象【接口、多态】

    今日内容 1.接口 2.三大特征——多态 3.引用类型转换 教学目标 1.写出定义接口的格式 2.写出实现接口的格式 3.说出接口中成员的特点 4.能够说出使用多态的前提条件 5.理解多态的向上转型 ...

  7. linux I/O重定向及管道

    一,I/O重定向 重定向正常输出 > :覆盖以存在文件的内容,很危险的操作 >>:如果文件已经存在,则是在原内容的最后追加. 可以禁止>的覆盖行为,使用set -C.只在当前会 ...

  8. Scrapy框架(一)

    Scrapy框架(一) 国内镜像源: 阿里云 http://mirrors.aliyun.com/pypi/simple/ 中国科技大学 https://pypi.mirrors.ustc.edu.c ...

  9. SpringSession 独立使用

    疯狂创客圈 Java 高并发[ 亿级流量聊天室实战]实战系列 [博客园总入口 ] 架构师成长+面试必备之 高并发基础书籍 [Netty Zookeeper Redis 高并发实战 ] 前言 Crazy ...

  10. Beeline里面执行hive脚本 函数nvl2()与replace()报错

    Beeline里面执行hive脚本函数nvl2()与replace()报错 写脚本的时候是在impala里面执行的,都正常,但是转换为调度的时候是在beeline里面执行的 就会有问题了. 详情如下: ...