记录--可视化大屏-用threejs撸一个3d中国地图
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
不想看繁琐步骤的,可以直接去github
下载项目,如果可以顺便来个star
哈哈
本项目使用vue-cli
创建,但不影响使用,主要绘制都已封装成类
1、使用geoJson绘制3d地图
1.1 创建场景相关
// 创建webGL渲染器
this.renderer = new THREE.WebGLRenderer( { antialias: true,alpha: true} );
this.renderer.shadowMap.enabled = true; // 开启阴影
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
this.renderer.toneMapping = THREE.ACESFilmicToneMapping;
this.renderer.toneMappingExposure = 1.25; // 根据自己的需要调整颜色模式
// this.renderer.outputEncoding = THREE.sRGBEncoding; this.renderer.outputEncoding = THREE.sHSVEncoding;
this.renderer.setPixelRatio( window.devicePixelRatio );
// 清除背景色,透明背景
this.renderer.setClearColor(0xffffff, 0);
this.renderer.setSize(this.width, this.height); // 场景
this.scene = new THREE.Scene();
this.scene.background = null
// 相机 透视相机
this.camera = new THREE.PerspectiveCamera(45, this.width / this.height, 0.1, 5000);
this.camera.position.set(0, -40, 70);
this.camera.lookAt(0, 0, 0);
1.2 根据json绘制地图
利用THREE.Shape
绘制地图的平面边数据,再用THREE.ExtrudeGeometry
将一个面拉高成3d模型,3d饼图同理也可以这么制作
let jsonData = require('./json/china.json')
this.initMap(jsonData); // initMap 方法主要部分
initMap(chinaJson) {
/* ...省略
...
*/
chinaJson.features.forEach((elem, index) => {
// 定一个省份3D对象
const province = new THREE.Object3D();
// 每个的 坐标 数组
const { coordinates } = elem.geometry;
const color = COLOR_ARR[index % COLOR_ARR.length]
// 循环坐标数组
coordinates.forEach(multiPolygon => { multiPolygon.forEach((polygon) => {
const shape = new THREE.Shape(); for (let i = 0; i < polygon.length; i++) {
let [x, y] = projection(polygon[i]); if (i === 0) {
shape.moveTo(x, -y);
}
shape.lineTo(x, -y);
} const extrudeSettings = {
depth: 4,
bevelEnabled: true,
bevelSegments: 1,
bevelThickness: 0.2
}; const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings); // 平面部分材质
const material = new THREE.MeshStandardMaterial( {
metalness: 1,
color: color, } );
// 拉高部分材质
const material1 = new THREE.MeshStandardMaterial( {
metalness: 1,
roughness: 1,
color: color, } ); const mesh = new THREE.Mesh(geometry, [
material,
material1
]);
// 设置高度将省区分开来
if (index % 2 === 0) {
mesh.scale.set(1, 1, 1.2);
}
// 给mesh开启阴影
mesh.castShadow = true
mesh.receiveShadow = true
mesh._color = color
province.add(mesh); }) }) _this.map.add(province); })
}
geoJson
的坐标需要进行墨卡托投影转换才能转换成平面坐标,这里需要用到d3
// 墨卡托投影转换
const projection = d3.geoMercator().center([104.0, 37.5]).scale(80).translate([0, 0]);
2、增加光照
我们把各种光都打上,环境光,半球光,点光,平行光。以平行光为例,增加投影,调整投影分辨率,避免投影出现马赛克
const light = new THREE.DirectionalLight( 0xffffff, 0.5 );
light.position.set( 20, -50, 20 ); light.castShadow = true;
light.shadow.mapSize.width = 1024;
light.shadow.mapSize.height = 1024; this.scene.add(light);
castShadow = true
表示开启投影
3、增加阴影模糊
默认的阴影没有模糊效果,看起来像白炽灯照射的样子,没有柔和感。使用官方示例中的csm
来增加阴影模糊
import { CSM } from 'three/examples/jsm/csm/CSM.js'; this.csm = new CSM( {
maxFar: params.far,
cascades: 4,
mode: params.mode,
parent: this.scene,
shadowMapSize: 1024,
lightDirection: new THREE.Vector3( params.lightX, params.lightY, params.lightZ ).normalize(),
camera: this.camera
} );
4、增加鼠标事件
在3d
空间中,鼠标事件主要通过射线来获取鼠标所在位置,可以想象成鼠标放出一道射线,照射到的第一个物体就是鼠标所在位置。此时用的threejs
的Raycaster
,通过Raycaster
给对应的省份增加鼠标移入高亮效果和省份民悬浮展示效果
this.raycaster = new THREE.Raycaster();
// 传入需要检测的对象 group,group下的所有对象都会被检测到,如果被射线照到,则intersects有值,表示鼠标当前在这些物体上
const intersects = this.raycaster.intersectObject( this.group, true );
// 代码太多就不贴了,见 GitHub源码
5、渲染
threejs
的渲染一般调用原生的requestAnimationFrame
,主要做的事就是调用renderer
的render
方法,当然因为我们做了阴影模糊处理,所以还有别的需要做的:
this.camera.updateMatrixWorld();
this.csm.update();
this.renderer.render(this.scene, this.camera);
6、动画效果
地图上如果有一些动画效果,可以使用TWEEN.js
,github地址,比如地图标注的出现动画:
最后再奉上项目地址
本文转载于:
https://juejin.cn/post/7057808453263163422
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。
记录--可视化大屏-用threejs撸一个3d中国地图的更多相关文章
- 可视化大屏的终极解决方案居然这么简单,vue-autofit一行全搞定!
可视化大屏适配/自适应现状 可视化大屏的适配是一个老生常谈的话题了,现在其实不乏一些大佬开源的自适应插件.工具但是我为什么还要重复造轮子呢?因为目前市面上适配工具每一个都无法做到完美的效果,做出来的东 ...
- 使用DataV制作实时销售数据可视化大屏(实验篇)
课时1:背景介绍 任务说明 ABC是一家销售公司,其客户可以通过网站下单订购该公司经营范围内的商品,并使用信用卡.银行卡.转账等方式付费.付费成功后,ABC公司会根据客户地址依据就近原则选择自己的货仓 ...
- Qt编写数据可视化大屏界面电子看板系统
一.前言 目前大屏大数据可视化UI这块非常火,趁热也用Qt来实现一个,Qt这个一站式超大型GUI超市,没有什么他做不了的,大屏电子看板当然也不在话下,有了QSS和QPainter这两个无敌的工具组合, ...
- Qt编写数据可视化大屏界面电子看板13-基础版
一.前言 之前发布的Qt编写的可视化大屏电子看板系统,很多开发者比较感兴趣,也收到了很多反馈意见,纵观市面上的大屏系统,基本上都是B/S结构的web版本,需要在后台进行自定义配置模块,绑定数据源等,其 ...
- Qt编写数据可视化大屏界面电子看板12-数据库采集
一.前言 数据采集是整个数据可视化大屏界面电子看板系统核心功能,没有数据源,这仅仅是个玩具UI,没啥用,当然默认做了定时器模拟数据,产生随机数据,这个可以直接配置文件修改来选择采用何种数据采集方法,总 ...
- Qt编写数据可视化大屏界面电子看板11-自定义控件
一.前言 说到自定义控件,我是感觉特别熟悉的几个字,本人亲自原创的自定义控件超过110个,都是来自各个行业的具体应用真实需求,而不是凭空捏造的,当然有几个小控件也有点凑数的嫌疑,在编写整个数据可视化大 ...
- Qt编写数据可视化大屏界面电子看板9-曲线效果
一.前言 为了编写数据可视化大屏界面电子看板系统,为了能够兼容Qt4和嵌入式linux系统,尤其是那种主频很低的,但是老板又需要在这种硬件上(比如树莓派.香橙派.全志H3.imx6)展示这么华丽的界面 ...
- Qt编写数据可视化大屏界面电子看板8-调整间距
一.前言 在数据可视化大屏界面电子看板系统中,前期为了使用目标客户机,调整间距是必不可少的工作,QMainWindow中的QDockWidget,会默认生成布局和QSplitter调整宽高大小,鼠标移 ...
- Qt编写数据可视化大屏界面电子看板5-恢复布局
一.前言 恢复布局这个功能在整个数据可视化大屏界面电子看板系统中非常有用,很多时候不小心把现有布局拖动乱了,(当然如果不想布局被拖动改动,可以修改配置文件中的MoveEnable参数来控制,默认为真表 ...
- Qt编写数据可视化大屏界面电子看板4-布局另存
一.前言 布局另存是数据可视化大屏界面电子看板系统中的额外功能之一,主要用于有时候用户需要在现有布局上做个微调,然后直接将该布局另存为一个布局配置文件使用,可以省略重新新建布局重新来一次大的调整的工作 ...
随机推荐
- CF131D Subway 题解
题目传送门 前置知识 强连通分量 | 最短路 解法 考虑用 Tarjan 进行缩点,然后跑最短路. 缩点:本题的缩点有些特殊,基于有向图缩点修改而得,因为是无向图,所以在 Tarjan 过程中要额外记 ...
- NC20573 [SDOI2011]染色
题目链接 题目 题目描述 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如 ...
- Swoole从入门到入土(20)——WebSocket服务器[协程版本]
本篇让我们先用一段示例代码开路: <?php Co\run(function () { $server = new Co\Http\Server('0.0.0.0', 9501, false); ...
- 《系列二》-- 11、Aware是什么
目录 正文 阅读之前要注意的东西:本文就是主打流水账式的源码阅读,主导的是一个参考,主要内容需要看官自己去源码中验证.全系列文章基于 spring 源码 5.x 版本. 写在开始前的话: 阅读spri ...
- 《系列二》-- 9、bean属性填充
目录 一.概述: populateBean 在什么时候执行? 二.populateBean 的重要操作 三.重点操作一 propertyValue 的注入 3.1 根据 Bean名称注入 3.2 浅看 ...
- ASCII编码的影响与作用:数字化时代的不可或缺之物
一.ASCII编码的起源 ASCII(American Standard Code for Information Interchange)编码是一种最早用于将字符转换为数字的编码系统.它诞生于20世 ...
- day04---系统重要文件
系统重要的文件 /etc的重要文件 1./etc/sysconfig/network-scripts/ifcfg-eth0 [root@localhost ~]# cat /etc/sysconfig ...
- day06---基础优化之防火墙,yum源,字符集,vim补充,echo命令
1.系统版本号 cat /etc/redhat-release hostnamectl uname -r 2.系统 时间硬件时间 date hwclock clock hwclock systohc ...
- 详细的BoltDB学习记录文档
最近项目中用到了boltdb这个go开发的key/value 数据库,但是之前并有接触过,所以特意去看了官方,也找了些资料,网上找的资料要不就是官方文档的翻译,要不就是简单的介绍一点,都不是很全,所以 ...
- Gitlab中的打包作业完成后,更新http服务器里的版本号文件
背景 在.gitlab-ci.yml里面,我们有4个场景 dotnet build.dotnet pack和dotnet push 单元测试 SSH到http服务器,更新对应的版本号文件里面的版本数字 ...