开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情
最近3D可视化在商用中的使用越来越广泛,three.js作为前端的3D组件库,能够支持非常多类型的3D模型在浏览器中的渲染和交互操作。目前,团队绝大多数应用多采用React技术栈,除了使用类似@react-three/fiber这样的二次封装库,有没有什么更简单直接的在React组件中使用three.js的方式呢?
安装
yarn add three
引入
// 引入three.js
import * as THREE from 'three';
定义一个用来渲染3D图形的DOM
<div
id='map'
ref={mapRef}
style={{ width: '100%', height: '100%' }}>
</div>
通过useRef绑定
const mapRef = useRef<HTMLDivElement>(null);
在副作用函数中,在存在该节点时,渲染Canvas
useEffect(() => {
if(mapRef?.current){
...
mapRef?.current?.appendChild(renderer.domElement); //body元素中插入canvas对象
//执行渲染操作 指定场景、相机作为参数
renderer.render(scene, camera);
}
}, [mapRef]);
组件完整代码如下(DEMO代码为ThreeJS教程中的模版代码):
import React, { useRef, useEffect } from 'react';
import * as THREE from 'three';
function Three() {
const mapRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (mapRef?.current){
/**
* 创建场景对象Scene
*/
var scene = new THREE.Scene();
/**
* 创建网格模型
*/
// var geometry = new THREE.SphereGeometry(60, 40, 40); //创建一个球体几何对象
var geometry = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
var material = new THREE.MeshLambertMaterial({
color: 0x0000ff
}); //材质对象Material
var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
scene.add(mesh); //网格模型添加到场景中
/**
* 光源设置
*/
//点光源
var point = new THREE.PointLight(0xffffff);
point.position.set(400, 200, 300); //点光源位置
scene.add(point); //点光源添加到场景中
//环境光
var ambient = new THREE.AmbientLight(0x444444);
scene.add(ambient);
/**
* 相机设置
*/
var width = window.innerWidth; //窗口宽度
var height = window.innerHeight; //窗口高度
var k = width / height; //窗口宽高比
var s = 200; //三维场景显示范围控制系数,系数越大,显示的范围越大
//创建相机对象
var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
camera.position.set(200, 300, 200); //设置相机位置
camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
/**
* 创建渲染器对象
*/
var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);//设置渲染区域尺寸
renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
mapRef?.current?.appendChild(renderer.domElement); //body元素中插入canvas对象
//执行渲染操作 指定场景、相机作为参数
renderer.render(scene, camera);
}
}, [mapRef]);
return (
<>
<div id='map' ref={mapRef} style={{ width: '100%', height: '100%' }}>
</div>
</>
);
}
export default Three;
这样就可以在React的组件中渲染出Three.js的模型啦
后续可以根据项目的实际需要,去定义相机、视角等等不同情况下的渲染情况。这种引入方式相对比较直接,但是能够更好的自行理解并解决ThreeJS代码中的问题,是一种比较合适的接入形式。