colorPickerComponent.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import * as React from "react";
  2. import { Color4, Color3 } from 'babylonjs/Maths/math.color';
  3. import { SketchPicker } from 'react-color';
  4. export interface IColorPickerComponentProps {
  5. value: Color4 | Color3;
  6. onColorChanged: (newOne: string) => void;
  7. disableAlpha?: boolean;
  8. }
  9. interface IColorPickerComponentState {
  10. pickerEnabled: boolean;
  11. color: {
  12. r: number,
  13. g: number,
  14. b: number,
  15. a?: number
  16. },
  17. hex: string
  18. }
  19. export class ColorPickerLineComponent extends React.Component<IColorPickerComponentProps, IColorPickerComponentState> {
  20. private _floatRef: React.RefObject<HTMLDivElement>
  21. private _floatHostRef: React.RefObject<HTMLDivElement>
  22. constructor(props: IColorPickerComponentProps) {
  23. super(props);
  24. this.state = {pickerEnabled: false, color: {
  25. r: this.props.value.r * 255,
  26. g: this.props.value.g * 255,
  27. b: this.props.value.b * 255,
  28. a: this.props.value instanceof Color4 ? this.props.value.a * 100 : 100,
  29. }, hex: this.props.value.toHexString()};
  30. this._floatRef = React.createRef();
  31. this._floatHostRef = React.createRef();
  32. }
  33. syncPositions() {
  34. const div = this._floatRef.current as HTMLDivElement;
  35. const host = this._floatHostRef.current as HTMLDivElement;
  36. if (!div || !host) {
  37. return;
  38. }
  39. let top = host.getBoundingClientRect().top;
  40. let height = div.getBoundingClientRect().height;
  41. if (top + height + 10 > window.innerHeight) {
  42. top = window.innerHeight - height - 10;
  43. }
  44. div.style.top = top + "px";
  45. div.style.left = host.getBoundingClientRect().left - div.getBoundingClientRect().width + "px";
  46. }
  47. shouldComponentUpdate(nextProps: IColorPickerComponentProps, nextState: IColorPickerComponentState) {
  48. return nextProps.value.toHexString() !== this.props.value.toHexString()
  49. || nextProps.disableAlpha !== this.props.disableAlpha
  50. || nextState.hex !== this.state.hex
  51. || nextState.pickerEnabled !== this.state.pickerEnabled;
  52. }
  53. componentDidUpdate() {
  54. this.syncPositions();
  55. }
  56. componentDidMount() {
  57. this.syncPositions();
  58. }
  59. render() {
  60. var color = this.state.color;
  61. return (
  62. <div className="color-picker">
  63. <div className="color-rect" ref={this._floatHostRef}
  64. style={{background: this.state.hex}}
  65. onClick={() => this.setState({pickerEnabled: true})}>
  66. </div>
  67. {
  68. this.state.pickerEnabled &&
  69. <>
  70. <div className="color-picker-cover" onClick={() => this.setState({pickerEnabled: false})}></div>
  71. <div className="color-picker-float" ref={this._floatRef}>
  72. <SketchPicker color={color}
  73. disableAlpha={this.props.disableAlpha}
  74. onChange={(color) => {
  75. let hex: string;
  76. if (this.props.disableAlpha) {
  77. let newColor3 = Color3.FromInts(color.rgb.r, color.rgb.g, color.rgb.b);
  78. hex = newColor3.toHexString();
  79. } else {
  80. let newColor4 = Color4.FromInts(color.rgb.r, color.rgb.g, color.rgb.b, 255 * (color.rgb.a || 0));
  81. hex = newColor4.toHexString();
  82. }
  83. this.setState({hex: hex, color: color.rgb});
  84. this.props.onColorChanged(hex);
  85. }}
  86. />
  87. </div>
  88. </>
  89. }
  90. </div>
  91. );
  92. }
  93. }