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

概况如下:

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 }

原文地址:https://www.cnblogs.com/gaozhiqiang/p/11470441.html

时间: 2024-10-08 05:30:23

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

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

文章目录 使用方法 自定义参数 相关链接 Particles.js是一款基于HTML5 Canvas画布的轻量级粒子动画插件,可以设置粒子的形状.旋转.分布.颜色等属性,还可以动态添加粒子,效果非常炫酷,能和鼠标互动吸附或者是躲避鼠标指针. 使用方法 1.该粒子动画库插件使用方法非常简单,首先要在页面中引入particles.js文件. <script src="js/particles.js"></script> 2.在页面中使用一个div来作为放置粒子的容器

fabric.js的简单上手及基于fabric.js的canvas切图工具:1、基本使用及配置

参考链接 Fabric.js 简单介绍和使用 简介 Fabric.js是一个可以简化canvas程序编写的库. Fabric.js为canvas提供所缺少的对象模型, svg parser, 交互和一整套其他不可或缺的工具.基于MIT协议开源,在github上有许多人贡献代码. 为什么选择fabric.js 手上的项目必须使用canvas 原生的canvas API不够友好 用fabric.js实现切图用户体验更好 为项目以后的迭代留下扩展的余地 简单上手 请参考文章开头的参考链接 这里主要介绍

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

前面简单介绍了webGL和Three.js的背景以及照相机的设定,接下来介绍一些Three.js中的几何形状. 1.立方体 虽然这一形状的名字叫立方体(CubeGeometry),但它其实是长方体,也就是长宽高可以设置为不同的值.其构造函数是: THREE.CubeGeometry(width,height,depth,widthSegments,heightSegments, depthSegments) width:x方向上的长度 height:y方向上的长度 depth:z方向上的长度 w

简单AI五子棋,js,canvas

新年第一篇博客,最近几天走亲访友的没有学习.今天开始进入学习模式. <!DOCTYPE html> <html> <head> <title>五子棋</title> <link rel="stylesheet" type="text/css" href="./css/style.css"> </head> <body> <canvas id=&q

js渲染canvas的问题??????依次开100朵花

怎么依次开10朵.饱满的.... 我上代码,jquery自己下载 <!doctype html> <html> <head> <title>Love</title> <meta charset="gbk" /> <!--[if IE]> <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"><

用js控制canvas实现的模仿windows上单选、多选及拖动控制的toy program

功能包括:鼠标点击单选.拖动多选.ctrl+单击组合效果.对选中的单个或多个canvas图层通过鼠标拖动.方向键移动.delete删除图层等. 感觉复杂的地方主要在控制逻辑上,下面是全部代码(带注释哦),可以直接复制保存为html文件在浏览器里查看效果 <!DOCTYPE> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312&

4种方法生成二维码 (js 控制canvas 画出 二维码)

随着网络的迅速发展 发展 发展,二维码的应用将会越来越多.同时很多只是很平凡的二维码,请拿起你的手 把这个二维码 设计起来吧.下面分享了几个非常好的二维码设计.  二维码原理: 二维条码/二维码可以分为堆叠式/行排式二维条码和矩阵式二维条码. 堆叠式/行排式二维条码形态上是由多行短截的一维5条码堆叠而成:矩阵式二维条码以矩阵的形式组成,在矩阵相应元素位置上用“点”表示二进制“1”, 用“空”表示二进制“0”,“点”和“空”的排列组成代码. 最近对二维码产生了兴趣 研究了一下二维码 这里生出的术语

js 利用canvas + flv.js实现 视频流 截屏 、本地下载功能实现,兼容火狐,谷歌, 截屏跨域的坑

1 本地视频截屏(canvsa) <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title></title> <link rel="stylesheet" href=&q

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

index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>测试</title> <script src="js/three.min.js"></script> <script src="js/stats.min.js">