vector3LineComponent.tsx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import * as React from "react";
  2. import { Vector3, Observable } from "babylonjs";
  3. import { NumericInputComponent } from "./numericInputComponent";
  4. import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
  5. import { faMinus, faPlus } from "@fortawesome/free-solid-svg-icons";
  6. import { PropertyChangedEvent } from "../../propertyChangedEvent";
  7. interface IVector3LineComponentProps {
  8. label: string,
  9. target: any,
  10. propertyName: string,
  11. onChange?: (newvalue: Vector3) => void,
  12. onPropertyChangedObservable?: Observable<PropertyChangedEvent>
  13. }
  14. export class Vector3LineComponent extends React.Component<IVector3LineComponentProps, { isExpanded: boolean, value: Vector3 }> {
  15. private _localChange = false;
  16. constructor(props: IVector3LineComponentProps) {
  17. super(props);
  18. this.state = { isExpanded: false, value: this.props.target[this.props.propertyName].clone() }
  19. }
  20. shouldComponentUpdate(nextProps: IVector3LineComponentProps, nextState: { isExpanded: boolean, value: Vector3 }) {
  21. const nextPropsValue = nextProps.target[nextProps.propertyName];
  22. if (!nextPropsValue.equals(nextState.value) || this._localChange) {
  23. nextState.value = nextPropsValue.clone();
  24. this._localChange = false;
  25. return true;
  26. }
  27. return false;
  28. }
  29. switchExpandState() {
  30. this._localChange = true;
  31. this.setState({ isExpanded: !this.state.isExpanded });
  32. }
  33. raiseOnPropertyChanged(previousValue: Vector3) {
  34. if (this.props.onChange) {
  35. this.props.onChange(this.state.value);
  36. }
  37. if (!this.props.onPropertyChangedObservable) {
  38. return;
  39. }
  40. this.props.onPropertyChangedObservable.notifyObservers({
  41. object: this.props.target,
  42. property: this.props.propertyName,
  43. value: this.state.value,
  44. initialValue: previousValue
  45. });
  46. }
  47. updateStateX(value: number) {
  48. this._localChange = true;
  49. const store = this.state.value.clone();
  50. this.props.target[this.props.propertyName].x = value;
  51. this.state.value.x = value;
  52. this.setState({ value: this.state.value });
  53. this.raiseOnPropertyChanged(store);
  54. }
  55. updateStateY(value: number) {
  56. this._localChange = true;
  57. const store = this.state.value.clone();
  58. this.props.target[this.props.propertyName].y = value;
  59. this.state.value.y = value;
  60. this.setState({ value: this.state.value });
  61. this.raiseOnPropertyChanged(store);
  62. }
  63. updateStateZ(value: number) {
  64. this._localChange = true;
  65. const store = this.state.value.clone();
  66. this.props.target[this.props.propertyName].z = value;
  67. this.state.value.z = value;
  68. this.setState({ value: this.state.value });
  69. this.raiseOnPropertyChanged(store);
  70. }
  71. render() {
  72. const chevron = this.state.isExpanded ? <FontAwesomeIcon icon={faMinus} /> : <FontAwesomeIcon icon={faPlus} />
  73. return (
  74. <div className="vector3Line">
  75. <div className="firstLine">
  76. <div className="label">
  77. {this.props.label}
  78. </div>
  79. <div className="vector">
  80. {`X: ${this.state.value.x.toFixed(2)}, Y: ${this.state.value.y.toFixed(2)}, Z: ${this.state.value.z.toFixed(2)}`}
  81. </div>
  82. <div className="expand hoverIcon" onClick={() => this.switchExpandState()} title="Expand">
  83. {chevron}
  84. </div>
  85. </div>
  86. {
  87. this.state.isExpanded &&
  88. <div className="secondLine">
  89. <NumericInputComponent label="x" value={this.state.value.x} onChange={value => this.updateStateX(value)} />
  90. <NumericInputComponent label="y" value={this.state.value.y} onChange={value => this.updateStateY(value)} />
  91. <NumericInputComponent label="z" value={this.state.value.z} onChange={value => this.updateStateZ(value)} />
  92. </div>
  93. }
  94. </div>
  95. );
  96. }
  97. }