Zpět

React & Babylon.js & React BabylonJS

Ukázka #1 - Data-binding do 3D scény

  • // Vyžaduje kompilaci pomocí: npm run build
    
    // importy
    import React from 'react';
    import ReactDOM from 'react-dom';
    import { Engine, Scene, ArcRotateCamera, HemisphericLight } from 'react-babylonjs';
    import { Vector3, Color3, Color4 } from '@babylonjs/core';
    import { Control } from '@babylonjs/gui';
    
    // Hlavní komponent aplikace
    class ExampleApp1 extends React.Component {
    
    	// konstruktor komponentu
    	constructor(props) {
    		super(props);
    		this.state = {
    			text: 'Hello world!',
    			diffuseColor: '#dd3300',
    			outlineColor: '#ee9966'
    		};
    	}
    	
    	// metoda volaná po připojení scény
    	onSceneMount(e) {
    		const { scene } = e;
    		scene.clearColor = new Color4(0.133, 0.133, 0.133, 1);
    	}
    	
    	// metoda pro vykreslení scény
    	renderScene() {
    		return (
    			<div className="fixed-ratio">
    				<Engine antialias adaptToDeviceRatio>
    				  <Scene onSceneMount={this.onSceneMount}>
    					<ArcRotateCamera name="camera1" radius={7} beta={Math.PI / 2} alpha={-(Math.PI / 2)} target={Vector3.Zero()} minZ={0.001} wheelPrecision={30} />
    					<HemisphericLight name="light1" intensity={0.7} direction={Vector3.Up()} />
    					<plane name='plane1' width={20} height={20}>
    						<advancedDynamicTexture name='texture1' height={2048} width={2048} createForParentMesh>
    							<textBlock
    								name='text1'
    								text={this.state.text}
    								color={this.state.diffuseColor}
    								fontSize={200}
    								outlineWidth={5}
    								outlineColor={this.state.outlineColor}
    							/>
    						</advancedDynamicTexture>
    					</plane>
    				  </Scene>
    				</Engine>
    			</div>
    		);
    	}
    
        // metoda pro vykreslení ovládacích prvků
    	renderControls() {
    		return (
    			<form>
    				<div>
    					<label>Text</label>
    					<!-- data-binding textu do vstupu, listener pro změnu -->
    					<input type="text"
                            value={this.state.text}
                            onChange={(e) => this.setState({ text: e.target.value })}
                        />
    				</div>
    				<div className="grid">
    				    <div>
    					    <label>Základní barva</label>
    					    <div>
    						    <input 
                                    type="color"
                                    value={this.state.diffuseColor}
                                    onChange={(e) => this.setState({ diffuseColor: e.target.value })} 
                                />
    						    <span style={{ color: this.state.diffuseColor }}>{this.state.diffuseColor}</span>
    					    </div>
    				    </div>
    				    <div>
    					    <label>Barva okraje</label>
    					    <div>
    						    <input 
                                    type="color"
                                    value={this.state.outlineColor}
                                    onChange={(e) => this.setState({ outlineColor: e.target.value })} 
                                />
    						    <span style={{ color: this.state.outlineColor }}>{this.state.outlineColor}</span>
    					    </div>
    				    </div>
    				</div>
    			</form>
    		);
    	}
    	
        // hlavní vykreslovací metoda
    	render() {
    		return (
    			<div>
    				{this.renderScene()}
    				{this.renderControls()}
    			</div>
    		);
    	}
    }
    
    // vykreslení aplikace do HTML elementu
    ReactDOM.render(<ExampleApp1 />, document.getElementById('app1'));
    
  • 
    npm install
    npm install react
    npm install react-dom
    npm install react-scripts
    npm install react-reconciler
    npm install @babylonjs/core
    npm install @babylonjs/gui
    npm install @babylonjs/loaders
    npm install react-babylonjs
    npm run start
    

