TextElementOperate.tsx 2.5 KB

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