ImageElementOperate.tsx 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import { useMemo } from 'react';
  2. import { useCanvasStore } from '@/lib/store';
  3. import type { PPTImageElement } 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 ImageElementOperateProps {
  10. readonly elementInfo: PPTImageElement;
  11. readonly handlerVisible: boolean;
  12. readonly rotateElement: (e: React.MouseEvent, element: PPTImageElement) => void;
  13. readonly scaleElement: (
  14. e: React.MouseEvent,
  15. element: PPTImageElement,
  16. command: OperateResizeHandlers,
  17. ) => void;
  18. }
  19. export function ImageElementOperate({
  20. elementInfo,
  21. handlerVisible,
  22. rotateElement,
  23. scaleElement,
  24. }: ImageElementOperateProps) {
  25. const canvasScale = useCanvasStore.use.canvasScale();
  26. const clipingImageElementId = useCanvasStore.use.clipingImageElementId();
  27. const isCliping = useMemo(
  28. () => clipingImageElementId === elementInfo.id,
  29. [clipingImageElementId, elementInfo.id],
  30. );
  31. const scaleWidth = useMemo(
  32. () => elementInfo.width * canvasScale,
  33. [elementInfo.width, canvasScale],
  34. );
  35. const scaleHeight = useMemo(
  36. () => elementInfo.height * canvasScale,
  37. [elementInfo.height, canvasScale],
  38. );
  39. const { resizeHandlers, borderLines } = useCommonOperate(scaleWidth, scaleHeight);
  40. return (
  41. <div className={`image-element-operate ${isCliping ? 'invisible' : ''}`}>
  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. }