THREEJS实现立体环图(思路版)

文章介绍了如何在Echarts大屏项目中,由于缺少立体环图组件,转而使用three.js进行自定义开发的过程。作者通过学习three.js的基础知识,创建场景、相机和渲染器,然后利用THREE.Shape和THREE.ExtrudeGeometry创建立体扇形,并计算数据对应的角度。此外,还使用CSS2DRenderer添加了百分比标签。目前代码已实现立体饼状图,但标签实现还在探索中。
摘要由CSDN通过智能技术生成

注意: 只有实现思路和代码,无法开箱即用。

1. 使用背景

收到个任务,制作echarts大屏,有个模块需要使用立体环图,在echarts官网找了一圈没有找到如何实现,网上资料甚少,最后只能叫设计改成普通图了。任务完成后自己学习下如何实现。

需求图:
在这里插入图片描述
我暂时实现的样子 - label标签还没有想到应该怎么实现,希望各位大佬知道的能分享下经验
请添加图片描述

2. 学习视频及文档

1: three.js教程-从入门到入门 视频短讲解挺清楚的,开了两倍速大概了解下什么是Three.js
2. Three.js中文网 比较详细
3. Three官网 事例多

3. 实现流程

3.1 创建好THREE基本环境

import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
//场景
const scene = new THREE.Scene()
//相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.set(0, 50, 100);
//渲染器
const renderer = new THREE.WebGLRenderer()
document.querySelector('#app').appendChild(renderer.domElement)
renderer.setSize(window.innerWidth, window.innerHeight)
//控制器让画面可以拖动
const controls = new OrbitControls(camera, renderer.domElement);
//渲染场景
function render() {
  renderer.render(scene, camera)
  requestAnimationFrame(render)
}
render()

3.2 单一立体扇形实现

使用到THREE.Shape()THREE.ExtrudeGeometry()创建。(在官方事例中进行修改)

const heartShape = new THREE.Shape();
//通过两个弧形形成一个扇形平面---具体也没明白为啥可以,就是写了之后发现竟然实现了
//外层弧形
heartShape.absarc(0, 0, 20, 0, Math.PI/2)
//内层弧形
heartShape.absarc(0, 0, 10, Math.PI/2, 0, true)

const extrudeSettings = { depth: 8, bevelEnabled: true, bevelSegments: 2, steps: 2, bevelSize: 1, bevelThickness: 1 };
//使用 ExtrudeGeometry 把扇形平面拉伸成立体状
const geometry = new THREE.ExtrudeGeometry( heartShape, extrudeSettings );

const mesh = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial() );

3.3 计算每个数据所占的角度大小。

// 假设数据是这样的
const chartData = [
  { label: '星期一', value: 40 },
  { label: '星期二', value: 80 },
  { label: '星期三', value: 20 },
]
//第一步 获取所有值的和
const max = chartData.reduce((pre, item) => { return pre + item.value }, 0)
//第二步 设置图形初始角度为0
let startdeg = 0
chartData.forEach((item, index) => {
	// 每一个图形的开始角度
	let start = startdeg
	// 每一个图形的结束角度 = 初始角度+所占比例的角度
	let end = startdeg + 2*Math.PI*(item.value/max)
	... 有开始角度和结束角度了 用3.2方式绘制图形 
	// 更新 图形初始化角度
	startdeg = end
})

至此 立体饼状图就能出来了。

3.4 每个饼状图上的百分比标签。

使用的是CSS2DRenderer 也就是用DOM+CSS方式。

import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';

const labelDiv = document.createElement('div');∂
labelDiv.innerHTML = `<div style='color: #fff'>50%</div>`
const earthLabel = new CSS2DObject(labelDiv);
earthLabel.position.set(10, 0, 0)
// earthLabel.center.set(0, 0, 0);
scene.add(earthLabel);

// css2d渲染
let labelRenderer = new CSS2DRenderer();
labelRenderer.setSize(window.innerWidth, window.innerHeight);
labelRenderer.domElement.style.position = 'absolute';
labelRenderer.domElement.style.top = '0px';
document.querySelector('#app').appendChild(labelRenderer.domElement);
//把相机场景放入渲染
labelRenderer.render(scene, camera);

3.5 每个百分比标签位置

下载最后面的代码 参考下吧

4. 代码分享

gitCode仓库 three实现立体环形图
代码总共100多行,后面要是有什么思路继续完善一下。

如本文对你10分帮助,就赏个10分(一毛)吧

你可能指的是使用Three.js创建一个带有纹理的立体模型,并将其导出为图片的操作。实现这一功能需要借助Three.js提供的CanvasRenderer和FileSaver库。下面是一个简单的示例代码: ```javascript // 创建场景、相机和渲染器 var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); var renderer = new THREE.CanvasRenderer(); renderer.setSize(400, 400); document.body.appendChild(renderer.domElement); // 创建立方体几何体 var geometry = new THREE.BoxGeometry(1, 1, 1); // 创建纹理贴图 var texture = new THREE.TextureLoader().load('texture.jpg'); // 创建材质 var material = new THREE.MeshBasicMaterial({ map: texture }); // 创建立方体网格 var cube = new THREE.Mesh(geometry, material); scene.add(cube); // 设置相机位置 camera.position.z = 5; // 渲染场景 renderer.render(scene, camera); // 导出图片 var imgData = renderer.domElement.toDataURL(); var a = document.createElement('a'); a.href = imgData; a.download = 'cube.png'; document.body.appendChild(a); a.click(); document.body.removeChild(a); ``` 这段代码创建了一个带有纹理的立方体,并将其导出为名为'cube.png'的图片。你可以将代码中的'texture.jpg'替换成其他图片路径,来实现不同的纹理效果。需要注意的是,CanvasRenderer虽然能够导出图片,但在性能和渲染效果上都不如WebGLRenderer,因此在实际项目中应尽可能使用WebGLRenderer来进行渲染。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值