Ukázka #2 - Práce s polem

  • // Vyžaduje kompilaci pomocí: npm run build
    
    // importy
    import React from 'react';
    import ReactDOM from 'react-dom';
    import { Engine, Scene, ArcRotateCamera, PointLight } from 'react-babylonjs';
    import { Vector3, Color3, Color4 } from '@babylonjs/core';
    
    // Bezstavový komponent koskty
    const BoxBabylon = ({ instance, index, total }) => {
        const { position, size, color } = instance;
        return (
    	  <box name={ 'box' + index }
    		size={1}
    		position={new Vector3((position.x + (index * 2) + 1 - total), position.y, position.z)}
    		scaling={new Vector3(size.x, size.y, size.z)}>
    		<standardMaterial name={'mat' + index} diffuseColor={Color3.FromHexString(color)} />
    	  </box>
        );
    }
    
    // Bezstavový komponent ovládání kostky
    const BoxControl = ({ instance, index, onChange, remove }) => {
        const { position, size, color } = instance;
        return (
    		<li>
    			<div>
    				<div className="grid">
    					<div>
    						<label>Objekt {index + 1}</label>
    						<div>
    							<input type="color" value={color} onChange={onChange((box, value) => box.color = value)} />
    							<span style={{ color: color }}> { color } </span>
    						</div>
    					</div>
    					<div>
    						<div className="grid">
    							<div>
    								<label>↔ W { Math.floor(size.x * 100) }%</label>
    								<input type="range" value={size.x} min={0.1} max={2} step={0.1} onChange={onChange((box, value) => box.size.x = value)} />
    							</div>
    							<div>
    								<label>↕ H { Math.floor(size.y * 100) }%</label>
    								<input type="range" value={size.y} min={0.1} max={2} step={0.1} onChange={onChange((box, value) => box.size.y = value)} />
    							</div>
    							<div>
    								<label>⤢ L { Math.floor(size.z * 100) }%</label>
    								<input type="range" value={size.z} min={0.1} max={2} step={0.1} onChange={onChange((box, value) => box.size.z = value)} />
    							</div>
    							<div>
    								<label>→ X { position.x }</label>
    								<input type="range" value={position.x} min={-1} max={1} step={0.1} onChange={onChange((box, value) => box.position.x = value)} />
    							</div>
    							<div>
    								<label">↑ Y { position.y }</label>
    								<input type="range" value={position.y} min={-1} max={1} step={0.1} onChange={onChange((box, value) => box.position.y = value)} />
    							</div>
    							<div>
    								<label">↗ Z { position.z }</label>
    								<input type="range" value={position.z} min={-1} max={1} step={0.1} onChange={onChange((box, value) => box.position.z = value)} />
    							</div>
    						</div>
    					</div>
    					<div>
    						<a onClick={() => remove()}>Smazat</a>
    					</div>
    				</div>
    			</div>
    		</li>
        );
    }
    
    // Hlavní komponent aplikace
    class ExampleApp2 extends React.Component {
    
        // konstruktor komponentu
        constructor(props) {
            super(props);
            this.state = {
                boxes: []
            };
        }
    
        // metoda pro získání funkce pro změnu stavu kostky
        changeState(index) {
            var that = this;
            return (boxStateHandler) => {
                return (e) => {
                    var value = e.target.value;
                    return that.setState((state) => {
                        boxStateHandler(state.boxes[index], value);
                        return state;
                    });
                }
            }
        }
    
        // metoda pro smazání kostky
        remove(index) {
            var that = this;
            return () => {
                return that.setState((state) => {
                    state.boxes.splice(index, 1);
                    return state;
                });
            }
        }
    
        // metoda pro přidání kostky
        add() {
            this.setState((state) => {
                state.boxes.push({
                    position: { x: 0, y: 0, z: 0 },
                    size: { x: 1, y: 1, z: 1 },
                    color: "#ff9900" // nebo jiná náhodná barva
                });
                return state;
            });
        };
    
        // metoda volaná při připojení komponentu
    	componentDidMount() {
    		this.add();
    	}
    
        // metoda volaná při připojení scény
    	onSceneMount(e) {
    		const { scene } = e;
            scene.clearColor = new Color4(0.133, 0.133, 0.133, 1);
    	}
    
        // metoda pro vykreslení
        render() {
            return (
                <div>
                    <div className="fixed-ratio">
    					<Engine antialias adaptToDeviceRatio>
    					  <Scene onSceneMount={this.onSceneMount}>
    						<ArcRotateCamera name="camera1" radius={7} beta={Math.PI / 2} alpha={-(Math.PI / 2)} target={Vector3.Zero()} minZ={0.001} wheelPrecision={30} />
                            <PointLight name="light1" position={new Vector3(2,2,-5)} intensity={0.7} />
    						{this.state.boxes.map((box, index) => (
    							<BoxBabylon instance={box} index={index} total={this.state.boxes.length} key={index} />
    						))}
    					  </Scene>
    					</Engine>
                    </div>
                    <formgt;
                        <ul>
                            {this.state.boxes.map((box, index) => (
                                <BoxControl instance={box} index={index} key={index} onChange={this.changeState(index)} remove={this.remove(index)} />
                            ))}
                        </ul>
                        <div onClick={(e) => this.add()}>Přidat nový objekt</div>
                    </form>
                </div>
            );
        }
    }
    
    // vykreslení aplikace do HTML elementu
    ReactDOM.render(<ExampleApp2 />, document.getElementById('app2'));
    
  • 
    npm install
    npm install react
    npm install react-dom
    npm install react-scripts
    npm install react-reconciler
    npm install @babylonjs/core
    npm install @babylonjs/gui
    npm install @babylonjs/loaders
    npm install react-babylonjs
    npm run start