vector4LineComponent.tsx 4.7 KB

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