VisibleAnimationHandle.tsx 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import React from 'react';
  2. import { dataType, OriginRectType, ShowAnimateEnum } from '../types';
  3. interface VisibleHandleProps {
  4. visible: boolean;
  5. currentImage?: dataType;
  6. children: ({
  7. photoVisible,
  8. showAnimateType,
  9. originRect,
  10. onShowAnimateEnd,
  11. }: {
  12. photoVisible: boolean;
  13. showAnimateType: ShowAnimateEnum;
  14. originRect: OriginRectType;
  15. onShowAnimateEnd: () => void;
  16. }) => JSX.Element | null;
  17. }
  18. export default function VisibleAnimationHandle({
  19. visible,
  20. currentImage,
  21. children,
  22. }: VisibleHandleProps) {
  23. const [photoVisible, updatePhotoVisible] = React.useState(visible);
  24. const [showAnimateType, updateAnimateStatus] = React.useState<
  25. ShowAnimateEnum
  26. >(ShowAnimateEnum.None);
  27. const [originRect, updateOriginRect] = React.useState<OriginRectType>();
  28. function onShowAnimateEnd() {
  29. updateAnimateStatus(ShowAnimateEnum.None);
  30. // Close
  31. if (showAnimateType === ShowAnimateEnum.Out) {
  32. updatePhotoVisible(false);
  33. }
  34. }
  35. React.useEffect(() => {
  36. if (!currentImage) {
  37. return;
  38. }
  39. const originRef = currentImage.originRef;
  40. if (originRef && originRef.nodeType === 1) {
  41. // 获取触发时节点位置
  42. const { top, left, width, height } = originRef.getBoundingClientRect();
  43. updateOriginRect({
  44. clientX: left + width / 2,
  45. clientY: top + height / 2,
  46. });
  47. } else if (originRect && !originRef) {
  48. updateOriginRect(undefined);
  49. }
  50. if (visible) {
  51. updateAnimateStatus(ShowAnimateEnum.In);
  52. updatePhotoVisible(true);
  53. } else {
  54. updateAnimateStatus(ShowAnimateEnum.Out);
  55. }
  56. }, [visible]);
  57. return children({
  58. photoVisible,
  59. showAnimateType,
  60. originRect,
  61. onShowAnimateEnd,
  62. });
  63. }