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结构,只需要一个具有IDDOM元素即可,这里由于是以组件的形式,所以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 );
          4.4.1、PerspectiveCamera(fov、aspect、near、far): 远景相机,参数说明如下

            fov:相机视椎体垂直视角

            aspect:相机视椎体宽高比

            near:相机视椎体近裁剪面

            far:相机视椎体远裁剪面

         4.4.2、远景投影,也称之为透视投影。这个是我们人眼观察世界的模式,远景投影相机示意图如下:

There.js入门系列之React中使用Three.js

                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、效果如下

There.js入门系列之React中使用Three.js

    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([      ["灰白方块", "https://hsj-studio.oss-cn-shanghai.aliyuncs.com/share/portal/three/material/gray-white-cube.jpg"],      ["木箱子", "https://hsj-studio.oss-cn-shanghai.aliyuncs.com/share/portal/three/material/wood-cube.jpg"],      ["花纹-1", "https://hsj-studio.oss-cn-shanghai.aliyuncs.com/share/portal/three/material/flower-pattern-1.png"],      ["熊猫", "https://hsj-studio.oss-cn-shanghai.aliyuncs.com/share/portal/three/material/panda-madness.gif"],      ["毛面-灰色", "https://hsj-studio.oss-cn-shanghai.aliyuncs.com/share/portal/three/material/wenliku.com-2292.jpg"]    ]);

        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 化

React从入门到放弃之前奏:React简介

React-Native入门指导之iOS篇 —— 一准备工作

月薪20K前端入门系列之angular篇01

React系列:React入门

React Native 之 TextInput使用