sliderLineComponent.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import * as React from "react";
  2. import { Observable } from "babylonjs/Misc/observable";
  3. import { Tools } from 'babylonjs/Misc/tools';
  4. import { PropertyChangedEvent } from './propertyChangedEvent';
  5. import { FloatLineComponent } from './floatLineComponent';
  6. import { GlobalState } from '../globalState';
  7. interface ISliderLineComponentProps {
  8. label: string;
  9. target?: any;
  10. propertyName?: string;
  11. minimum: number;
  12. maximum: number;
  13. step: number;
  14. directValue?: number;
  15. useEuler?: boolean;
  16. onChange?: (value: number) => void;
  17. onInput?: (value: number) => void;
  18. onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
  19. decimalCount?: number;
  20. globalState: GlobalState;
  21. }
  22. export class SliderLineComponent extends React.Component<ISliderLineComponentProps, { value: number }> {
  23. private _localChange = false;
  24. constructor(props: ISliderLineComponentProps) {
  25. super(props);
  26. if (this.props.directValue !== undefined) {
  27. this.state = {
  28. value: this.props.directValue
  29. }
  30. } else {
  31. let value = this.props.target![this.props.propertyName!];
  32. if (value === undefined) {
  33. value = this.props.maximum;
  34. }
  35. this.state = { value: value };
  36. }
  37. }
  38. shouldComponentUpdate(nextProps: ISliderLineComponentProps, nextState: { value: number }) {
  39. if (nextProps.directValue !== undefined) {
  40. nextState.value = nextProps.directValue;
  41. return true;
  42. }
  43. let currentState = nextProps.target![nextProps.propertyName!];
  44. if (currentState === undefined) {
  45. currentState = nextProps.maximum;
  46. }
  47. if (currentState !== nextState.value || nextProps.minimum !== this.props.minimum || nextProps.maximum !== this.props.maximum || this._localChange) {
  48. nextState.value = Math.min(Math.max(currentState, nextProps.minimum), nextProps.maximum);
  49. this._localChange = false;
  50. return true;
  51. }
  52. return false;
  53. }
  54. onChange(newValueString: any) {
  55. this._localChange = true;
  56. let newValue = parseFloat(newValueString);
  57. if (this.props.useEuler) {
  58. newValue = Tools.ToRadians(newValue);
  59. }
  60. if (this.props.target) {
  61. if (this.props.onPropertyChangedObservable) {
  62. this.props.onPropertyChangedObservable.notifyObservers({
  63. object: this.props.target,
  64. property: this.props.propertyName!,
  65. value: newValue,
  66. initialValue: this.state.value
  67. });
  68. }
  69. this.props.target[this.props.propertyName!] = newValue;
  70. }
  71. if (this.props.onChange) {
  72. this.props.onChange(newValue);
  73. }
  74. this.setState({ value: newValue });
  75. }
  76. onInput(newValueString: any) {
  77. const newValue = parseFloat(newValueString);
  78. if (this.props.onInput) {
  79. this.props.onInput(newValue);
  80. }
  81. }
  82. prepareDataToRead(value: number) {
  83. if (this.props.useEuler) {
  84. return Tools.ToDegrees(value);
  85. }
  86. return value;
  87. }
  88. render() {
  89. return (
  90. <div className="sliderLine">
  91. <div className="label">
  92. {this.props.label}
  93. </div>
  94. <FloatLineComponent globalState={this.props.globalState} smallUI={true} label="" target={this.state} propertyName="value" min={this.prepareDataToRead(this.props.minimum)} max={this.prepareDataToRead(this.props.maximum)}
  95. onEnter={ () => {
  96. this.onChange(this.state.value)
  97. }
  98. } >
  99. </FloatLineComponent>
  100. <div className="slider">
  101. <input className="range" type="range" step={this.props.step} min={this.prepareDataToRead(this.props.minimum)} max={this.prepareDataToRead(this.props.maximum)} value={this.prepareDataToRead(this.state.value)}
  102. onInput={evt => this.onInput((evt.target as HTMLInputElement).value)}
  103. onChange={evt => this.onChange(evt.target.value)} />
  104. </div>
  105. </div>
  106. );
  107. }
  108. }