概况如下
1、SphereGeometry实现自转的地球;
2、THREE.CatmullRomCurve3实现球体线条地图点确定;
3、THREE.Math.degToRadMath.sinMath.cos实现地图经纬度与三位坐标x,y,z之间的转换;
4、MeshLine用于绘制线条;
5、canvas用于绘制球体世界地图贴图,通过THREE.CanvasTexture引入。

效果图如下:

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

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

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

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

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

通过canvas定义地球材质。

// canvas画地图函数,因为性能问题,线条不再canvas中实现,w表示宽度,h表示高度,worldPos表示世界地图经纬度信息
var createCanvas = function (w, h, worldPos) {var canvas = document.createElement('canvas');canvas.width = w;canvas.height = h;var context = canvas.getContext('2d');var centerX = w / 2;var centerY = h / 2;var average = w / 360;// 绘制背景颜色context.fillStyle = earthBallColor;context.fillRect(0, 0, w, h);// canvas中绘制地图方法function canvasLineFun (childrenPosition) {context.fillStyle = earthBallPlaneColor;context.moveTo(centerX + childrenPosition[0][0] * average, centerY - childrenPosition[0][1] * average);childrenPosition.forEach(function (posItem) {context.lineTo(centerX + posItem[0] * average, centerY - posItem[1] * average);})context.closePath();context.fill();}worldPos.forEach(function (item) {canvasLineFun(item);})return canvas;
}

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

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

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

// 经纬度转换函数,longitude表示经度,latitude表示唯独,radius表示球体半径
var getPosition = function (longitude, latitude, radius) {// 将经度,纬度转换为rad坐标var lg = THREE.Math.degToRad(longitude);var lt = THREE.Math.degToRad(latitude);var temp = radius * Math.cos(lt);// 获取x,y,z坐标var x = temp * Math.sin(lg);var y = radius * Math.sin(lt);var z = temp * Math.cos(lg);return {x: x,y: y,z: z}
}

绘制世界地图线条方法

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

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

// 获取世界经纬度信息函数
var getWorldGeometry = function () {$.ajax({ type : "GET", //提交方式 url : "./code/world.json",async: false,success : function(response) {//返回数据根据结果进行相应的处理 worldGeometry = [];// 绘制世界地图response.features.forEach(function (worldItem, worldItemIndex) {var length = worldItem.geometry.coordinates.length;var multipleBool = length > 1 ? true : false;worldItem.geometry.coordinates.forEach(function (worldChildItem, worldChildItemIndex) {if (multipleBool) {// 值界可以使用的经纬度信息if (worldChildItem.length && worldChildItem[0].length == 2) {worldGeometry.push(worldChildItem);}// 需要转换才可以使用的经纬度信息if (worldChildItem.length && worldChildItem[0].length > 2) {worldChildItem.forEach(function (countryItem, countryItenIndex) {worldGeometry.push(countryItem);})}} else {var countryPos = null;if (worldChildItem.length > 1) {countryPos = worldChildItem;} else {countryPos = worldChildItem[0];}if (countryPos) {worldGeometry.push(countryPos);}}})})} })
}

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

// 执行函数
var render = function () {scene.rotation.y -= 0.01;renderer.render(scene, camera);orbitcontrols.update();requestAnimationFrame(render);
}

three.js通过canvas实现球体世界平面地图相关推荐

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

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

  2. Canvas实现球体碰撞交互效果(一)

    一.Canvas简介 提到Canvas相信做前端开发的同学都不陌生,它是一个用于绘制图形的容器,我们会在一些特殊场景时需要用到Canvas,比如我们要在页面上显示一个流程图,这个流程图需要根据后端返回 ...

  3. skycons.js 基于canvas的天气动态js插件

    skycons.js 基于canvas的天气动态js插件 skycons.js是一个开源的javascript天气动画图标渲染器.相当于gif动图一样. skycons CDN地址:https://w ...

  4. java使用重绘实现拖动_原生JS使用Canvas实现拖拽式绘图功能

    一.实现的功能 1.基于oop思想构建,支持坐标点.线条(由坐标点组成,包含方向).多边形(由多个坐标点组成).圆形(包含圆心坐标点和半径)等实体 2.原生JavaScript实现,不依赖任何第三方j ...

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

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

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

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

  7. html5画板功能,JS实现canvas简单小画板功能

    本文实例为大家分享了JS实现canvas简单小画板的具体代码,供大家参考,具体内容如下 Html部分: Document CSS部分: *{ margin: 0; padding: 0; list-s ...

  8. html canvas直线进度条,js+HTML5 canvas 实现简单的加载条(进度条)功能示例

    本文实例讲述了js+HTML5 canvas 实现简单的加载条(进度条)功能.分享给大家供大家参考,具体如下: www.jb51.net canvas实现加载条动画 /* * 获取canvas, ca ...

  9. html 写字版插件,JS+HTML5 Canvas实现简单的写字板功能示例

    本文实例讲述了JS+HTML5 Canvas实现简单的写字板功能.分享给大家供大家参考,具体如下: 先来看运行效果: 具体代码如下: www.jb51.net JS写字板 body,html { pa ...

最新文章

  1. PHP mysql数据迁移,【MySQL】迁移数据目录php-php教程
  2. Android--用手指移动画面里的照片/onTouchEvent事件判断
  3. python个人项目-软工个人项目WC(Python实现)
  4. svn 合并分支代码到主干
  5. Postman工具之参数化
  6. 服务器硬盘维修工具,服务器硬盘镜像备份和恢复工具_OO DiskImage Server V8.5.39 服务器版...
  7. 利用System.Net.Mail 的SmtpClient发送邮件
  8. form表单,submit,ajax提交
  9. 【Mac】Mac 下 kafka 生产者 控制台 发送长消息被截断
  10. [源码]天骄天下个人网站系统(三个月倾情打造)
  11. redis+mybatis+spring
  12. 关于嵌入式学习随笔-1《STM32简介》
  13. STC单片机程序下载原理与自动下载
  14. 5028: 小Z的加油店2257: [Jsoi2009]瓶子和燃料
  15. ME525+在线 刷机
  16. 为什么“电路中容抗和阻抗相等时,也就是谐振时,电路呈阻性?”谢谢
  17. mysql中查找出生日期_如何在MySQL中根据出生日期记录显示日期名称?
  18. Hadoop 安装snappy(编译源码)
  19. STM32的最小系统组成
  20. nasm寄存器xmm[0~8使用]

热门文章

  1. 物联网在智能交通中的应用前景
  2. play debug启动报错Error occurred during initialization of VM agent library failed to init: jdwp
  3. 高效的苹果清理软件——cleanmymac
  4. 元学习概述(Meta-Learning)
  5. 【云计算】从事云计算运维可以考取哪些证书?
  6. [WPF专业编程指南].李应保(奋斗的小鸟)_PDF 电子书
  7. shell181网格划分_复合材料SHELL181单元完全攻略
  8. 复旦微魔方FM33FR0xx——FL库笔记-定义
  9. java 两个点球面距离_计算球面两点间距离实现Vincenty+Haversine
  10. Python高级正则表达式