ZoomWrapper.tsx 1.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. 'use client';
  2. import { motion } from 'motion/react';
  3. import type { ReactNode } from 'react';
  4. import type { PercentageGeometry } from '@/lib/types/action';
  5. interface ZoomWrapperProps {
  6. children: ReactNode;
  7. zoomTarget: { elementId: string; scale: number } | null;
  8. geometry: PercentageGeometry | null;
  9. }
  10. /**
  11. * 缩放包装器组件
  12. *
  13. * 功能:
  14. * - 包裹整个画布,根据 zoomTarget 进行缩放
  15. * - 以元素中心为缩放原点
  16. * - 使用百分比坐标系统
  17. */
  18. export function ZoomWrapper({ children, zoomTarget, geometry }: ZoomWrapperProps) {
  19. if (!zoomTarget || !geometry) {
  20. return <>{children}</>;
  21. }
  22. const { scale } = zoomTarget;
  23. const { centerX, centerY } = geometry;
  24. return (
  25. <motion.div
  26. className="w-full h-full"
  27. initial={{ scale: 1 }}
  28. animate={{ scale }}
  29. exit={{ scale: 1 }}
  30. transition={{
  31. type: 'spring',
  32. stiffness: 200,
  33. damping: 25,
  34. }}
  35. style={{
  36. transformOrigin: `${centerX}% ${centerY}%`,
  37. }}
  38. >
  39. {children}
  40. </motion.div>
  41. );
  42. }