sliderLineComponent.tsx 3.9 KB

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