There.js入门系列之React中使用Three.js
Posted 漫漫前端路
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了There.js入门系列之React中使用Three.js相关的知识,希望对你有一定的参考价值。
There.js入门系列
React中使用Three.js
1、安装库:
npm i three --save
2、页面组件中引入:
import * as THREE from 'three';
3、three.js使用面向对象的方式来构建程序,包含了3个基本对象:场景(scene)、相机(camera)、渲染器(renderer)。
4、新建一个Cube组件,来模拟实现一个立方体的简单demo
4.1、首先定义html结构,只需要一个具有ID的DOM元素即可,这里由于是以组件的形式,所以ID由父元素传入
4.2、父组件:
import Cube from '../Components/3D/Cube';
<div>
<Cube
eleId={this.cubeId}
/>
</div>
4.3、Cube子组件,先定义HTML结构
render() {
const {
eleId
} = this.props;
return (
<div id={eleId}></div>
)
}
4.4、在Cube内首先定义一个初始化的方法,initThree
-
在方法内定义 3 个基本对象
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
fov:相机视椎体垂直视角
aspect:相机视椎体宽高比
near:相机视椎体近裁剪面
far:相机视椎体远裁剪面
4.4.2、远景投影,也称之为透视投影。这个是我们人眼观察世界的模式,远景投影相机示意图如下:
4.4.3、WebGLRenderer:WebGL渲染器,使用WebGL来绘制场景,如果设备支持的话。使用WebGL将能够利用GPU硬件加速从而提高渲染性能
4.5、将渲染器放入指定的DOM中
const container = document.getElementById(this.props.eleId);
4.6、以上场景、相机以及渲染器都已经初始化,接下来我们设置需要渲染到场景中的cube对象
4.6.1、我们从three.js的几何模型中选取BoxGeometry来创建我们的对象模型
const geometry = new THREE.BoxGeometry( 1, 1, 1 );
4.6.2、为了给立方体模型进行着色,我们还需要材料,这里选用基础网孔材料(MeshBasicMaterial),为了观看效果,我们对颜色进行设置,并且设置渲染模型为线框
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00, wireframe: true } );
4.6.3、有了模型和材料后,还需要一个网孔,网孔是用来承载几何模型的一个对象,还可以把材料应用到它上面
const cube = new THREE.Mesh( geometry, material );
4.6.4、然后将该对象添加到场景中
scene.add( cube );
4.6.5、默认情况下,当我们调用 scene.add() 时,对象将被添加到原点处,即坐标点(0,0,0),这将导致相机和立方体发生空间重叠,场景渲染后对象会无法查看到。为了避免这样,我们把相机(camera)的视野拉远一些,否则将导致3D图像无法观看到
camera.position.z = 5;
4.6.6、利用渲染器进行渲染
renderer.render( scene, camera );
4.6.7、效果如下
4.7、接下来我们创建动画效果,为了实现动画效果,有两步需要操作
4.7.1、定义一个函数,去循环渲染对象
renderers = () => {
requestAnimationFrame( this.renderers );
renderer.render( scene, camera );
}
-
requestAnimationFrame:告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,与setInterval的区别(为了提高性能和电池寿命,因此在大多数浏览器里,当requestAnimationFrame() 运行在后台标签页或者隐藏的<iframe> 里时,requestAnimationFrame() 会被暂停调用以提升性能和电池寿命)
4.7.2、然后在循环函数中,render方法前面添加代码以更改渲染对象旋转角
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
4.7.3、在initThree函数中调用该方法即可,即可看到旋转的立方体
4.8、为了观看效果,这里对代码进行部分改造,增加可调控模型的界面控制:相机视角、模型纹理、模型 、模型纹理、模型类型...
4.8.1、首先定义纹理素材信息(这里由于three的纹理加载器会有跨域的问题,因此将网上的素材放到阿里云的OSS中,在OSS进行跨域处理设置即可)
this.materialPng = new Map([
[ ],
[ ],
[ ],
[ ],
[ ]
]);
4.8.2、将纹理素材定义到antd的Select组件中
this.materialPng.forEach((value, key) => {
materialPngOption.push(
<Option key={value} value={value}>{key}</Option>
)
});
4.8.3、界面控制HTML结构部分代码如下
<Button type="link" disabled>相机X轴</Button>
<InputNumber
defaultValue={0}
onChange={this.handleCameraX}
/>
<Button type="link" disabled>相机Y轴</Button>
<InputNumber
defaultValue={0}
onChange={this.handleCameraY}
/>
<Button type="link" disabled>相机Z轴</Button>
<InputNumber
defaultValue={5}
onChange={this.handleCameraZ}
/>
<br/>
<Button type="link" disabled>模型类型</Button>
<Switch
onChange={this.handleCubeType}
checkedChildren="线框"
unCheckedChildren="默认"
defaultChecked={false}
/>
</div>
<Button type="link" disabled>模型贴图</Button>
<Select
style={{ width: 150 }}
onSelect={this.handleSelectMaterial}
defaultValue={this.materialPng.get("木箱子")}
>
{materialPngOption}
</Select>
4.8.4、相应的属性更改方法如下,这里更改属性后,界面中模型相应属性变化就能够看到,是因为之前定义的renderers函数,requestAnimationFrame的刷新频率为每秒60次,如果你没有定义该刷新函数,就需要在每个属性更改方法中主动调用render函数进行重新渲染:
handleCameraX = (value) => {
this.camera.position.x = value;
};
handleCameraY = (value) => {
this.camera.position.y = value;
};
handleCameraZ = (value) => {
this.camera.position.z = value;
};
handleCubeType = (value) => {
this.cube.material.wireframe = value;
};
handleSelectMaterial = (value) => {
this.loader.load(value, (texture) => {
this.cube.material.map = texture;
});
this.cube.material.needsUpdate = true;
};
4.8.5、整体效果如下:(其中场景背景色更改使用到了颜色选取器插件,该插件将在后续的章节中讲到)
以上是关于There.js入门系列之React中使用Three.js的主要内容,如果未能解决你的问题,请参考以下文章
新手入门系列之-React / Vue 应用持续集成Docker 化