vector4LineComponent.tsx 5.0 KB

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