123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- import { Canvas, CircleMenu, ButtonInput, ContextMenu, Loader } from '../libs/flow.module.js';
- import { StandardMaterialEditor } from './materials/StandardMaterialEditor.js';
- import { OperatorEditor } from './math/OperatorEditor.js';
- import { FloatEditor } from './inputs/FloatEditor.js';
- import { ColorEditor } from './inputs/ColorEditor.js';
- import { UVEditor } from './accessors/UVEditor.js';
- import { PositionEditor } from './accessors/PositionEditor.js';
- import { NormalEditor } from './accessors/NormalEditor.js';
- import { CheckerEditor } from './procedural/CheckerEditor.js';
- import { EventDispatcher } from 'three';
- export const ClassLib = {
- 'StandardMaterialEditor': StandardMaterialEditor,
- 'OperatorEditor': OperatorEditor,
- 'FloatEditor': FloatEditor,
- 'ColorEditor': ColorEditor,
- 'UVEditor': UVEditor,
- 'PositionEditor': PositionEditor,
- 'NormalEditor': NormalEditor,
- 'CheckerEditor': CheckerEditor
- };
- export class NodeEditor extends EventDispatcher {
- constructor() {
- super();
- const domElement = document.createElement( 'flow' );
- const canvas = new Canvas();
- domElement.appendChild( canvas.dom );
- this.canvas = canvas;
- this.domElement = domElement;
- this._initMenu();
- this._initContextMenu();
- }
- add( node ) {
- this.canvas.add( node );
- return this;
- }
- get nodes() {
- return this.canvas.nodes;
- }
- _initMenu() {
- const menu = new CircleMenu();
- const menuButton = new ButtonInput().setIcon( 'ti ti-menu-2' );
- const newButton = new ButtonInput().setIcon( 'ti ti-file' ).setToolTip( 'New' );
- const openButton = new ButtonInput().setIcon( 'ti ti-upload' ).setToolTip( 'Open' );
- const saveButton = new ButtonInput().setIcon( 'ti ti-download' ).setToolTip( 'Save' );
- menuButton.onClick( () => {
- this.context.show( 50, 50 );
- } );
- newButton.onClick( () => {
- this.canvas.clear();
- this.dispatchEvent( { type: 'new' } );
- } );
- openButton.onClick( () => {
- this.context.hide();
- const input = document.createElement( 'input' );
- input.type = 'file';
- input.onchange = e => {
- const file = e.target.files[ 0 ];
- const reader = new FileReader();
- reader.readAsText( file, 'UTF-8' );
- reader.onload = readerEvent => {
- const json = Loader.parseObjects( JSON.parse( readerEvent.target.result ), ClassLib );
- this.canvas.clear();
- this.canvas.deserialize( json );
- this.dispatchEvent( { type: 'load' } );
- };
- };
- input.click();
- } );
- saveButton.onClick( () => {
- this.context.hide();
- const json = JSON.stringify( this.canvas.toJSON() );
- const a = document.createElement( 'a' );
- const file = new Blob( [ json ], { type: 'text/plain' } );
- a.href = URL.createObjectURL( file );
- a.download = 'node_editor.json';
- a.click();
- } );
- menu.add( menuButton );
- menu.add( newButton );
- menu.add( openButton );
- menu.add( saveButton );
- this.domElement.appendChild( menu.dom );
- this.menu = menu;
- }
- _initContextMenu() {
- const context = new ContextMenu( this.domElement );
- const add = ( node ) => {
- const canvas = this.canvas;
- const canvasRect = canvas.rect;
- node.setPosition(
- ( canvas.relativeX + ( canvasRect.width / 2 ) ) - ( 350 / 2 ),
- ( canvas.relativeY + ( canvasRect.height / 2 ) ) - 20
- );
- context.hide();
- this.add( node );
- this.canvas.select( node );
- };
- //**************//
- //* INPUTS
- //**************//
- const inputsContext = new ContextMenu();
- const floatInput = new ButtonInput( 'Float' ).setIcon( 'ti ti-box-multiple-1' )
- .onClick( () => add( new FloatEditor() ) );
- //const vec2Input = new ButtonInput( 'Vector 2' ).setIcon( 'ti ti-box-multiple-2' );
- //const vec3Input = new ButtonInput( 'Vector 3' ).setIcon( 'ti ti-box-multiple-3' );
- //const vec4Input = new ButtonInput( 'Vector 4' ).setIcon( 'ti ti-box-multiple-4' );
- const colorInput = new ButtonInput( 'Color' ).setIcon( 'ti ti-palette' )
- .onClick( () => add( new ColorEditor() ) );
- //const mapInput = new ButtonInput( 'Map' ).setIcon( 'ti ti-photo' );
- //const cubeMapInput = new ButtonInput( 'Cube Map' ).setIcon( 'ti ti-box' );
- //const sliderInput = new ButtonInput( 'Slider' ).setIcon( 'ti ti-adjustments-horizontal' );
- //const integerInput = new ButtonInput( 'Integer' ).setIcon( 'ti ti-list-numbers' );
- inputsContext
- .add( floatInput )
- //.add( vec2Input )
- //.add( vec3Input )
- //.add( vec4Input )
- .add( colorInput );
- //.add( sliderInput );
- //**************//
- //* MATH
- //**************//
- const mathContext = new ContextMenu();
- const operatorsNode = new ButtonInput( 'Operators' ).setIcon( 'ti ti-math-symbols' )
- .onClick( () => add( new OperatorEditor() ) );
- mathContext
- .add( operatorsNode );
- //**************//
- //* ACCESSORS
- //**************//
- const accessorsContext = new ContextMenu();
- const uvNode = new ButtonInput( 'UV' ).setIcon( 'ti ti-details' )
- .onClick( () => add( new UVEditor() ) );
- const positionNode = new ButtonInput( 'Position' ).setIcon( 'ti ti-hierarchy' )
- .onClick( () => add( new PositionEditor() ) );
- const normalNode = new ButtonInput( 'Normal' ).setIcon( 'ti ti-fold-up' )
- .onClick( () => add( new NormalEditor() ) );
- accessorsContext
- .add( uvNode )
- .add( positionNode )
- .add( normalNode );
- //**************//
- //* PROCEDURAL
- //**************//
- const proceduralContext = new ContextMenu();
- const checkerNode = new ButtonInput( 'Checker' ).setIcon( 'ti ti-border-outer' )
- .onClick( () => add( new CheckerEditor() ) );
- proceduralContext
- .add( checkerNode );
- //**************//
- //* MAIN
- //**************//
- context.add( new ButtonInput( 'Inputs' ).setIcon( 'ti ti-forms' ), inputsContext );
- context.add( new ButtonInput( 'Accessors' ).setIcon( 'ti ti-vector-triangle' ), accessorsContext );
- context.add( new ButtonInput( 'Math' ).setIcon( 'ti ti-calculator' ), mathContext );
- context.add( new ButtonInput( 'Procedural' ).setIcon( 'ti ti-infinity' ), proceduralContext );
- this.domElement.appendChild( context.dom );
- this.context = context;
- }
- }
|