vector3LineComponent.tsx 4.2 KB

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