index.tsx 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import React, { CSSProperties, PropsWithChildren } from 'react';
  2. import { hsvaToHslaString, hsvaToRgbaString } from "@douyinfe/semi-foundation/colorPicker/utils/convert";
  3. import { round } from "@douyinfe/semi-foundation/colorPicker/utils/round";
  4. import { cssClasses } from '@douyinfe/semi-foundation/colorPicker/constants';
  5. import BaseComponent from "../../_base/baseComponent";
  6. import AlphaSliderFoundation, {
  7. AlphaSliderAdapter,
  8. AlphaSliderBaseProps,
  9. AlphaSliderBaseState
  10. } from "@douyinfe/semi-foundation/colorPicker/AlphaSliderFoundation";
  11. export interface AlphaSliderProps extends AlphaSliderBaseProps {
  12. className?: string;
  13. style?: CSSProperties
  14. }
  15. export interface AlphaSliderState extends AlphaSliderBaseState {
  16. }
  17. class AlphaSlider extends BaseComponent<PropsWithChildren<AlphaSliderProps>, AlphaSliderState> {
  18. private ref: React.RefObject<HTMLDivElement>;
  19. constructor(props) {
  20. super(props);
  21. this.foundation = new AlphaSliderFoundation(this.adapter);
  22. this.state = {
  23. handlePosition: props.hsva.a * props.width - props.handleSize / 2,
  24. isHandleGrabbing: false
  25. };
  26. this.ref = React.createRef<HTMLDivElement>();
  27. }
  28. get adapter(): AlphaSliderAdapter<AlphaSliderProps, AlphaSliderState> {
  29. return {
  30. ...super.adapter,
  31. handleMouseDown: (e: any) => {
  32. this.setState({ isHandleGrabbing: true });
  33. window.addEventListener('mousemove', this.foundation.setHandlePositionByMousePosition);
  34. window.addEventListener('mouseup', this.foundation.handleMouseUp);
  35. },
  36. handleMouseUp: (e: MouseEvent) => {
  37. this.setState({ isHandleGrabbing: false });
  38. window.removeEventListener('mousemove', this.foundation.setHandlePositionByMousePosition);
  39. window.removeEventListener('mouseup', this.foundation.handleMouseUp);
  40. },
  41. getColorPickerFoundation: () => this.props.foundation,
  42. getDOM: () => this.ref.current
  43. };
  44. }
  45. componentDidUpdate(prevProps: Readonly<AlphaSliderBaseProps>, prevState: Readonly<AlphaSliderBaseState>, snapshot?: any) {
  46. if (prevProps.hsva.a !== this.props.hsva.a) {
  47. this.setState({ handlePosition: this.props.hsva.a * this.props.width - this.props.handleSize / 2 });
  48. }
  49. }
  50. handleClick = (e: React.MouseEvent) => {
  51. this.foundation.setHandlePositionByMousePosition(e);
  52. this.foundation.handleMouseDown(e);
  53. }
  54. render() {
  55. const colorFrom = hsvaToHslaString({ ...this.props.hsva, a: 0 });
  56. const colorTo = hsvaToHslaString({ ...this.props.hsva, a: 1 });
  57. const alphaSliderBackground = `linear-gradient(90deg, ${colorFrom}, ${colorTo})`;
  58. return <div className={`${cssClasses.PREFIX}-alphaSlider`} ref={this.ref}
  59. aria-label="Alpha"
  60. aria-valuetext={`${round(this.props.hsva.a * 100)}%`}
  61. onMouseDown={this.handleClick}
  62. style={{
  63. width: this.props.width,
  64. height: this.props.height,
  65. ...this.props.style
  66. }}>
  67. <div className={`${cssClasses.PREFIX}-alphaSliderInner`} style={{ background: alphaSliderBackground }}>
  68. <div className={`${cssClasses.PREFIX}-alphaHandle`}
  69. style={{
  70. width: this.props.handleSize,
  71. height: this.props.handleSize,
  72. left: this.state.handlePosition,
  73. top: `50%`,
  74. transform: `translateY(-50%)`,
  75. backgroundColor: hsvaToRgbaString(this.props.hsva)
  76. }}
  77. onMouseDown={(e) => this.foundation.handleMouseDown(e)}>
  78. </div>
  79. </div>
  80. </div>;
  81. }
  82. }
  83. export default AlphaSlider;