3DДекілька 3D редакторівThree.jsПлагін
У цьому гайді описано, як включити редактор вузлів у 3D-сцену. Це можна досягти за допомогою rete-area-3d-plugin
, який замінює стандартний rete-area-plugin
.
Завдяки Three.js цей плагін створює сцену, яка містить камеру та два рендерери – CSS3DRenderer
і WebGLRenderer
. Отже, 3D-об’єкти та нативні HTML-елементи відображаються разом в одному в’юпорті, з можливістю перекриття. Основна перевага використання нативних елементів (на відміну від візуалізації в текстуру) полягає в збереженні повної інтерактивності.
Перед використанням цього плагіна необхідно окремо встановити однорангову залежність three
.
npm i rete-area-3d-plugin three @types/three
Якщо ви дотримувались базового гайду, вам потрібно буде замінити ініціалізацію Area2DPlugin
на Area3DPlugin
і змінити деякі визначення типів.
import { Area3D, Area3DPlugin } from 'rete-area-3d-plugin';
type AreaExtra =
| Area3D<Schemes>
const area = new Area3DPlugin<Schemes, AreaExtra>(container);
editor.use(area);
Отже, контейнер включатиме як елемент <canvas>
, так і контейнер для HTML-елементів, які зазнають 3D-трансформації.
Якщо ваш редактор має вузли, ви можете побачити їх у вікні перегляду, але вони не будуть інтерактивними. Щоб забезпечити візуальний зворотний зв’язок для взаємодії вузла, він має бути частиною циклу анімації та бути пов’язаним із Object3D
, який безпосередньо відповідає за перетягування.
Area3DExtensions.animate(area)
Це розширення використовує типовий підхід three.js до циклів анімації, використовуючи функцію render()
разом із requestAnimationFrame()
.
Крім того, нам потрібно пов’язати наші вузли та з’єднання з геометрією в 3D-сцені, щоб забезпечити інтерактивну функціональність і запобігти небажаному накладанню з іншими об’єктами.
Area3DExtensions.forms.connection(render);
Area3DExtensions.forms.node(area);
Під час рендерінгу, ці розширення створюють геометрію, яка точно повторює форму вузлів і з’єднань.
Тепер ви можете взаємодіяти з вузлами та обертати або переміщати камеру навколо них. Перегляньте повний результат на сторінці прикладу 3D.
Деякі розширення, доступні у rete-area-plugin
, можна використовувати лише в редакторі, не враховуючи в’юпорт та подібні фактори.
import { AreaExtensions } from 'rete-area-plugin'
AreaExtensions.showInputControl(area)
AreaExtensions.simpleNodesOrder(area)
AreaExtensions.snapGrid(area, { size: 30 })
AreaExtensions.selectableNodes(area, AreaExtensions.selector(), { accumulating: AreaExtensions.accumulateOnCtrl() });
У цьому плагіні доступні такі розширення:
import { Area3DExtensions } from 'rete-area-3d-plugin'
Area3DExtensions.forms.comment(area) // створює геометрію для плагіна коментарів
Area3DExtensions.forms.reroute(area) // створює геометрію для плагіна зміни маршруту
Area3DExtensions.lookAt(area, editor.getNodes()) // альтернатива zoomAt від rete-area-plugin
Як було сказано раніше, цей плагін створює сцену з камерою та рендерерами. Щоб отримати доступ до них, ви можете використовувати такий код:
const { scene } = area.area
scene.root // Scene від three.js
scene.camera // PerspectiveCamera
scene.renderer.css3d // CSS3DRenderer
scene.renderer.webgl // WebGLRenderer
scene.orbit // OrbitControls
Наприклад, у вас є можливість вимкнути орбітальний контроль (scene.orbit.enabled = false
) і додати альтернативний, або налаштувати параметри рендерів або камери.
Ви можете додавати 3D-об’єкти через scene.root
, який є екземпляром Scene
у Three.js.
Якщо ви хочете включити HTML-елементи в сцену, зокрема в полотно редактора, використовуйте такий код:
area.area.content.add(element)
HTML елемент буде додано до полотна редактора в нульовій позиції. Щоб гарантувати, що він не перекривається іншими елементами сцени, він повинен мати геометрію, яка відображає його форму.
area.area.content.updateGeometry(element, bufferGeometry)
Перегляньте більше прикладів у вихідному коді
Що стосується інших елементів HTML, він зберігатиме власний порядок, і ви можете змінити його наступним чином:
area.area.content.reorder(element, nextElement)
Видалення елемента:
area.area.content.remove(element)
Якщо ви кастомізували свої вузли або з’єднання, ви можете помітити, що вони не відповідають заповненню в 3D-сцені. Щоб адаптувати їх до нових форм, ви можете або реалізувати свою власну геометрію, або повторно використовувати існуючу з різними аргументами.
Приклад зміни радіуса межі вузла:
Area3DExtensions.forms.node(area, {
customize(node) {
return Area3DExtensions.forms.createClassicNodeGeometry(node, {
borderRadius: 0
})
}
})
Приклад геометрії з'єднання із збільшеною шириною:
Area3DExtensions.forms.connection(reactRender, {
customize(path) {
return Area3DExtensions.forms.createClassicConnectionGeometry(path, 10)
}
})
Крім того, плагін пропонує можливість включати кілька редакторів в одну сцену. Ви можете досягти цього, створивши головний екземпляр Area3DPlugin
і поділившись ним з іншими редакторами.
const mainEditor = new NodeEditor<Schemes>();
const mainArea = new Area3DPlugin<Schemes, AreaExtra>(container)
mainEditor.use(mainArea)
const secondaryEditor = new NodeEditor<Schemes>();
const secondaryArea = mainArea.share()
secondaryEditor.use(secondaryArea)
У межах певної сцени ви зіткнетеся з двома редакторами, розташованими в одній площині та накладаючись один на одного. Щоб розділити їх, ви можете змінити положення та орієнтацію другого редактора.
const canvas = secondaryArea.area.getCanvas()
canvas.rotateY(Math.PI / 2)
canvas.get(sharedArea)?.translateX(500)
Перегляньте повний результат на сторінці прикладу Декілька 3D-редакторів.