CommonElementOperate.tsx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import { useMemo } from 'react';
  2. import { useCanvasStore } from '@/lib/store';
  3. import type {
  4. PPTVideoElement,
  5. PPTLatexElement,
  6. PPTAudioElement,
  7. PPTChartElement,
  8. } from '@/lib/types/slides';
  9. import type { OperateResizeHandlers } from '@/lib/types/edit';
  10. import { useCommonOperate } from '../hooks/useCommonOperate';
  11. import { RotateHandler } from './RotateHandler';
  12. import { ResizeHandler } from './ResizeHandler';
  13. import { BorderLine } from './BorderLine';
  14. type PPTElement = PPTVideoElement | PPTLatexElement | PPTAudioElement | PPTChartElement;
  15. interface CommonElementOperateProps {
  16. readonly elementInfo: PPTElement;
  17. readonly handlerVisible: boolean;
  18. readonly rotateElement: (e: React.MouseEvent, element: PPTElement) => void;
  19. readonly scaleElement: (
  20. e: React.MouseEvent,
  21. element: PPTElement,
  22. command: OperateResizeHandlers,
  23. ) => void;
  24. }
  25. export function CommonElementOperate({
  26. elementInfo,
  27. handlerVisible,
  28. rotateElement,
  29. scaleElement,
  30. }: CommonElementOperateProps) {
  31. const canvasScale = useCanvasStore.use.canvasScale();
  32. const scaleWidth = useMemo(
  33. () => elementInfo.width * canvasScale,
  34. [elementInfo.width, canvasScale],
  35. );
  36. const scaleHeight = useMemo(
  37. () => elementInfo.height * canvasScale,
  38. [elementInfo.height, canvasScale],
  39. );
  40. const { resizeHandlers, borderLines } = useCommonOperate(scaleWidth, scaleHeight);
  41. const cannotRotate = useMemo(
  42. () => ['chart', 'video', 'audio'].includes(elementInfo.type),
  43. [elementInfo.type],
  44. );
  45. return (
  46. <div className="common-element-operate">
  47. {borderLines.map((line) => (
  48. <BorderLine
  49. key={line.type}
  50. type={line.type}
  51. style={line.style}
  52. className="operate-border-line"
  53. />
  54. ))}
  55. {handlerVisible && (
  56. <>
  57. {resizeHandlers.map((point) => (
  58. <ResizeHandler
  59. key={point.direction}
  60. type={point.direction}
  61. rotate={elementInfo.rotate}
  62. style={point.style}
  63. className="operate-resize-handler"
  64. onMouseDown={(e) => {
  65. e.stopPropagation();
  66. scaleElement(e, elementInfo, point.direction);
  67. }}
  68. />
  69. ))}
  70. {!cannotRotate && (
  71. <RotateHandler
  72. className="operate-rotate-handler"
  73. style={{ left: scaleWidth / 2 + 'px' }}
  74. onMouseDown={(e) => {
  75. e.stopPropagation();
  76. rotateElement(e, elementInfo);
  77. }}
  78. />
  79. )}
  80. </>
  81. )}
  82. </div>
  83. );
  84. }