На момент написания этой статьи я знаю две оболочки Three.js, созданные специально для React, React-Three, которые вы можете найти здесь, и React-Three-Render, которые можно найти здесь. Но что, если вы хотите включить оригинальную и хорошо поддерживаемую библиотеку Three.js в свой проект React?
Следующее руководство позволяет вам сделать это, используя методы и ссылки жизненного цикла компонентов React, которые я объясню более подробно через секунду (шаблон, описанный ниже, не только для Three.js, он полезен для любого вида воспроизведения или анимации. в React, например Tween.js, video.js и т. д.).
Первоначально я нашел это решение на Переполнении стека. Я немного очистил код, используя стрелочные функции, без конструктора и т. Д.
import React, { Component } from 'react'; import * as THREE from 'three'; class ThreeScene extends Component{ componentDidMount(){ const width = this.mount.clientWidth const height = this.mount.clientHeight //ADD SCENE this.scene = new THREE.Scene() //ADD CAMERA this.camera = new THREE.PerspectiveCamera( 75, width / height, 0.1, 1000 ) this.camera.position.z = 4 //ADD RENDERER this.renderer = new THREE.WebGLRenderer({ antialias: true }) this.renderer.setClearColor('#000000') this.renderer.setSize(width, height) this.mount.appendChild(this.renderer.domElement) //ADD CUBE const geometry = new THREE.BoxGeometry(1, 1, 1) const material = new THREE.MeshBasicMaterial({ color: '#433F81' }) this.cube = new THREE.Mesh(geometry, material) this.scene.add(this.cube) this.start() } componentWillUnmount(){ this.stop() this.mount.removeChild(this.renderer.domElement) } start = () => { if (!this.frameId) { this.frameId = requestAnimationFrame(this.animate) } } stop = () => { cancelAnimationFrame(this.frameId) } animate = () => { this.cube.rotation.x += 0.01 this.cube.rotation.y += 0.01 this.renderScene() this.frameId = window.requestAnimationFrame(this.animate) } renderScene = () => { this.renderer.render(this.scene, this.camera) } render(){ return( <div style={{ width: '400px', height: '400px' }} ref={(mount) => { this.mount = mount }} /> ) } } export default ThreeScene
Прячьте добавить или npm установите библиотеку Three.js. Продвигаясь вперед с Three, вы обнаружите, что большая часть ваших действий по устранению неполадок связана с поиском, импортом и реализацией различных библиотек для таких вещей, как элементы управления орбитой и загрузчики объектов. Эти части по-прежнему зависят от глобального загрязнения пространства имен Three.js и были бы непригодны для использования, если бы добрые души Интернета не преобразовали многие из этих библиотек в собственные модули npm и не устранили некоторые проблемы с именами. В более позднем посте я расскажу, какие из этих модулей npm, по моему мнению, работают. Между тем, три библиотеки, указанные выше, являются базовой и постоянно поддерживаются.
В приведенном выше шаблоне используются методы жизненного цикла React componentDidMount()
и componentWillUnmount()
. Вы будете использовать componentDidMount()
для инициализации вашей сцены Three.js, вызывая сцену, средство визуализации, камеру и все остальное, что вы хотите в вашей сцене.
Обратите внимание, что средство визуализации Three.js прикреплено к элементу React с использованием ref
. Согласно документации React, ссылки используются, когда «вам необходимо принудительно изменить дочерний элемент за пределами типичного потока данных». Это особенно хорошо для работы с императивной анимацией внутри React. На самом деле это единственный раз, когда я когда-либо использовал референсы, которых обычно следует избегать.
Также обратите внимание на componentWillUnmount()
, где вы останавливаете анимацию и удаляете ее из DOM. Это очень важно и позволяет избежать большой утечки памяти.