// Hlavní komponent aplikace
class ExampleApp1 extends React.Component {
// konstruktor komponentu
constructor(props) {
super(props);
// stav komponentu
this.state = {
text: 'Hello world!',
diffuseColor: '#dd3300'
};
}
// metoda pro vykreslení scény
renderScene() {
return (
<div className="fixed-ratio">
<a-scene embedded="">
<a-entity position="0 0 0" camera="" look-controls=""></a-entity>
<!-- data-binding textu -->
<a-text
value={this.state.text}
color={this.state.diffuseColor}
align="center"
position="0 0 -0.5">
</a-text>
</a-scene>
</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>
<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>
</form>
);
}
// hlavní vykreslovací metoda
render() {
return (
<div>
{this.renderScene()}
{this.renderControls()}
</div>
);
}
}
// vykreslení aplikace do HTML elementu
ReactDOM.render(<ExampleApp1 />, document.getElementById('app1'));
// Bezstavový komponent pro 3D kostku
const BoxAFrame = ({ instance, index }) => {
const { position, size, color } = instance;
return (
<a-entity position={(index * 2) + ' 0 0'}>
<a-box
color={color}
position={position.x + ' ' + position.y + ' ' + position.z}
width={size.x}
height={size.y}
depth={size.z}>
</a-box>
</a-entity>
);
}
// Bezstavový komponent pro 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);
// stav komponentu
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 volaná při připojení komponentu
componentDidMount() {
this.add();
this.add();
}
// 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;
});
};
// hlavní vykreslovací metoda
render() {
return (
<div>
<!-- 3D scéna -->
<div className="fixed-ratio">
<a-scene embedded="">
<a-entity position="0 0 0" camera="" look-controls=""></a-entity>
<a-entity position={(- this.state.boxes.length + 1) + ' 0 -5'}>
<!-- cyklus pro vykreslení 3D kostek -->
{this.state.boxes.map((box, index) => (
<BoxAFrame instance={box} index={index} key={index} />
))}
</a-entity>
</a-scene>
</div>
<!-- formulář pro ovládání -->
<form>
<ul>
<!-- cyklus pro ovládání jednotlivých kostek -->
{this.state.boxes.map((box, index) => (
<BoxControl instance={box} index={index} key={index} onChange={this.changeState(index)} remove={this.remove(index)} />
))}
</ul>
<a onClick={(e) => this.add()}>Přidat nový objekt</a>
</form>
</div>
);
}
}
// vykreslení aplikace do HTML elementu
ReactDOM.render(<ExampleApp2 />, document.getElementById('app2'));
// Bezstavový komponent 3D sedadla
const Seat = ({ row, column, enabled, picker }) => {
const click = () => picker(row, column);
return (
<a-entity position={(column * 1.4) + ' ' + (row * -0.5) + ' ' + (row * 2.5)}>
<a-box color={enabled ? '#0099ff' : '#ff9900'}
width="0.6"
height="0.5"
depth="0.5"
position="0 0 0"
data-clickable
onClick={click}>
</a-box>
<a-box color={enabled ? '#0055ee' : '#ee5500'}
width="0.2"
height="0.8"
depth="0.6"
position="0.4 0.15 0"
data-clickable
onClick={click}>
</a-box>
<a-box color={enabled ? '#0055ee' : '#ee5500'}
width="0.2"
height="0.8"
depth="0.6"
position="-0.4 0.15 0"
data-clickable
onClick={click}>
</a-box>
<a-box color={enabled ? '#0077ff' : '#ff7700'}
width="0.8"
height="1.2"
depth="0.1"
position="0 0.35 -0.25"
data-clickable
onClick={click}>
</a-box>
</a-entity>
);
}
// Bezstavový komponent tlačítka pro výběr sedadla
const SeatButton = ({ row, column, enabled, picker }) => {
const click = () => picker(row, column);
return (
<input type='button' className={enabled ? 'seat-free' : 'seat-taken' } onClick={click} value={'S ' + (column + 1)} />
);
}
// Hlavní komponent aplikace
class ExampleApp3 extends React.Component {
// konstruktor komponentu
constructor(props) {
super(props);
// stav komponentu
this.state = {
seats: [
[true, true, true, true, true, true, true],
[true, true, true, true, true, true, true],
[true, true, true, true, true, true, true],
[true, true, true, true, true, true, true]
],
free: 28,
taken: 0
};
}
// metoda pro získání funkce na vybrání sedadla
getSeatPicker() {
var that = this;
return (row, column) => {
that.setState((state) => {
state.seats[row][column] = !state.seats[row][column];
state.seats[row][column] ? (state.free++ , state.taken--) : (state.taken++ , state.free--);
return state;
});
}
}
// metoda pro vykreslování
render() {
return (
<div>
<!-- 3D scéna -->
<div className="fixed-ratio">
<a-scene embedded="">
<a-entity position="0 0 0" camera="" look-controls=""></a-entity>
<a-entity light="type: directional; color: #FFF; intensity: 2; castShadow:true;" position="10 5 10"></a-entity>
<a-entity position={(-this.state.seats[0].length / 2) + ' 0 ' + (-this.state.seats.length * 3)}>
<!-- cyklus pro vytvoření 3D sedadel v řadách -->
{this.state.seats.map((row, rowIndex) => (
row.map((enabled, colIndex) => (
<Seat row={rowIndex} column={colIndex} enabled={enabled} picker={this.getSeatPicker()} key={rowIndex + 'x' + colIndex} />
))
))}
</a-entity>
<a-entity cursor="rayOrigin: mouse; fuse: false;" raycaster="objects: [data-clickable];"></a-entity>
</a-scene>
</div>
<!-- tabulka -->
<form>
<h3>Vyberte sedadlo</h3>
<table>
<caption>Obsazeno je {this.state.taken}, zbývá {this.state.free} volných míst</caption>
<tbody>
<!-- cyklus pro tabulku sedadel -->
{this.state.seats.map((row, rowIndex) => (
<tr key={rowIndex}>
<td>Řada {rowIndex+1}</td>
{row.map((enabled, colIndex) => (
<td key={rowIndex + 'x' + colIndex}>
<SeatButton row={rowIndex} column={colIndex} enabled={enabled} picker={this.getSeatPicker()} />
</td>
))}
</tr>
))}
</tbody>
</table>
</form>
</div>
);
}
}
// vykreslení aplikace do HTML elementu
ReactDOM.render(<ExampleApp3 />, document.getElementById('app3'));