@cs-open/react-fabric 0.0.13 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/README.md +18 -13
  2. package/dist/cjs/components/BackgroundImage/index.cjs +1 -1
  3. package/dist/cjs/components/BackgroundImage/index.cjs.map +1 -1
  4. package/dist/cjs/components/Canvas/index.cjs +1 -1
  5. package/dist/cjs/components/Canvas/index.cjs.map +1 -1
  6. package/dist/cjs/components/IText/index.cjs.map +1 -1
  7. package/dist/cjs/components/Objects/index.cjs.map +1 -1
  8. package/dist/cjs/components/Text/index.cjs +1 -1
  9. package/dist/cjs/components/Text/index.cjs.map +1 -1
  10. package/dist/cjs/container/ReactFabric/index.cjs +1 -1
  11. package/dist/cjs/container/ReactFabric/index.cjs.map +1 -1
  12. package/dist/esm/components/BackgroundImage/index.mjs +1 -1
  13. package/dist/esm/components/BackgroundImage/index.mjs.map +1 -1
  14. package/dist/esm/components/Canvas/index.mjs +1 -1
  15. package/dist/esm/components/Canvas/index.mjs.map +1 -1
  16. package/dist/esm/components/IText/index.mjs +1 -1
  17. package/dist/esm/components/IText/index.mjs.map +1 -1
  18. package/dist/esm/components/Objects/index.mjs.map +1 -1
  19. package/dist/esm/components/Text/index.mjs +1 -1
  20. package/dist/esm/components/Text/index.mjs.map +1 -1
  21. package/dist/esm/container/ReactFabric/index.mjs +1 -1
  22. package/dist/esm/container/ReactFabric/index.mjs.map +1 -1
  23. package/dist/types/components/BackgroundImage/index.d.ts +5 -1
  24. package/dist/types/components/BackgroundImage/index.d.ts.map +1 -1
  25. package/dist/types/components/Canvas/index.d.ts.map +1 -1
  26. package/dist/types/components/Objects/index.d.ts.map +1 -1
  27. package/dist/types/components/Text/index.d.ts +6 -2
  28. package/dist/types/components/Text/index.d.ts.map +1 -1
  29. package/dist/types/container/ReactFabric/index.d.ts +105 -22
  30. package/dist/types/container/ReactFabric/index.d.ts.map +1 -1
  31. package/dist/types/types/canvas.d.ts +3 -2
  32. package/dist/types/types/canvas.d.ts.map +1 -1
  33. package/package.json +9 -9
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  React 组件库,基于 Fabric.js 构建,提供强大的 Canvas 绘图功能。
4
4
 
5
+ <img width="1770" height="1478" alt="react-fabric demo" src="https://github.com/user-attachments/assets/02ff8152-bad3-4e99-82db-13eefc5413b0" />
6
+
5
7
  ## 安装
6
8
 
7
9
  ```bash
@@ -12,19 +14,6 @@ yarn add @cs-open/react-fabric
12
14
  pnpm add @cs-open/react-fabric
13
15
  ```
14
16
 
15
- ## 依赖要求
16
-
17
- ### 必需依赖
18
-
19
- 以下依赖会自动安装:
20
-
21
- - `fabric` - Fabric.js 核心库
22
- - `react` - React 框架
23
- - `react-dom` - React DOM 渲染器
24
- - `zustand` - 状态管理
25
- - `@floating-ui/core` - 浮动 UI 组件
26
- - `use-sync-external-store` - 同步外部存储
27
-
28
17
  ### 可选依赖
29
18
 
30
19
  某些插件需要额外的依赖才能正常工作:
@@ -130,3 +119,19 @@ DOM control
130
119
  ## 许可证
131
120
 
132
121
  MIT
122
+
123
+ ```jsx
124
+ pnpm run changeset // 修改 changeset.md
125
+ 全选 changed & unchanged enter
126
+ 不选 enter major
127
+ 不选 enter minor
128
+ Summary 随便写
129
+ desired changeset ? true
130
+ pnpm run version-packages // 修改 package.json 的 version
131
+ pnpm install // 修改 lock 文件
132
+ git add .
133
+ git commit -m 'chore(core): version bump'
134
+ git push
135
+ 提交pr到main
136
+ 通过 github action 自动发布到 npm
137
+ ```
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var h=require("fabric"),s=require("react"),F=require("../../hooks/useDidUpdate.cjs"),w=require("../../hooks/useStore.cjs");const q=o=>({width:o.width,height:o.height}),R=s.forwardRef(({src:o,onLoad:b,onScaling:V,scaleToFit:l,scaleToCover:g,...d},S)=>{const a=s.useRef(null),n=w.useStoreApi(),{width:T,height:p}=w.useStore(q),m=s.useCallback(c=>{const{canvas:e,manualZoom:r=1,defaultCentered:f}=n.getState();if(!a.current)return;if(!e){console.warn("updateViewport: !canvas");return}if(!e.backgroundImage){console.warn("updateViewport: !canvas.backgroundImage");return}const i=c.scaleToFit?h.util.findScaleToFit(a.current,e):c.scaleToCover?h.util.findScaleToCover(a.current,e):1,t=i*r;e.setViewportTransform([t,0,0,t,0,0]);let u=0,v=0;if(f&&e.backgroundImage){const k=e.backgroundImage.width||0,C=e.backgroundImage.height||0;u=(e.width-k*t)/2,v=(e.height-C*t)/2}const I=[t,0,0,t,u,v];e.setViewportTransform(I),e.requestRenderAll(),n.setState({fitZoom:i,manualZoom:r,zoom:t})},[n]);return s.useEffect(()=>{m({scaleToFit:l,scaleToCover:g})},[T,p,l,g,m,n]),s.useEffect(()=>{if(!o){console.warn("ReactFabricBackgroundImage: !src");return}const{domNode:c,setLoading:e}=n.getState();return e(!0),h.FabricImage.fromURL(o,{crossOrigin:"anonymous"}).then(r=>{const f=r.getSrc(),i=a.current?.getSrc();if(i&&f!==i)return;const{canvas:t}=n.getState();if(t){const u={...d,angle:0};if(r.set({...u,objectCaching:!1}),t.getContext().imageSmoothingEnabled=!0,t.getContext().imageSmoothingQuality="high",t.backgroundImage=r,a.current=r,requestAnimationFrame(()=>{m({scaleToFit:l,scaleToCover:g})}),!t.viewportTransform){console.warn("!viewport");return}b?.(r)}else console.warn("ReactFabric:BackgroundImage: !canvas",t)}).catch(console.error).finally(()=>{c&&(c.dataset.src=o),e(!1)}),()=>{const{canvas:r}=n.getState();r?.backgroundImage&&(r.backgroundImage=void 0,r.remove(a.current),a.current=null,r.renderAll())}},[o]),F.useDidUpdate(()=>{const{canvas:c}=n.getState();a.current&&(Object.entries(d).forEach(([e,r])=>{e==="angle"?a.current?.rotate(r):a.current?.set(e,r)}),c?.requestRenderAll())},[d,n]),s.useImperativeHandle(S,()=>({instance:a.current})),null});var A=s.memo(R);exports.default=A;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var f=require("fabric"),c=require("react"),q=require("../../hooks/useDidUpdate.cjs"),w=require("../../hooks/useStore.cjs");const A=a=>({width:a.width,height:a.height}),E=c.forwardRef(({src:a,onLoad:S,onScaling:j,onError:T,scaleToFit:l,scaleToCover:g,...d},k)=>{const t=c.useRef(null),o=w.useStoreApi(),h=c.useRef(a),{width:p,height:I}=w.useStore(A),m=c.useCallback(i=>{const{canvas:r,manualZoom:e=1,defaultCentered:n}=o.getState();if(!t.current)return;if(!r){console.warn("updateViewport: !canvas");return}if(!r.backgroundImage){console.warn("updateViewport: !canvas.backgroundImage");return}const u=i.scaleToFit?f.util.findScaleToFit(t.current,r):i.scaleToCover?f.util.findScaleToCover(t.current,r):1,s=u*e;r.setViewportTransform([s,0,0,s,0,0]);let v=0,b=0;if(n&&r.backgroundImage){const R=r.backgroundImage.width||0,C=r.backgroundImage.height||0;v=(r.width-R*s)/2,b=(r.height-C*s)/2}const F=[s,0,0,s,v,b];r.setViewportTransform(F),r.requestRenderAll(),o.setState({fitZoom:u,manualZoom:e,zoom:s})},[o]);return c.useEffect(()=>{m({scaleToFit:l,scaleToCover:g})},[p,I,l,g,m,o]),c.useEffect(()=>{if(!a){console.warn("ReactFabricBackgroundImage: !src");return}const{domNode:i,setLoading:r}=o.getState();return r(!0),h.current=a,f.FabricImage.fromURL(a,{crossOrigin:"anonymous"}).then(e=>{if(S?.(e),e.getSrc()!==h.current)return;const{canvas:n}=o.getState();if(n){const u={...d,angle:0};if(e.set({...u,objectCaching:!1}),n.getContext().imageSmoothingEnabled=!0,n.getContext().imageSmoothingQuality="high",n.backgroundImage=e,t.current=e,requestAnimationFrame(()=>{m({scaleToFit:l,scaleToCover:g})}),!n.viewportTransform){console.warn("!viewport");return}}else console.warn("ReactFabric:BackgroundImage: !canvas",n)}).catch(e=>{T?.(e),console.error("[ReactFabric] BackgroundImage: fromURL error",e)}).finally(()=>{i&&(i.dataset.src=a),r(!1)}),()=>{const{canvas:e}=o.getState();e?.backgroundImage&&(e.backgroundImage=void 0,e.remove(t.current),t.current=null,e.renderAll())}},[a]),q.useDidUpdate(()=>{const{canvas:i}=o.getState();t.current&&(Object.entries(d).forEach(([r,e])=>{r==="angle"?t.current?.rotate(e):t.current?.set(r,e)}),i?.requestRenderAll())},[d,o]),c.useImperativeHandle(k,()=>({instance:t.current})),null});var L=c.memo(E);exports.default=L;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../../../src/components/BackgroundImage/index.tsx"],"sourcesContent":["import type {\n BasicTransformEvent,\n ImageProps,\n ObjectEvents,\n SerializedImageProps,\n TDegree,\n TPointerEvent,\n} from 'fabric'\nimport { FabricImage, util } from 'fabric'\nimport { forwardRef, memo, useCallback, useEffect, useImperativeHandle, useRef } from 'react'\nimport { useDidUpdate } from '../../hooks/useDidUpdate'\nimport { useStore, useStoreApi } from '../../hooks/useStore'\nimport type { ReactFabricState } from '../../types/store'\n\nexport type Handle = {}\n\ntype ScaleMode = {\n scaleToFit?: boolean\n scaleToCover?: boolean\n}\nexport type BackgroundImageProps = Partial<ImageProps> & {\n src: string\n onLoad?: (imageSource: FabricImage<Partial<ImageProps>, SerializedImageProps, ObjectEvents>) => void\n onScaling?: (scale: BasicTransformEvent<TPointerEvent>) => void\n\n /** 自动缩放至容器宽高 */\n} & ScaleMode\n\nconst selector = (s: ReactFabricState) => ({\n width: s.width,\n height: s.height,\n})\n\nconst BackgroundImage = forwardRef<Handle, BackgroundImageProps>(\n ({ src, onLoad, onScaling, scaleToFit, scaleToCover, ...options }, ref) => {\n const backgroundImageRef = useRef<FabricImage | null>(null)\n\n const store = useStoreApi()\n\n const { width, height } = useStore(selector)\n\n const updateViewport = useCallback(\n (params: { scaleToFit?: boolean; scaleToCover?: boolean }) => {\n const { canvas, manualZoom = 1, defaultCentered } = store.getState()\n if (!backgroundImageRef.current) {\n return\n }\n if (!canvas) {\n console.warn('updateViewport: !canvas')\n return\n }\n if (!canvas.backgroundImage) {\n console.warn('updateViewport: !canvas.backgroundImage')\n return\n }\n\n // 1. 计算缩放\n const fitZoom = params.scaleToFit\n ? util.findScaleToFit(backgroundImageRef.current, canvas)\n : params.scaleToCover\n ? util.findScaleToCover(backgroundImageRef.current, canvas)\n : 1\n\n const combinedZoom = fitZoom * manualZoom\n\n // 2. 先应用基础缩放\n canvas.setViewportTransform([combinedZoom, 0, 0, combinedZoom, 0, 0])\n\n // 3. 如果需要居中,计算偏移量\n let deltaX = 0\n let deltaY = 0\n\n if (defaultCentered && canvas.backgroundImage) {\n const bgWidth = canvas.backgroundImage.width || 0\n const bgHeight = canvas.backgroundImage.height || 0\n deltaX = (canvas.width! - bgWidth * combinedZoom) / 2\n deltaY = (canvas.height! - bgHeight * combinedZoom) / 2\n // const canvasCenter = {\n // x: canvas.width! / 2,\n // y: canvas.height! / 2,\n // }\n // const bgCenter = {\n // x:\n // (canvas.backgroundImage.left! + (canvas.backgroundImage.width! * canvas.backgroundImage.scaleX!) / 2) *\n // combinedZoom,\n // y:\n // (canvas.backgroundImage.top! + (canvas.backgroundImage.height! * canvas.backgroundImage.scaleY!) / 2) *\n // combinedZoom,\n // }\n // deltaX = canvasCenter.x - bgCenter.x\n // deltaY = canvasCenter.y - bgCenter.y\n }\n\n // 4. 应用最终变换\n const finalTransform: [number, number, number, number, number, number] = [\n combinedZoom,\n 0,\n 0,\n combinedZoom,\n deltaX,\n deltaY,\n ]\n\n canvas.setViewportTransform(finalTransform)\n canvas.requestRenderAll()\n\n // 5. 更新 store\n store.setState({\n fitZoom,\n manualZoom,\n zoom: combinedZoom,\n })\n },\n [store],\n )\n\n // 监听 width, height 的变化\n useEffect(() => {\n updateViewport({\n scaleToFit,\n scaleToCover,\n })\n }, [width, height, scaleToFit, scaleToCover, updateViewport, store])\n\n useEffect(() => {\n if (!src) {\n console.warn('ReactFabricBackgroundImage: !src')\n return\n }\n const { domNode, setLoading } = store.getState()\n setLoading(true)\n FabricImage.fromURL(src, { crossOrigin: 'anonymous' })\n .then(imageSource => {\n const currentSrc = imageSource.getSrc()\n const latestSrc = backgroundImageRef.current?.getSrc()\n\n if (latestSrc && currentSrc !== latestSrc) {\n return\n }\n\n const { canvas } = store.getState()\n if (canvas) {\n // 初始化时角度的旋转,一定要放到 updateViewport 之后;先画正图片,再进行旋转\n const removeAngleOptions = { ...options, angle: 0 }\n imageSource.set({\n ...removeAngleOptions,\n objectCaching: false,\n })\n canvas.getContext().imageSmoothingEnabled = true\n canvas.getContext().imageSmoothingQuality = 'high'\n canvas.backgroundImage = imageSource\n backgroundImageRef.current = imageSource\n\n requestAnimationFrame(() => {\n updateViewport({\n scaleToFit,\n scaleToCover,\n })\n })\n\n const viewport = canvas.viewportTransform\n if (!viewport) {\n console.warn('!viewport')\n return\n }\n\n // imageSource.angle = options.angle || 0\n onLoad?.(imageSource)\n } else {\n console.warn('ReactFabric:BackgroundImage: !canvas', canvas)\n }\n })\n .catch(console.error)\n .finally(() => {\n if (domNode) domNode.dataset.src = src\n setLoading(false)\n })\n\n return () => {\n const { canvas } = store.getState()\n if (canvas?.backgroundImage) {\n canvas.backgroundImage = undefined\n canvas.remove(backgroundImageRef.current!)\n backgroundImageRef.current = null\n canvas.renderAll()\n }\n }\n }, [src])\n\n useDidUpdate(() => {\n const { canvas } = store.getState()\n\n if (backgroundImageRef.current) {\n Object.entries(options).forEach(([key, value]) => {\n if (key === 'angle') {\n backgroundImageRef.current?.rotate(value as TDegree)\n } else {\n backgroundImageRef.current?.set(key, value)\n }\n })\n canvas?.requestRenderAll()\n }\n }, [options, store])\n\n useImperativeHandle(ref, () => ({\n // 是最新的?\n instance: backgroundImageRef.current,\n }))\n\n return null\n },\n)\n\nexport default memo(BackgroundImage)\n"],"names":["selector","s","BackgroundImage","forwardRef","src","onLoad","onScaling","scaleToFit","scaleToCover","options","ref","backgroundImageRef","useRef","store","useStoreApi","width","height","useStore","updateViewport","useCallback","params","canvas","manualZoom","defaultCentered","fitZoom","util","combinedZoom","deltaX","deltaY","bgWidth","bgHeight","finalTransform","useEffect","domNode","setLoading","FabricImage","imageSource","currentSrc","latestSrc","removeAngleOptions","useDidUpdate","key","value","useImperativeHandle","memo"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../../../../src/components/BackgroundImage/index.tsx"],"sourcesContent":["import type {\n BasicTransformEvent,\n ImageProps,\n ObjectEvents,\n SerializedImageProps,\n TDegree,\n TPointerEvent,\n} from 'fabric'\nimport { FabricImage, util } from 'fabric'\nimport { forwardRef, memo, useCallback, useEffect, useImperativeHandle, useRef } from 'react'\nimport { useDidUpdate } from '../../hooks/useDidUpdate'\nimport { useStore, useStoreApi } from '../../hooks/useStore'\nimport type { ReactFabricState } from '../../types/store'\n\nexport type Handle = {\n instance: FabricImage | null\n}\n\ntype ScaleMode = {\n scaleToFit?: boolean\n scaleToCover?: boolean\n}\nexport type BackgroundImageProps = Partial<ImageProps> & {\n src: string\n onLoad?: (imageSource: FabricImage<Partial<ImageProps>, SerializedImageProps, ObjectEvents>) => void\n onScaling?: (scale: BasicTransformEvent<TPointerEvent>) => void\n onError?: (e: any) => void\n\n /** 自动缩放至容器宽高 */\n} & ScaleMode\n\nconst selector = (s: ReactFabricState) => ({\n width: s.width,\n height: s.height,\n})\n\nconst BackgroundImage = forwardRef<Handle, BackgroundImageProps>(\n ({ src, onLoad, onScaling, onError, scaleToFit, scaleToCover, ...options }, ref) => {\n const backgroundImageRef = useRef<FabricImage | null>(null)\n\n const store = useStoreApi()\n const newestSrcRef = useRef(src)\n\n const { width, height } = useStore(selector)\n\n const updateViewport = useCallback(\n (params: { scaleToFit?: boolean; scaleToCover?: boolean }) => {\n const { canvas, manualZoom = 1, defaultCentered } = store.getState()\n if (!backgroundImageRef.current) {\n return\n }\n if (!canvas) {\n console.warn('updateViewport: !canvas')\n return\n }\n if (!canvas.backgroundImage) {\n console.warn('updateViewport: !canvas.backgroundImage')\n return\n }\n\n // 1. 计算缩放\n const fitZoom = params.scaleToFit\n ? util.findScaleToFit(backgroundImageRef.current, canvas)\n : params.scaleToCover\n ? util.findScaleToCover(backgroundImageRef.current, canvas)\n : 1\n\n const combinedZoom = fitZoom * manualZoom\n\n // 2. 先应用基础缩放\n canvas.setViewportTransform([combinedZoom, 0, 0, combinedZoom, 0, 0])\n\n // 3. 如果需要居中,计算偏移量\n let deltaX = 0\n let deltaY = 0\n\n if (defaultCentered && canvas.backgroundImage) {\n const bgWidth = canvas.backgroundImage.width || 0\n const bgHeight = canvas.backgroundImage.height || 0\n deltaX = (canvas.width! - bgWidth * combinedZoom) / 2\n deltaY = (canvas.height! - bgHeight * combinedZoom) / 2\n // const canvasCenter = {\n // x: canvas.width! / 2,\n // y: canvas.height! / 2,\n // }\n // const bgCenter = {\n // x:\n // (canvas.backgroundImage.left! + (canvas.backgroundImage.width! * canvas.backgroundImage.scaleX!) / 2) *\n // combinedZoom,\n // y:\n // (canvas.backgroundImage.top! + (canvas.backgroundImage.height! * canvas.backgroundImage.scaleY!) / 2) *\n // combinedZoom,\n // }\n // deltaX = canvasCenter.x - bgCenter.x\n // deltaY = canvasCenter.y - bgCenter.y\n }\n\n // 4. 应用最终变换\n const finalTransform: [number, number, number, number, number, number] = [\n combinedZoom,\n 0,\n 0,\n combinedZoom,\n deltaX,\n deltaY,\n ]\n\n canvas.setViewportTransform(finalTransform)\n canvas.requestRenderAll()\n\n // 5. 更新 store\n store.setState({\n fitZoom,\n manualZoom,\n zoom: combinedZoom,\n })\n },\n [store],\n )\n\n // 监听 width, height 的变化\n useEffect(() => {\n updateViewport({\n scaleToFit,\n scaleToCover,\n })\n }, [width, height, scaleToFit, scaleToCover, updateViewport, store])\n\n useEffect(() => {\n if (!src) {\n console.warn('ReactFabricBackgroundImage: !src')\n return\n }\n const { domNode, setLoading } = store.getState()\n setLoading(true)\n newestSrcRef.current = src\n\n FabricImage.fromURL(src, { crossOrigin: 'anonymous' })\n .then(imageSource => {\n onLoad?.(imageSource)\n const currentSrc = imageSource.getSrc()\n\n if (currentSrc !== newestSrcRef.current) {\n return\n }\n\n const { canvas } = store.getState()\n if (canvas) {\n // 初始化时角度的旋转,一定要放到 updateViewport 之后;先画正图片,再进行旋转\n const removeAngleOptions = { ...options, angle: 0 }\n imageSource.set({\n ...removeAngleOptions,\n objectCaching: false,\n })\n canvas.getContext().imageSmoothingEnabled = true\n canvas.getContext().imageSmoothingQuality = 'high'\n canvas.backgroundImage = imageSource\n backgroundImageRef.current = imageSource\n\n requestAnimationFrame(() => {\n updateViewport({\n scaleToFit,\n scaleToCover,\n })\n })\n\n const viewport = canvas.viewportTransform\n if (!viewport) {\n console.warn('!viewport')\n return\n }\n\n // imageSource.angle = options.angle || 0\n } else {\n console.warn('ReactFabric:BackgroundImage: !canvas', canvas)\n }\n })\n .catch(e => {\n onError?.(e)\n console.error('[ReactFabric] BackgroundImage: fromURL error', e)\n })\n .finally(() => {\n if (domNode) domNode.dataset.src = src\n setLoading(false)\n })\n\n return () => {\n const { canvas } = store.getState()\n if (canvas?.backgroundImage) {\n canvas.backgroundImage = undefined\n canvas.remove(backgroundImageRef.current!)\n backgroundImageRef.current = null\n canvas.renderAll()\n }\n }\n }, [src])\n\n useDidUpdate(() => {\n const { canvas } = store.getState()\n\n if (backgroundImageRef.current) {\n Object.entries(options).forEach(([key, value]) => {\n if (key === 'angle') {\n backgroundImageRef.current?.rotate(value as TDegree)\n } else {\n backgroundImageRef.current?.set(key, value)\n }\n })\n canvas?.requestRenderAll()\n }\n }, [options, store])\n\n useImperativeHandle(ref, () => ({\n // 是最新的?\n instance: backgroundImageRef.current,\n }))\n\n return null\n },\n)\n\nexport default memo(BackgroundImage)\n"],"names":["selector","s","BackgroundImage","forwardRef","src","onLoad","onScaling","onError","scaleToFit","scaleToCover","options","ref","backgroundImageRef","useRef","store","useStoreApi","newestSrcRef","width","height","useStore","updateViewport","useCallback","params","canvas","manualZoom","defaultCentered","fitZoom","util","combinedZoom","deltaX","deltaY","bgWidth","bgHeight","finalTransform","useEffect","domNode","setLoading","FabricImage","imageSource","removeAngleOptions","useDidUpdate","key","value","useImperativeHandle","memo"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var c=require("react/jsx-runtime"),i=require("fabric"),a=require("react"),j=require("../../hooks/useDraggable.cjs"),x=require("../../hooks/useResizeHandler.cjs"),y=require("../../hooks/useSplitProps.cjs"),b=require("../../hooks/useStore.cjs"),z=require("../../utils/events.cjs");const E={position:"absolute",width:"100%",height:"100%",top:0,left:0},M=({children:w,onMouseWheel:l,...S})=>{const e=a.useRef(),o=b.useStoreApi(),f=a.useRef(null);j.default();const d=a.useRef(null),q=b.useStore(r=>r.controls),[P,n]=y.useSplitProps(S);return a.useLayoutEffect(()=>{const r=f.current;e.current=new i.Canvas(r||void 0,{...n});const t=z.bindEvents(e.current,P);return o.setState({canvas:e.current}),window.canvas=e.current,()=>{t(),e.current?.dispose(),r?.remove(),e.current=void 0,o.setState({canvas:null})}},[]),x.default(),a.useEffect(()=>{const r=t=>{const{zoomable:R,panAble:_,maxManualZoom:v,minManualZoom:m,fitZoom:p=1,zoom:g}=o.getState();if(t.e.preventDefault(),t.e.stopPropagation(),t.e.wheelDeltaY!==0){if(t.e.ctrlKey||t.e.wheelDeltaY===void 0){if(!R)return;const u=t.e.deltaY>0?.95:1.05;let s=g/p*u;s>v&&(s=v),s<m&&(s=m);const h=s*p;e.current?.zoomToPoint(new i.Point(t.e.offsetX,t.e.offsetY),h),o.setState({manualZoom:s,zoom:h})}else{if(!_)return;const u=1.5,s=new i.Point(-t.e.deltaX*u,-t.e.deltaY*u);e.current?.relativePan(s)}l?.(t)}};return e.current?.on("mouse:wheel",r),()=>{e.current?.off("mouse:wheel",r)}},[l,o]),a.useEffect(()=>{o.setState({domNode:d.current?.closest(".react-fabric")})},[o]),a.useEffect(()=>{e.current&&(e.current.set(n),e.current.requestRenderAll())},[n]),c.jsxs("div",{className:"react-fabric__canvas",ref:d,style:E,children:[c.jsx("canvas",{ref:f}),w,q.map(r=>c.jsx("div",{id:r.id,style:{position:"absolute"},className:`react-fabric__control ${r.className}`,ref:r.ref,children:r.children},r.id))]})};exports.default=M;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var c=require("react/jsx-runtime"),i=require("fabric"),n=require("react"),j=require("../../hooks/useDraggable.cjs"),x=require("../../hooks/useResizeHandler.cjs"),y=require("../../hooks/useSplitProps.cjs"),b=require("../../hooks/useStore.cjs"),z=require("../../utils/events.cjs");const E={position:"absolute",width:"100%",height:"100%",top:0,left:0},M=({children:w,onMouseWheel:l,...S})=>{const e=n.useRef(),a=b.useStoreApi(),f=n.useRef(null);j.default();const d=n.useRef(null),q=b.useStore(t=>t.controls),[P,u]=y.useSplitProps(S);return n.useLayoutEffect(()=>{const t=f.current;e.current=new i.Canvas(t||void 0,{...u});const r=z.bindEvents(e.current,P);return a.setState({canvas:e.current}),window.canvas=e.current,()=>{r(),e.current?.dispose(),e.current=void 0,a.setState({canvas:null})}},[]),x.default(),n.useEffect(()=>{const t=r=>{const{zoomable:R,panAble:_,maxManualZoom:v,minManualZoom:m,fitZoom:p=1,zoom:g}=a.getState();if(r.e.preventDefault(),r.e.stopPropagation(),r.e.wheelDeltaY!==0){if(r.e.ctrlKey||r.e.wheelDeltaY===void 0){if(!R)return;const o=r.e.deltaY>0?.95:1.05;let s=g/p*o;s>v&&(s=v),s<m&&(s=m);const h=s*p;e.current?.zoomToPoint(new i.Point(r.e.offsetX,r.e.offsetY),h),a.setState({manualZoom:s,zoom:h})}else{if(!_)return;const o=1.5,s=new i.Point(-r.e.deltaX*o,-r.e.deltaY*o);e.current?.relativePan(s)}l?.(r)}};return e.current?.on("mouse:wheel",t),()=>{e.current?.off("mouse:wheel",t)}},[l,a]),n.useEffect(()=>{a.setState({domNode:d.current?.closest(".react-fabric")})},[a]),n.useEffect(()=>{e.current&&(e.current.set(u),e.current.requestRenderAll())},[u]),c.jsxs("div",{className:"react-fabric__canvas",ref:d,style:E,children:[c.jsx("canvas",{ref:f}),w,q.map(t=>c.jsx("div",{id:t.id,style:{position:"absolute"},className:`react-fabric__control ${t.className}`,ref:t.ref,children:t.children},t.id))]})};exports.default=M;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../../../src/components/Canvas/index.tsx"],"sourcesContent":["import type { CanvasEvents, CanvasOptions, TPointerEventInfo } from 'fabric'\nimport { Canvas as BaseCanvas, Point } from 'fabric'\nimport type { CSSProperties, PropsWithChildren } from 'react'\nimport { useEffect, useLayoutEffect, useRef } from 'react'\nimport useDraggable from '../../hooks/useDraggable'\nimport useResizeHandler from '../../hooks/useResizeHandler'\nimport { useSplitProps } from '../../hooks/useSplitProps'\nimport { useStore, useStoreApi } from '../../hooks/useStore'\nimport type { AllCanvasEvents } from '../../types/canvas'\nimport { bindEvents } from '../../utils/events'\n\nconst style: CSSProperties = {\n position: 'absolute',\n width: '100%',\n height: '100%',\n top: 0,\n left: 0,\n}\n\n// 首先定义事件类型\ntype CanvasEventProps = {\n [K in keyof AllCanvasEvents]: AllCanvasEvents[K]\n}\n\n// 分离配置属性类型\ntype CanvasConfigProps = Omit<CanvasOptions, keyof CanvasEventProps>\n\n// 重新定义 CanvasProps\nexport type CanvasProps = PropsWithChildren<Partial<CanvasConfigProps> & Partial<CanvasEventProps>>\n\nconst Canvas = ({ children, onMouseWheel, ...props }: CanvasProps) => {\n const canvasRef = useRef<BaseCanvas>()\n const store = useStoreApi()\n const canvasDomRef = useRef<HTMLCanvasElement | null>(null)\n useDraggable()\n const domRef = useRef<HTMLDivElement>(null)\n const controls = useStore(state => state.controls)\n\n const [listeners, attributes] = useSplitProps(props)\n\n useLayoutEffect(() => {\n const canvas = canvasDomRef.current\n\n canvasRef.current = new BaseCanvas(canvas || undefined, {\n ...attributes,\n })\n\n // 绑定事件并获取清理函数\n const unbindEvents = bindEvents<CanvasEvents>(canvasRef.current, listeners)\n\n store.setState({\n canvas: canvasRef.current,\n })\n //@ts-expect-error 报错撒撒\n window.canvas = canvasRef.current\n\n return () => {\n unbindEvents() // 调用清理函数\n canvasRef.current?.dispose()\n canvas?.remove()\n canvasRef.current = undefined // 清除引用\n store.setState({\n canvas: null,\n })\n }\n }, [])\n\n useResizeHandler()\n\n useEffect(() => {\n const onMouseWheelHandler = (opt: TPointerEventInfo<WheelEvent>) => {\n const { zoomable, panAble, maxManualZoom, minManualZoom, fitZoom = 1, zoom } = store.getState()\n\n // 阻止默认行为\n opt.e.preventDefault()\n opt.e.stopPropagation()\n\n // 如果是惯性滚动,直接返回\n if ((opt.e as any).wheelDeltaY === 0) return\n\n // 检查是否为缩放手势(Mac 上的双指捏合/张开)\n if (opt.e.ctrlKey || (opt.e as any).wheelDeltaY === undefined) {\n // 缩放逻辑\n if (!zoomable) return\n\n const delta = opt.e.deltaY\n const zoomFactor = delta > 0 ? 0.95 : 1.05\n const currentManualZoom = zoom / fitZoom\n let newManualZoom = currentManualZoom * zoomFactor\n\n if (newManualZoom > maxManualZoom) newManualZoom = maxManualZoom\n if (newManualZoom < minManualZoom) newManualZoom = minManualZoom\n\n const combinedZoom = newManualZoom * fitZoom\n\n canvasRef.current?.zoomToPoint(new Point(opt.e.offsetX, opt.e.offsetY), combinedZoom)\n\n store.setState({\n manualZoom: newManualZoom,\n zoom: combinedZoom,\n })\n } else {\n if (!panAble) return\n // 平移逻辑\n // 如果觉得太灵敏了,可以调小这个值,比如改为 1.2 或更小\n const sensitivityFactor = 1.5\n const delta = new Point(-opt.e.deltaX * sensitivityFactor, -opt.e.deltaY * sensitivityFactor)\n canvasRef.current?.relativePan(delta)\n }\n\n onMouseWheel?.(opt)\n }\n\n canvasRef.current?.on('mouse:wheel', onMouseWheelHandler)\n\n return () => {\n canvasRef.current?.off('mouse:wheel', onMouseWheelHandler)\n }\n }, [onMouseWheel, store])\n\n useEffect(() => {\n store.setState({\n domNode: domRef.current?.closest('.react-fabric') as HTMLDivElement,\n })\n }, [store])\n\n useEffect(() => {\n if (canvasRef.current) {\n canvasRef.current.set(attributes)\n canvasRef.current.requestRenderAll()\n }\n }, [attributes])\n\n return (\n <div className=\"react-fabric__canvas\" ref={domRef} style={style}>\n <canvas ref={canvasDomRef}></canvas>\n {children}\n {controls.map(control => (\n <div\n key={control.id}\n id={control.id}\n style={{\n position: 'absolute',\n }}\n className={`react-fabric__control ${control.className}`}\n ref={control.ref}\n >\n {control.children}\n </div>\n ))}\n </div>\n )\n}\n\nexport default Canvas\n"],"names":["style","Canvas","children","onMouseWheel","props","canvasRef","useRef","store","useStoreApi","canvasDomRef","useDraggable","domRef","controls","useStore","state","listeners","attributes","useSplitProps","useLayoutEffect","canvas","BaseCanvas","unbindEvents","bindEvents","useResizeHandler","useEffect","onMouseWheelHandler","opt","zoomable","panAble","maxManualZoom","minManualZoom","fitZoom","zoom","zoomFactor","newManualZoom","combinedZoom","Point","sensitivityFactor","delta","jsxs","jsx","control"],"mappings":"2VAWMA,MAAAA,EAAuB,CAC3B,SAAU,WACV,MAAO,OACP,OAAQ,OACR,IAAK,EACL,KAAM,CACR,EAaMC,EAAS,CAAC,CAAE,SAAAC,EAAU,aAAAC,EAAc,GAAGC,CAAM,IAAmB,CACpE,MAAMC,EAAYC,EAAAA,OACZC,EAAAA,EAAQC,EAAAA,YAAY,EACpBC,EAAeH,EAAAA,OAAiC,IAAI,EAC1DI,EAAAA,UACA,MAAMC,EAASL,SAAuB,IAAI,EACpCM,EAAWC,WAASC,GAASA,EAAM,QAAQ,EAE3C,CAACC,EAAWC,CAAU,EAAIC,gBAAcb,CAAK,EAEnD,OAAAc,EAAAA,gBAAgB,IAAM,CACpB,MAAMC,EAASV,EAAa,QAE5BJ,EAAU,QAAU,IAAIe,EAAAA,OAAWD,GAAU,OAAW,CACtD,GAAGH,CACL,CAAC,EAGD,MAAMK,EAAeC,EAAAA,WAAyBjB,EAAU,QAASU,CAAS,EAE1E,OAAAR,EAAM,SAAS,CACb,OAAQF,EAAU,OACpB,CAAC,EAED,OAAO,OAASA,EAAU,QAEnB,IAAM,CACXgB,EACAhB,EAAAA,EAAU,SAAS,QAAQ,EAC3Bc,GAAQ,OAAO,EACfd,EAAU,QAAU,OACpBE,EAAM,SAAS,CACb,OAAQ,IACV,CAAC,CACH,CACF,EAAG,CAAA,CAAE,EAELgB,YAEAC,EAAU,UAAA,IAAM,CACd,MAAMC,EAAuBC,GAAuC,CAClE,KAAM,CAAE,SAAAC,EAAU,QAAAC,EAAS,cAAAC,EAAe,cAAAC,EAAe,QAAAC,EAAU,EAAG,KAAAC,CAAK,EAAIzB,EAAM,WAOrF,GAJAmB,EAAI,EAAE,eAAe,EACrBA,EAAI,EAAE,gBAAA,EAGDA,EAAI,EAAU,cAAgB,EAGnC,CAAIA,GAAAA,EAAI,EAAE,SAAYA,EAAI,EAAU,cAAgB,OAAW,CAE7D,GAAI,CAACC,EAAU,OAGf,MAAMM,EADQP,EAAI,EAAE,OACO,EAAI,IAAO,KAEtC,IAAIQ,EADsBF,EAAOD,EACOE,EAEpCC,EAAgBL,IAAeK,EAAgBL,GAC/CK,EAAgBJ,IAAeI,EAAgBJ,GAEnD,MAAMK,EAAeD,EAAgBH,EAErC1B,EAAU,SAAS,YAAY,IAAI+B,EAAAA,MAAMV,EAAI,EAAE,QAASA,EAAI,EAAE,OAAO,EAAGS,CAAY,EAEpF5B,EAAM,SAAS,CACb,WAAY2B,EACZ,KAAMC,CACR,CAAC,CACH,KAAO,CACL,GAAI,CAACP,EAAS,OAGd,MAAMS,EAAoB,IACpBC,EAAQ,IAAIF,EAAAA,MAAM,CAACV,EAAI,EAAE,OAASW,EAAmB,CAACX,EAAI,EAAE,OAASW,CAAiB,EAC5FhC,EAAU,SAAS,YAAYiC,CAAK,CACtC,CAEAnC,IAAeuB,CAAG,CAAA,CACpB,EAEA,OAAArB,EAAU,SAAS,GAAG,cAAeoB,CAAmB,EAEjD,IAAM,CACXpB,EAAU,SAAS,IAAI,cAAeoB,CAAmB,CAC3D,CACF,EAAG,CAACtB,EAAcI,CAAK,CAAC,EAExBiB,EAAU,UAAA,IAAM,CACdjB,EAAM,SAAS,CACb,QAASI,EAAO,SAAS,QAAQ,eAAe,CAClD,CAAC,CACH,EAAG,CAACJ,CAAK,CAAC,EAEViB,EAAAA,UAAU,IAAM,CACVnB,EAAU,UACZA,EAAU,QAAQ,IAAIW,CAAU,EAChCX,EAAU,QAAQ,mBAEtB,EAAG,CAACW,CAAU,CAAC,EAGbuB,EAAAA,KAAC,MAAA,CAAI,UAAU,uBAAuB,IAAK5B,EAAQ,MAAOX,EACxD,UAAAwC,MAAC,SAAA,CAAO,IAAK/B,CAAc,CAAA,EAC1BP,EACAU,EAAS,IAAI6B,GACZD,MAAC,MAEC,CAAA,GAAIC,EAAQ,GACZ,MAAO,CACL,SAAU,UACZ,EACA,UAAW,yBAAyBA,EAAQ,SAAS,GACrD,IAAKA,EAAQ,IAEZ,SAAAA,EAAQ,QARJA,EAAAA,EAAQ,EASf,CACD,CAAA,CAAA,CACH,CAEJ"}
1
+ {"version":3,"file":"index.cjs","sources":["../../../../src/components/Canvas/index.tsx"],"sourcesContent":["import type { CanvasEvents, CanvasOptions, TPointerEventInfo } from 'fabric'\nimport { Canvas as BaseCanvas, Point } from 'fabric'\nimport type { CSSProperties, PropsWithChildren } from 'react'\nimport { useEffect, useLayoutEffect, useRef } from 'react'\nimport useDraggable from '../../hooks/useDraggable'\nimport useResizeHandler from '../../hooks/useResizeHandler'\nimport { useSplitProps } from '../../hooks/useSplitProps'\nimport { useStore, useStoreApi } from '../../hooks/useStore'\nimport type { AllCanvasEvents } from '../../types/canvas'\nimport { bindEvents } from '../../utils/events'\n\nconst style: CSSProperties = {\n position: 'absolute',\n width: '100%',\n height: '100%',\n top: 0,\n left: 0,\n}\n\n// 首先定义事件类型\ntype CanvasEventProps = {\n [K in keyof AllCanvasEvents]: AllCanvasEvents[K]\n}\n\n// 分离配置属性类型\ntype CanvasConfigProps = Omit<CanvasOptions, keyof CanvasEventProps>\n\n// 重新定义 CanvasProps\nexport type CanvasProps = PropsWithChildren<Partial<CanvasConfigProps> & Partial<CanvasEventProps>>\n\nconst Canvas = ({ children, onMouseWheel, ...props }: CanvasProps) => {\n const canvasRef = useRef<BaseCanvas>()\n const store = useStoreApi()\n const canvasDomRef = useRef<HTMLCanvasElement | null>(null)\n useDraggable()\n const domRef = useRef<HTMLDivElement>(null)\n const controls = useStore(state => state.controls)\n\n const [listeners, attributes] = useSplitProps(props)\n\n useLayoutEffect(() => {\n const canvas = canvasDomRef.current\n\n canvasRef.current = new BaseCanvas(canvas || undefined, {\n ...attributes,\n })\n\n // 绑定事件并获取清理函数\n const unbindEvents = bindEvents<CanvasEvents>(canvasRef.current, listeners)\n\n store.setState({\n canvas: canvasRef.current,\n })\n //@ts-expect-error 报错撒撒\n window.canvas = canvasRef.current\n\n return () => {\n unbindEvents() // 调用清理函数\n canvasRef.current?.dispose()\n canvasRef.current = undefined // 清除引用\n store.setState({\n canvas: null,\n })\n }\n }, [])\n\n useResizeHandler()\n\n useEffect(() => {\n const onMouseWheelHandler = (opt: TPointerEventInfo<WheelEvent>) => {\n const { zoomable, panAble, maxManualZoom, minManualZoom, fitZoom = 1, zoom } = store.getState()\n\n // 阻止默认行为\n opt.e.preventDefault()\n opt.e.stopPropagation()\n\n // 如果是惯性滚动,直接返回\n if ((opt.e as any).wheelDeltaY === 0) return\n\n // 检查是否为缩放手势(Mac 上的双指捏合/张开)\n if (opt.e.ctrlKey || (opt.e as any).wheelDeltaY === undefined) {\n // 缩放逻辑\n if (!zoomable) return\n\n const delta = opt.e.deltaY\n const zoomFactor = delta > 0 ? 0.95 : 1.05\n const currentManualZoom = zoom / fitZoom\n let newManualZoom = currentManualZoom * zoomFactor\n\n if (newManualZoom > maxManualZoom) newManualZoom = maxManualZoom\n if (newManualZoom < minManualZoom) newManualZoom = minManualZoom\n\n const combinedZoom = newManualZoom * fitZoom\n\n canvasRef.current?.zoomToPoint(new Point(opt.e.offsetX, opt.e.offsetY), combinedZoom)\n\n store.setState({\n manualZoom: newManualZoom,\n zoom: combinedZoom,\n })\n } else {\n if (!panAble) return\n // 平移逻辑\n // 如果觉得太灵敏了,可以调小这个值,比如改为 1.2 或更小\n const sensitivityFactor = 1.5\n const delta = new Point(-opt.e.deltaX * sensitivityFactor, -opt.e.deltaY * sensitivityFactor)\n canvasRef.current?.relativePan(delta)\n }\n\n onMouseWheel?.(opt)\n }\n\n canvasRef.current?.on('mouse:wheel', onMouseWheelHandler)\n\n return () => {\n canvasRef.current?.off('mouse:wheel', onMouseWheelHandler)\n }\n }, [onMouseWheel, store])\n\n useEffect(() => {\n store.setState({\n domNode: domRef.current?.closest('.react-fabric') as HTMLDivElement,\n })\n }, [store])\n\n useEffect(() => {\n if (canvasRef.current) {\n canvasRef.current.set(attributes)\n canvasRef.current.requestRenderAll()\n }\n }, [attributes])\n\n return (\n <div className=\"react-fabric__canvas\" ref={domRef} style={style}>\n <canvas ref={canvasDomRef}></canvas>\n {children}\n {controls.map(control => (\n <div\n key={control.id}\n id={control.id}\n style={{\n position: 'absolute',\n }}\n className={`react-fabric__control ${control.className}`}\n ref={control.ref}\n >\n {control.children}\n </div>\n ))}\n </div>\n )\n}\n\nexport default Canvas\n"],"names":["style","Canvas","children","onMouseWheel","props","canvasRef","useRef","store","useStoreApi","canvasDomRef","useDraggable","domRef","controls","useStore","state","listeners","attributes","useSplitProps","useLayoutEffect","canvas","BaseCanvas","unbindEvents","bindEvents","useResizeHandler","useEffect","onMouseWheelHandler","opt","zoomable","panAble","maxManualZoom","minManualZoom","fitZoom","zoom","zoomFactor","newManualZoom","combinedZoom","Point","sensitivityFactor","delta","jsxs","jsx","control"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../../../src/components/IText/index.tsx"],"sourcesContent":["import type { Group as BaseGroup } from 'fabric'\nimport { IText, util, Point } from 'fabric'\nimport { forwardRef, memo, useImperativeHandle, type ReactNode } from 'react'\nimport { useCreateObject } from '../../hooks/useCreateObject'\nimport { useSplitProps } from '../../hooks/useSplitProps'\nimport type { AllObjectEvents } from '../../types/object'\nimport { useInstancePosition } from '../../hooks/useInstancePosition'\n\nexport type ITextProps<T = unknown> = Partial<ConstructorParameters<typeof IText>[1] & AllObjectEvents> & {\n group?: BaseGroup\n text: string\n children?: ReactNode\n} & T\n\nIText.prototype.set({\n _getNonTransformedDimensions() {\n // Object dimensions\n return new Point(this.width, this.height).scalarAdd(this.padding)\n },\n _calculateCurrentDimensions() {\n // Controls dimensions\n return util.transformPoint(this._getTransformedDimensions(), this.getViewportTransform(), true)\n },\n})\n\nconst ITextBox = forwardRef<IText | undefined, ITextProps>(({ group, text, children, ...props }, ref) => {\n const [listeners, attributes] = useSplitProps(props)\n\n const instance = useCreateObject({\n Constructor: IText,\n param: text,\n attributes,\n group,\n listeners,\n })\n\n useImperativeHandle(ref, () => instance, [instance])\n\n return useInstancePosition(instance, children)\n})\n\nexport default memo(ITextBox)\n"],"names":["IText","Point","util","ITextBox","forwardRef","group","text","children","props","ref","listeners","attributes","useSplitProps","instance","useCreateObject","useImperativeHandle","useInstancePosition","x","memo"],"mappings":"wPAcAA,EAAAA,MAAM,UAAU,IAAI,CAClB,8BAA+B,CAE7B,OAAO,IAAIC,EAAM,MAAA,KAAK,MAAO,KAAK,MAAM,EAAE,UAAU,KAAK,OAAO,CAClE,EACA,6BAA8B,CAE5B,OAAOC,EAAAA,KAAK,eAAe,KAAK,4BAA6B,KAAK,uBAAwB,EAAI,CAChG,CACF,CAAC,EAED,MAAMC,EAAWC,EAA0C,WAAA,CAAC,CAAE,MAAAC,EAAO,KAAAC,EAAM,SAAAC,EAAU,GAAGC,CAAM,EAAGC,IAAQ,CACvG,KAAM,CAACC,EAAWC,CAAU,EAAIC,gBAAcJ,CAAK,EAE7CK,EAAWC,EAAgB,gBAAA,CAC/B,YAAad,EACb,MAAA,MAAOM,EACP,WAAAK,EACA,MAAAN,EACA,UAAAK,CACF,CAAC,EAED,OAAAK,sBAAoBN,EAAK,IAAMI,EAAU,CAACA,CAAQ,CAAC,EAE5CG,EAAoBH,oBAAAA,EAAUN,CAAQ,CAC/C,CAAC,EAED,IAAAU,EAAeC,EAAAA,KAAKf,CAAQ"}
1
+ {"version":3,"file":"index.cjs","sources":["../../../../src/components/IText/index.tsx"],"sourcesContent":["import type { Group as BaseGroup } from 'fabric'\nimport { IText, util, Point } from 'fabric'\nimport { forwardRef, memo, useImperativeHandle, type ReactNode } from 'react'\nimport { useCreateObject } from '../../hooks/useCreateObject'\nimport { useSplitProps } from '../../hooks/useSplitProps'\nimport type { AllObjectEvents } from '../../types/object'\nimport { useInstancePosition } from '../../hooks/useInstancePosition'\n\nexport type ITextProps<T = unknown> = Partial<ConstructorParameters<typeof IText>[1] & AllObjectEvents> & {\n group?: BaseGroup\n text: string\n children?: ReactNode\n} & T\n\nIText.prototype.set({\n _getNonTransformedDimensions() {\n // Object dimensions\n return new Point(this.width, this.height).scalarAdd(this.padding)\n },\n _calculateCurrentDimensions() {\n // Controls dimensions\n return util.transformPoint(this._getTransformedDimensions(), this.getViewportTransform(), true)\n },\n})\n\nconst ITextBox = forwardRef<IText | undefined, ITextProps>(({ group, text, children, ...props }, ref) => {\n const [listeners, attributes] = useSplitProps(props)\n\n const instance = useCreateObject({\n Constructor: IText,\n param: text,\n attributes,\n group,\n listeners,\n })\n\n useImperativeHandle(ref, () => instance, [instance])\n\n return useInstancePosition(instance, children)\n})\n\nexport default memo(ITextBox)\n"],"names":["IText","Point","util","ITextBox","forwardRef","group","text","children","props","ref","listeners","attributes","useSplitProps","instance","useCreateObject","useImperativeHandle","useInstancePosition","a","memo"],"mappings":"wPAcAA,EAAAA,MAAM,UAAU,IAAI,CAClB,8BAA+B,CAE7B,OAAO,IAAIC,EAAM,MAAA,KAAK,MAAO,KAAK,MAAM,EAAE,UAAU,KAAK,OAAO,CAClE,EACA,6BAA8B,CAE5B,OAAOC,EAAAA,KAAK,eAAe,KAAK,4BAA6B,KAAK,uBAAwB,EAAI,CAChG,CACF,CAAC,EAED,MAAMC,EAAWC,EAA0C,WAAA,CAAC,CAAE,MAAAC,EAAO,KAAAC,EAAM,SAAAC,EAAU,GAAGC,CAAM,EAAGC,IAAQ,CACvG,KAAM,CAACC,EAAWC,CAAU,EAAIC,gBAAcJ,CAAK,EAE7CK,EAAWC,EAAgB,gBAAA,CAC/B,YAAad,EACb,MAAA,MAAOM,EACP,WAAAK,EACA,MAAAN,EACA,UAAAK,CACF,CAAC,EAED,OAAAK,sBAAoBN,EAAK,IAAMI,EAAU,CAACA,CAAQ,CAAC,EAE5CG,EAAoBH,oBAAAA,EAAUN,CAAQ,CAC/C,CAAC,EAED,IAAAU,EAAeC,EAAAA,KAAKf,CAAQ"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../../../src/components/Objects/index.tsx"],"sourcesContent":["import { memo } from 'react'\nimport Path from '../Path'\nimport Text from '../Text'\nimport Rect from '../Rect'\nimport Line from '../Line'\nimport IText from '../IText'\n\nexport type ObjectsProps = {\n objects: { type: string;[index: string]: any }[]\n}\n\nconst Objects = ({ objects }: ObjectsProps) => {\n const components = {\n rect: Rect,\n path: Path,\n text: Text,\n line: Line,\n 'i-text': Text,\n itext: IText,\n }\n\n if (!objects) return null\n return (\n <>\n {objects?.map(({ type, ...options }) => {\n const Component = components[type.toLowerCase() as keyof typeof components]\n if (!Component) {\n return null\n }\n return <Component {...options} />\n })}\n </>\n )\n}\n\nexport default memo(Objects)\n"],"names":["Objects","objects","components","Rect","Path","Text","Line","IText","jsx","Fragment","type","options","Component","memo"],"mappings":"sRAWA,MAAMA,EAAU,CAAC,CAAE,QAAAC,CAAQ,IAAoB,CAC7C,MAAMC,EAAa,CACjB,KAAMC,EAAAA,QACN,KAAMC,UACN,KAAMC,UACN,KAAMC,EACN,QAAA,SAAUD,EAAAA,QACV,MAAOE,EAAAA,OACT,EAEA,OAAKN,EAEHO,EAAAA,IAAAC,EAAAA,SAAA,CACG,SAAAR,GAAS,IAAI,CAAC,CAAE,KAAAS,EAAM,GAAGC,CAAQ,IAAM,CACtC,MAAMC,EAAYV,EAAWQ,EAAK,YAAwC,CAAA,EAC1E,OAAKE,EAGEJ,EAAAA,IAACI,EAAA,CAAW,GAAGD,EAAS,EAFtB,IAGX,CAAC,CACH,CAAA,EAVmB,IAYvB,EAEA,IAAeE,EAAAA,EAAAA,KAAKb,CAAO"}
1
+ {"version":3,"file":"index.cjs","sources":["../../../../src/components/Objects/index.tsx"],"sourcesContent":["import { memo } from 'react'\nimport Path from '../Path'\nimport Text from '../Text'\nimport Rect from '../Rect'\nimport Line from '../Line'\nimport IText from '../IText'\n\nexport type ObjectsProps = {\n objects: { type: string; [index: string]: any }[]\n}\n\nconst Objects = ({ objects }: ObjectsProps) => {\n const components = {\n rect: Rect,\n path: Path,\n text: Text,\n line: Line,\n 'i-text': Text,\n itext: IText,\n }\n\n if (!objects) return null\n return (\n <>\n {objects?.map(({ type, ...options }) => {\n const Component = components[type.toLowerCase() as keyof typeof components]\n if (!Component) {\n return null\n }\n return <Component {...(options as any)} />\n })}\n </>\n )\n}\n\nexport default memo(Objects)\n"],"names":["Objects","objects","components","Rect","Path","Text","Line","IText","jsx","Fragment","type","options","Component","memo"],"mappings":"sRAWA,MAAMA,EAAU,CAAC,CAAE,QAAAC,CAAQ,IAAoB,CAC7C,MAAMC,EAAa,CACjB,KAAMC,EAAAA,QACN,KAAMC,UACN,KAAMC,UACN,KAAMC,EACN,QAAA,SAAUD,EAAAA,QACV,MAAOE,EAAAA,OACT,EAEA,OAAKN,EAEHO,EAAAA,IAAAC,EAAAA,SAAA,CACG,SAAAR,GAAS,IAAI,CAAC,CAAE,KAAAS,EAAM,GAAGC,CAAQ,IAAM,CACtC,MAAMC,EAAYV,EAAWQ,EAAK,YAAwC,CAAA,EAC1E,OAAKE,EAGEJ,EAAAA,IAACI,EAAA,CAAW,GAAID,EAAiB,EAF/B,IAGX,CAAC,CACH,CAAA,EAVmB,IAYvB,EAEA,IAAeE,EAAAA,EAAAA,KAAKb,CAAO"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=require("fabric"),i=require("react"),d=require("../../hooks/useCreateObject.cjs"),p=require("../../hooks/useSplitProps.cjs"),h=require("../../hooks/useStore.cjs"),v=require("fontfaceobserver"),F=require("../../hooks/useInstancePosition.cjs");t.FabricText.prototype.set({_getNonTransformedDimensions(){return new t.Point(this.width,this.height).scalarAdd(this.padding)},_calculateCurrentDimensions(){return t.util.transformPoint(this._getTransformedDimensions(),this.getViewportTransform(),!0)}});const g=i.forwardRef(({group:s,text:a,children:n,...o},u)=>{const c=h.useStoreApi(),[l,e]=p.useSplitProps(o),r=d.useCreateObject({Constructor:t.FabricText,param:a,attributes:e,group:s,listeners:l});return i.useEffect(()=>{const{canvas:f}=c.getState();!e.fontFamily||!r||new v(e.fontFamily).load().then(()=>{r.set({fontFamily:e.fontFamily}),f?.requestRenderAll()}).catch(m=>{console.error(`ReactFabric: \u5B57\u4F53\u52A0\u8F7D\u5931\u8D25: ${e.fontFamily}`,m)})},[e.fontFamily,r]),i.useImperativeHandle(u,()=>r,[r]),F.useInstancePosition(r,n)});var b=i.memo(g);exports.default=b;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=require("fabric"),i=require("react"),p=require("../../hooks/useCreateObject.cjs"),h=require("../../hooks/useSplitProps.cjs"),v=require("../../hooks/useStore.cjs"),F=require("fontfaceobserver"),y=require("../../hooks/useInstancePosition.cjs");t.FabricText.prototype.set({_getNonTransformedDimensions(){return new t.Point(this.width,this.height).scalarAdd(this.padding)},_calculateCurrentDimensions(){return t.util.transformPoint(this._getTransformedDimensions(),this.getViewportTransform(),!0)}});const s=i.forwardRef(({group:a,text:n,children:o,...u},c)=>{const l=v.useStoreApi(),[f,e]=h.useSplitProps(u),r=p.useCreateObject({Constructor:t.FabricText,param:n,attributes:e,group:a,listeners:f});return i.useEffect(()=>{const{canvas:m}=l.getState();!e.fontFamily||!r||new F(e.fontFamily).load().then(()=>{r.set({fontFamily:e.fontFamily}),m?.requestRenderAll()}).catch(d=>{console.error(`ReactFabric: \u5B57\u4F53\u52A0\u8F7D\u5931\u8D25: ${e.fontFamily}`,d)})},[e.fontFamily,r]),i.useImperativeHandle(c,()=>r,[r]),y.useInstancePosition(r,o)});s.displayName="Text";var b=i.memo(s);exports.default=b;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../../../src/components/Text/index.tsx"],"sourcesContent":["import type { Group as BaseGroup } from 'fabric'\nimport { FabricText, Point, util } from 'fabric'\nimport { forwardRef, memo, useEffect, useImperativeHandle, type ReactNode } from 'react'\nimport { useCreateObject } from '../../hooks/useCreateObject'\nimport { useSplitProps } from '../../hooks/useSplitProps'\nimport { useStoreApi } from '../../hooks/useStore'\nimport type { AllObjectEvents } from '../../types/object'\nimport FontFaceObserver from 'fontfaceobserver'\nimport { useInstancePosition } from '../../hooks/useInstancePosition'\n\nexport type Handle = FabricText | undefined\n\nexport type TextProps<T = unknown> = Partial<ConstructorParameters<typeof FabricText>[1] & AllObjectEvents> & {\n group?: BaseGroup\n text: string\n children?: ReactNode\n} & T\n\nFabricText.prototype.set({\n _getNonTransformedDimensions() {\n // Object dimensions\n return new Point(this.width, this.height).scalarAdd(this.padding)\n },\n _calculateCurrentDimensions() {\n // Controls dimensions\n return util.transformPoint(this._getTransformedDimensions(), this.getViewportTransform(), true)\n },\n})\n\nconst Text = forwardRef<Handle, TextProps>(({ group, text, children, ...props }, ref) => {\n const store = useStoreApi()\n\n const [listeners, attributes] = useSplitProps(props)\n\n const instance = useCreateObject({\n Constructor: FabricText,\n param: text,\n attributes,\n group,\n listeners,\n })\n\n /**\n * 字体只有被使用了才会加载;先由 Text 使用一次, 监听加载完成,之后再 set 一次\n */\n useEffect(() => {\n const { canvas } = store.getState()\n if (!attributes.fontFamily || !instance) return\n const font = new FontFaceObserver(attributes.fontFamily)\n font\n .load()\n .then(() => {\n instance.set({\n fontFamily: attributes.fontFamily,\n })\n canvas?.requestRenderAll()\n })\n .catch(error => {\n // 加载失败\n console.error(`ReactFabric: 字体加载失败: ${attributes.fontFamily}`, error)\n })\n }, [attributes.fontFamily, instance])\n\n useImperativeHandle(ref, () => instance, [instance])\n return useInstancePosition(instance, children)\n})\n\nexport default memo(Text)\n"],"names":["FabricText","Point","util","Text","forwardRef","group","text","children","props","ref","store","useStoreApi","listeners","attributes","useSplitProps","instance","useCreateObject","useEffect","canvas","FontFaceObserver","error","useImperativeHandle","useInstancePosition","memo"],"mappings":"4TAkBAA,EAAAA,WAAW,UAAU,IAAI,CACvB,8BAA+B,CAE7B,OAAO,IAAIC,EAAM,MAAA,KAAK,MAAO,KAAK,MAAM,EAAE,UAAU,KAAK,OAAO,CAClE,EACA,6BAA8B,CAE5B,OAAOC,OAAK,eAAe,KAAK,4BAA6B,KAAK,qBAAwB,EAAA,EAAI,CAChG,CACF,CAAC,EAED,MAAMC,EAAOC,aAA8B,CAAC,CAAE,MAAAC,EAAO,KAAAC,EAAM,SAAAC,EAAU,GAAGC,CAAM,EAAGC,IAAQ,CACvF,MAAMC,EAAQC,EAAAA,YAAY,EAEpB,CAACC,EAAWC,CAAU,EAAIC,EAAAA,cAAcN,CAAK,EAE7CO,EAAWC,EAAgB,gBAAA,CAC/B,YAAahB,EAAAA,WACb,MAAOM,EACP,WAAAO,EACA,MAAAR,EACA,UAAAO,CACF,CAAC,EAKD,OAAAK,EAAAA,UAAU,IAAM,CACd,KAAM,CAAE,OAAAC,CAAO,EAAIR,EAAM,SAAS,EAC9B,CAACG,EAAW,YAAc,CAACE,GAClB,IAAII,EAAiBN,EAAW,UAAU,EAEpD,OACA,KAAK,IAAM,CACVE,EAAS,IAAI,CACX,WAAYF,EAAW,UACzB,CAAC,EACDK,GAAQ,iBAAiB,CAC3B,CAAC,EACA,MAAME,GAAS,CAEd,QAAQ,MAAM,sDAAwBP,EAAW,UAAU,GAAIO,CAAK,CACtE,CAAC,CACL,EAAG,CAACP,EAAW,WAAYE,CAAQ,CAAC,EAEpCM,EAAAA,oBAAoBZ,EAAK,IAAMM,EAAU,CAACA,CAAQ,CAAC,EAC5CO,EAAAA,oBAAoBP,EAAUR,CAAQ,CAC/C,CAAC,EAED,IAAegB,EAAAA,EAAAA,KAAKpB,CAAI"}
1
+ {"version":3,"file":"index.cjs","sources":["../../../../src/components/Text/index.tsx"],"sourcesContent":["import type { Group as BaseGroup } from 'fabric'\nimport { FabricText, Point, util } from 'fabric'\nimport { forwardRef, memo, useEffect, useImperativeHandle, type ReactNode } from 'react'\nimport { useCreateObject } from '../../hooks/useCreateObject'\nimport { useSplitProps } from '../../hooks/useSplitProps'\nimport { useStoreApi } from '../../hooks/useStore'\nimport type { AllObjectEvents } from '../../types/object'\nimport FontFaceObserver from 'fontfaceobserver'\nimport { useInstancePosition } from '../../hooks/useInstancePosition'\n\nexport type Handle = FabricText | undefined\n\nexport type TextProps<T = unknown> = Partial<FabricText & AllObjectEvents> & {\n group?: BaseGroup\n text: string\n children?: ReactNode\n} & T\n\nFabricText.prototype.set({\n _getNonTransformedDimensions() {\n // Object dimensions\n return new Point(this.width, this.height).scalarAdd(this.padding)\n },\n _calculateCurrentDimensions() {\n // Controls dimensions\n return util.transformPoint(this._getTransformedDimensions(), this.getViewportTransform(), true)\n },\n})\n\nconst Text = forwardRef<Handle, TextProps>(({ group, text, children, ...props }, ref) => {\n const store = useStoreApi()\n\n const [listeners, attributes] = useSplitProps(props)\n\n const instance = useCreateObject({\n Constructor: FabricText,\n param: text,\n attributes,\n group,\n listeners,\n })\n\n /**\n * 字体只有被使用了才会加载;先由 Text 使用一次, 监听加载完成,之后再 set 一次\n */\n useEffect(() => {\n const { canvas } = store.getState()\n if (!attributes.fontFamily || !instance) return\n const font = new FontFaceObserver(attributes.fontFamily)\n font\n .load()\n .then(() => {\n instance.set({\n fontFamily: attributes.fontFamily,\n })\n canvas?.requestRenderAll()\n })\n .catch(error => {\n // 加载失败\n console.error(`ReactFabric: 字体加载失败: ${attributes.fontFamily}`, error)\n })\n }, [attributes.fontFamily, instance])\n\n useImperativeHandle(ref, () => instance, [instance])\n return useInstancePosition(instance, children)\n})\n\nText.displayName = 'Text'\nexport default memo(Text)\n"],"names":["FabricText","Point","util","Text","forwardRef","group","text","children","props","ref","store","useStoreApi","listeners","attributes","useSplitProps","instance","useCreateObject","useEffect","canvas","FontFaceObserver","error","useImperativeHandle","useInstancePosition","memo"],"mappings":"4TAkBAA,EAAAA,WAAW,UAAU,IAAI,CACvB,8BAA+B,CAE7B,OAAO,IAAIC,EAAAA,MAAM,KAAK,MAAO,KAAK,MAAM,EAAE,UAAU,KAAK,OAAO,CAClE,EACA,6BAA8B,CAE5B,OAAOC,EAAAA,KAAK,eAAe,KAAK,4BAA6B,KAAK,qBAAA,EAAwB,EAAI,CAChG,CACF,CAAC,EAED,MAAMC,EAAOC,EAAAA,WAA8B,CAAC,CAAE,MAAAC,EAAO,KAAAC,EAAM,SAAAC,EAAU,GAAGC,CAAM,EAAGC,IAAQ,CACvF,MAAMC,EAAQC,EAAAA,cAER,CAACC,EAAWC,CAAU,EAAIC,EAAcN,cAAAA,CAAK,EAE7CO,EAAWC,EAAAA,gBAAgB,CAC/B,YAAahB,EAAAA,WACb,MAAOM,EACP,WAAAO,EACA,MAAAR,EACA,UAAAO,CACF,CAAC,EAKD,OAAAK,EAAAA,UAAU,IAAM,CACd,KAAM,CAAE,OAAAC,CAAO,EAAIR,EAAM,SAAA,EACrB,CAACG,EAAW,YAAc,CAACE,GAClB,IAAII,EAAiBN,EAAW,UAAU,EAEpD,KAAK,EACL,KAAK,IAAM,CACVE,EAAS,IAAI,CACX,WAAYF,EAAW,UACzB,CAAC,EACDK,GAAQ,iBACV,CAAA,CAAC,EACA,MAAME,GAAS,CAEd,QAAQ,MAAM,sDAAwBP,EAAW,UAAU,GAAIO,CAAK,CACtE,CAAC,CACL,EAAG,CAACP,EAAW,WAAYE,CAAQ,CAAC,EAEpCM,EAAAA,oBAAoBZ,EAAK,IAAMM,EAAU,CAACA,CAAQ,CAAC,EAC5CO,EAAAA,oBAAoBP,EAAUR,CAAQ,CAC/C,CAAC,EAEDJ,EAAK,YAAc,OACnB,IAAeoB,EAAAA,EAAAA,KAAKpB,CAAI"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react/jsx-runtime"),a=require("react"),Z=require("./Wrapper.cjs"),q=require("../../components/Canvas/index.cjs"),y=require("../../components/StoreUpdater/index.cjs"),D=require("../../components/Loading/index.cjs");const W={width:"100%",height:"100%",overflow:"hidden",position:"relative",zIndex:0},z=a.forwardRef(({minManualZoom:r,maxManualZoom:l,className:n,children:i,width:t,height:u,selection:d,style:s,onMouseWheel:m,onMouseDown:c,onMouseMove:h,onMouseUp:f,zoomable:M,panAble:x,defaultSelection:p,defaultCentered:v,defaultDraggable:b,manualZoom:g,...j},w)=>e.jsx("div",{style:{...W,...s},ref:w,className:`react-fabric ${n||""}`,children:e.jsxs(Z.Wrapper,{width:t,height:u,children:[e.jsx(y.StoreUpdater,{minManualZoom:r,maxManualZoom:l,zoomable:M,panAble:x,defaultCentered:v,selection:d,defaultSelection:p,defaultDraggable:b,manualZoom:g}),e.jsx(q.default,{onMouseDown:c,onMouseMove:h,onMouseUp:f,onMouseWheel:m,...j,children:i}),e.jsx(D.default,{})]})})),o=a.memo(z);o.displayName="ReactFabric",exports.default=o;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react/jsx-runtime"),r=require("react"),q=require("./Wrapper.cjs"),Z=require("../../components/Canvas/index.cjs"),D=require("../../components/StoreUpdater/index.cjs"),y=require("../../components/Loading/index.cjs");const W={width:"100%",height:"100%",overflow:"hidden",position:"relative",zIndex:0},z=r.forwardRef(({minManualZoom:n,maxManualZoom:i,className:t,children:u,width:a,height:o,selection:d,style:s,onMouseWheel:m,onMouseDown:h,onMouseMove:c,onMouseUp:f,zoomable:M,panAble:x,defaultSelection:p,defaultCentered:v,defaultDraggable:b,manualZoom:g,...w},j)=>e.jsx("div",{style:{...W,...s},ref:j,className:`react-fabric ${t||""}`,children:e.jsxs(q.Wrapper,{width:a,height:o,children:[e.jsx(D.StoreUpdater,{minManualZoom:n,maxManualZoom:i,zoomable:M,panAble:x,defaultCentered:v,selection:d,defaultSelection:p,defaultDraggable:b,manualZoom:g,width:a,height:o}),e.jsx(Z.default,{onMouseDown:h,onMouseMove:c,onMouseUp:f,onMouseWheel:m,...w,children:u}),e.jsx(y.default,{})]})})),l=r.memo(z);l.displayName="ReactFabric",exports.default=l;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../../../src/container/ReactFabric/index.tsx"],"sourcesContent":["import type { CSSProperties } from 'react'\nimport { forwardRef, memo } from 'react'\nimport { Wrapper } from './Wrapper'\nimport Canvas from '../../components/Canvas'\nimport { StoreUpdater } from '../../components/StoreUpdater'\nimport Loading from '../../components/Loading'\n\n// 自定义基础事件类型\ntype FabricEvent = {\n e: Event\n pointer: { x: number; y: number }\n target?: unknown\n subTargets?: unknown[]\n button?: number\n isClick?: boolean\n transform?: unknown\n}\n\n// 重新定义 CanvasProps,不再从 components/Canvas 导入\ntype BaseCanvasProps = {\n width?: number\n height?: number\n selection?: boolean\n children?: React.ReactNode\n // 添加其他必要的 Canvas 属性\n}\n\nconst wrapperStyle: CSSProperties = {\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n position: 'relative',\n zIndex: 0,\n}\n\nexport type ReactFabricProps = BaseCanvasProps & {\n style?: CSSProperties\n className?: string\n zoomable?: boolean\n panAble?: boolean\n manualZoom?: number\n minManualZoom?: number\n maxManualZoom?: number\n /** 背景图是否默认居中显示\n * @default false\n */\n defaultCentered?: boolean\n /** 是否启用选择功能\n * @default true\n * */\n defaultSelection?: boolean\n /**\n * 是否默认可拖拽\n */\n defaultDraggable?: boolean\n onMouseDown?: (e: FabricEvent) => void\n onMouseMove?: (e: FabricEvent) => void\n onMouseUp?: (e: FabricEvent) => void\n onMouseWheel?: (e: FabricEvent) => void\n}\n\nconst ForwardReactFabric = forwardRef<HTMLDivElement, ReactFabricProps>(\n (\n {\n minManualZoom,\n maxManualZoom,\n className,\n children,\n width,\n height,\n selection,\n style,\n onMouseWheel,\n onMouseDown,\n onMouseMove,\n onMouseUp,\n zoomable,\n panAble,\n defaultSelection,\n defaultCentered,\n defaultDraggable,\n manualZoom,\n ...rest\n },\n ref,\n ) => {\n return (\n <div style={{ ...wrapperStyle, ...style }} ref={ref} className={`react-fabric ${className || ''}`}>\n <Wrapper width={width} height={height}>\n <StoreUpdater\n minManualZoom={minManualZoom}\n maxManualZoom={maxManualZoom}\n zoomable={zoomable}\n panAble={panAble}\n defaultCentered={defaultCentered}\n selection={selection}\n defaultSelection={defaultSelection}\n defaultDraggable={defaultDraggable}\n manualZoom={manualZoom}\n />\n\n <Canvas\n onMouseDown={onMouseDown}\n onMouseMove={onMouseMove}\n onMouseUp={onMouseUp}\n onMouseWheel={onMouseWheel}\n {...rest}\n >\n {children}\n </Canvas>\n <Loading />\n </Wrapper>\n </div>\n )\n },\n)\n\ntype ReactFabricComponent = React.MemoExoticComponent<typeof ForwardReactFabric>\n\nconst ReactFabric: ReactFabricComponent = memo(ForwardReactFabric)\nReactFabric.displayName = 'ReactFabric'\n\nexport default ReactFabric\n"],"names":["wrapperStyle","ForwardReactFabric","forwardRef","minManualZoom","maxManualZoom","className","children","width","height","selection","style","onMouseWheel","onMouseDown","onMouseMove","onMouseUp","zoomable","panAble","defaultSelection","defaultCentered","defaultDraggable","manualZoom","rest","ref","jsx","jsxs","Wrapper","StoreUpdater","Canvas","Loading","ReactFabric","memo"],"mappings":"+SA2BMA,EAA8B,CAClC,MAAO,OACP,OAAQ,OACR,SAAU,SACV,SAAU,WACV,OAAQ,CACV,EA4BMC,EAAqBC,EAAAA,WACzB,CACE,CACE,cAAAC,EACA,cAAAC,EACA,UAAAC,EACA,SAAAC,EACA,MAAAC,EACA,OAAAC,EACA,UAAAC,EACA,MAAAC,EACA,aAAAC,EACA,YAAAC,EACA,YAAAC,EACA,UAAAC,EACA,SAAAC,EACA,QAAAC,EACA,iBAAAC,EACA,gBAAAC,EACA,iBAAAC,EACA,WAAAC,EACA,GAAGC,CACL,EACAC,IAGEC,EAAC,IAAA,MAAA,CAAI,MAAO,CAAE,GAAGvB,EAAc,GAAGU,CAAM,EAAG,IAAKY,EAAK,UAAW,gBAAgBjB,GAAa,EAAE,GAC7F,SAAAmB,EAACC,KAAAA,EAAAA,QAAA,CAAQ,MAAOlB,EAAO,OAAQC,EAC7B,UAAAe,EAACG,IAAAA,EAAAA,aAAA,CACC,cAAevB,EACf,cAAeC,EACf,SAAUW,EACV,QAASC,EACT,gBAAiBE,EACjB,UAAWT,EACX,iBAAkBQ,EAClB,iBAAkBE,EAClB,WAAYC,EACd,EAEAG,EAAAA,IAACI,EAAAA,QAAA,CACC,YAAaf,EACb,YAAaC,EACb,UAAWC,EACX,aAAcH,EACb,GAAGU,EAEH,SAAAf,CACH,CAAA,EACAiB,EAAAA,IAACK,EAAAA,QAAA,CAAA,CAAQ,CACX,CAAA,CAAA,CAAA,CACF,CAGN,EAIMC,EAAoCC,EAAK7B,KAAAA,CAAkB,EACjE4B,EAAY,YAAc"}
1
+ {"version":3,"file":"index.cjs","sources":["../../../../src/container/ReactFabric/index.tsx"],"sourcesContent":["import type { CSSProperties } from 'react'\nimport { forwardRef, memo } from 'react'\nimport { Wrapper } from './Wrapper'\nimport Canvas, { type CanvasProps } from '../../components/Canvas'\nimport { StoreUpdater } from '../../components/StoreUpdater'\nimport Loading from '../../components/Loading'\n\n// 重新定义 CanvasProps,不再从 components/Canvas 导入\ntype BaseCanvasProps = {\n width?: number\n height?: number\n selection?: boolean\n children?: React.ReactNode\n // 添加其他必要的 Canvas 属性\n}\n\nconst wrapperStyle: CSSProperties = {\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n position: 'relative',\n zIndex: 0,\n}\n\nexport type ReactFabricProps = BaseCanvasProps &\n CanvasProps & {\n style?: CSSProperties\n className?: string\n zoomable?: boolean\n panAble?: boolean\n manualZoom?: number\n minManualZoom?: number\n maxManualZoom?: number\n /** 背景图是否默认居中显示\n * @default false\n */\n defaultCentered?: boolean\n /** 是否启用选择功能\n * @default true\n * */\n defaultSelection?: boolean\n /**\n * 是否默认可拖拽\n */\n defaultDraggable?: boolean\n }\n\nconst ForwardReactFabric = forwardRef<HTMLDivElement, ReactFabricProps>(\n (\n {\n minManualZoom,\n maxManualZoom,\n className,\n children,\n width,\n height,\n selection,\n style,\n onMouseWheel,\n onMouseDown,\n onMouseMove,\n onMouseUp,\n zoomable,\n panAble,\n defaultSelection,\n defaultCentered,\n defaultDraggable,\n manualZoom,\n ...rest\n },\n ref,\n ) => {\n return (\n <div style={{ ...wrapperStyle, ...style }} ref={ref} className={`react-fabric ${className || ''}`}>\n <Wrapper width={width} height={height}>\n <StoreUpdater\n minManualZoom={minManualZoom}\n maxManualZoom={maxManualZoom}\n zoomable={zoomable}\n panAble={panAble}\n defaultCentered={defaultCentered}\n selection={selection}\n defaultSelection={defaultSelection}\n defaultDraggable={defaultDraggable}\n manualZoom={manualZoom}\n width={width}\n height={height}\n />\n\n <Canvas\n onMouseDown={onMouseDown}\n onMouseMove={onMouseMove}\n onMouseUp={onMouseUp}\n onMouseWheel={onMouseWheel}\n {...rest}\n >\n {children}\n </Canvas>\n <Loading />\n </Wrapper>\n </div>\n )\n },\n)\n\ntype ReactFabricComponent = React.MemoExoticComponent<typeof ForwardReactFabric>\n\nconst ReactFabric: ReactFabricComponent = memo(ForwardReactFabric)\nReactFabric.displayName = 'ReactFabric'\n\nexport default ReactFabric\n"],"names":["wrapperStyle","ForwardReactFabric","forwardRef","minManualZoom","maxManualZoom","className","children","width","height","selection","style","onMouseWheel","onMouseDown","onMouseMove","onMouseUp","zoomable","panAble","defaultSelection","defaultCentered","defaultDraggable","manualZoom","rest","ref","jsx","jsxs","Wrapper","StoreUpdater","Canvas","Loading","ReactFabric","memo"],"mappings":"ySAgBA,MAAMA,EAA8B,CAClC,MAAO,OACP,OAAQ,OACR,SAAU,SACV,SAAU,WACV,OAAQ,CACV,EAyBMC,EAAqBC,EACzB,WAAA,CACE,CACE,cAAAC,EACA,cAAAC,EACA,UAAAC,EACA,SAAAC,EACA,MAAAC,EACA,OAAAC,EACA,UAAAC,EACA,MAAAC,EACA,aAAAC,EACA,YAAAC,EACA,YAAAC,EACA,UAAAC,EACA,SAAAC,EACA,QAAAC,EACA,iBAAAC,EACA,gBAAAC,EACA,iBAAAC,EACA,WAAAC,EACA,GAAGC,CACL,EACAC,IAGEC,EAAAA,IAAC,OAAI,MAAO,CAAE,GAAGvB,EAAc,GAAGU,CAAM,EAAG,IAAKY,EAAK,UAAW,gBAAgBjB,GAAa,EAAE,GAC7F,SAAAmB,OAACC,EAAA,QAAA,CAAQ,MAAOlB,EAAO,OAAQC,EAC7B,SAAA,CAAAe,EAACG,IAAAA,EAAAA,aAAA,CACC,cAAevB,EACf,cAAeC,EACf,SAAUW,EACV,QAASC,EACT,gBAAiBE,EACjB,UAAWT,EACX,iBAAkBQ,EAClB,iBAAkBE,EAClB,WAAYC,EACZ,MAAOb,EACP,OAAQC,CACV,CAAA,EAEAe,EAAAA,IAACI,EAAAA,QAAA,CACC,YAAaf,EACb,YAAaC,EACb,UAAWC,EACX,aAAcH,EACb,GAAGU,EAEH,SAAAf,CACH,CAAA,EACAiB,EAACK,IAAAA,EAAAA,QAAA,CAAQ,CAAA,CACX,CAAA,CAAA,CAAA,CACF,CAGN,EAIMC,EAAoCC,EAAAA,KAAK7B,CAAkB,EACjE4B,EAAY,YAAc"}
@@ -1,2 +1,2 @@
1
- "use client";import{util as h,FabricImage as C}from"fabric";import{forwardRef as F,useRef as R,useCallback as A,useEffect as v,useImperativeHandle as V,memo as x}from"react";import{useDidUpdate as j}from"../../hooks/useDidUpdate.mjs";import{useStoreApi as q,useStore as y}from"../../hooks/useStore.mjs";const E=o=>({width:o.width,height:o.height}),L=F(({src:o,onLoad:w,onScaling:Z,scaleToFit:u,scaleToCover:g,...l},p)=>{const a=R(null),n=q(),{width:S,height:b}=y(E),d=A(c=>{const{canvas:e,manualZoom:t=1,defaultCentered:m}=n.getState();if(!a.current)return;if(!e){console.warn("updateViewport: !canvas");return}if(!e.backgroundImage){console.warn("updateViewport: !canvas.backgroundImage");return}const s=c.scaleToFit?h.findScaleToFit(a.current,e):c.scaleToCover?h.findScaleToCover(a.current,e):1,r=s*t;e.setViewportTransform([r,0,0,r,0,0]);let i=0,f=0;if(m&&e.backgroundImage){const I=e.backgroundImage.width||0,k=e.backgroundImage.height||0;i=(e.width-I*r)/2,f=(e.height-k*r)/2}const T=[r,0,0,r,i,f];e.setViewportTransform(T),e.requestRenderAll(),n.setState({fitZoom:s,manualZoom:t,zoom:r})},[n]);return v(()=>{d({scaleToFit:u,scaleToCover:g})},[S,b,u,g,d,n]),v(()=>{if(!o){console.warn("ReactFabricBackgroundImage: !src");return}const{domNode:c,setLoading:e}=n.getState();return e(!0),C.fromURL(o,{crossOrigin:"anonymous"}).then(t=>{const m=t.getSrc(),s=a.current?.getSrc();if(s&&m!==s)return;const{canvas:r}=n.getState();if(r){const i={...l,angle:0};if(t.set({...i,objectCaching:!1}),r.getContext().imageSmoothingEnabled=!0,r.getContext().imageSmoothingQuality="high",r.backgroundImage=t,a.current=t,requestAnimationFrame(()=>{d({scaleToFit:u,scaleToCover:g})}),!r.viewportTransform){console.warn("!viewport");return}w?.(t)}else console.warn("ReactFabric:BackgroundImage: !canvas",r)}).catch(console.error).finally(()=>{c&&(c.dataset.src=o),e(!1)}),()=>{const{canvas:t}=n.getState();t?.backgroundImage&&(t.backgroundImage=void 0,t.remove(a.current),a.current=null,t.renderAll())}},[o]),j(()=>{const{canvas:c}=n.getState();a.current&&(Object.entries(l).forEach(([e,t])=>{e==="angle"?a.current?.rotate(t):a.current?.set(e,t)}),c?.requestRenderAll())},[l,n]),V(p,()=>({instance:a.current})),null});var O=x(L);export{O as default};
1
+ "use client";import{util as v,FabricImage as A}from"fabric";import{forwardRef as L,useRef as b,useCallback as x,useEffect as w,useImperativeHandle as E,memo as V}from"react";import{useDidUpdate as j}from"../../hooks/useDidUpdate.mjs";import{useStoreApi as q,useStore as y}from"../../hooks/useStore.mjs";const B=o=>({width:o.width,height:o.height}),U=L(({src:o,onLoad:p,onScaling:H,onError:S,scaleToFit:u,scaleToCover:l,...g},T)=>{const t=b(null),a=q(),d=b(o),{width:k,height:I}=y(B),m=x(c=>{const{canvas:r,manualZoom:e=1,defaultCentered:n}=a.getState();if(!t.current)return;if(!r){console.warn("updateViewport: !canvas");return}if(!r.backgroundImage){console.warn("updateViewport: !canvas.backgroundImage");return}const s=c.scaleToFit?v.findScaleToFit(t.current,r):c.scaleToCover?v.findScaleToCover(t.current,r):1,i=s*e;r.setViewportTransform([i,0,0,i,0,0]);let f=0,h=0;if(n&&r.backgroundImage){const C=r.backgroundImage.width||0,R=r.backgroundImage.height||0;f=(r.width-C*i)/2,h=(r.height-R*i)/2}const F=[i,0,0,i,f,h];r.setViewportTransform(F),r.requestRenderAll(),a.setState({fitZoom:s,manualZoom:e,zoom:i})},[a]);return w(()=>{m({scaleToFit:u,scaleToCover:l})},[k,I,u,l,m,a]),w(()=>{if(!o){console.warn("ReactFabricBackgroundImage: !src");return}const{domNode:c,setLoading:r}=a.getState();return r(!0),d.current=o,A.fromURL(o,{crossOrigin:"anonymous"}).then(e=>{if(p?.(e),e.getSrc()!==d.current)return;const{canvas:n}=a.getState();if(n){const s={...g,angle:0};if(e.set({...s,objectCaching:!1}),n.getContext().imageSmoothingEnabled=!0,n.getContext().imageSmoothingQuality="high",n.backgroundImage=e,t.current=e,requestAnimationFrame(()=>{m({scaleToFit:u,scaleToCover:l})}),!n.viewportTransform){console.warn("!viewport");return}}else console.warn("ReactFabric:BackgroundImage: !canvas",n)}).catch(e=>{S?.(e),console.error("[ReactFabric] BackgroundImage: fromURL error",e)}).finally(()=>{c&&(c.dataset.src=o),r(!1)}),()=>{const{canvas:e}=a.getState();e?.backgroundImage&&(e.backgroundImage=void 0,e.remove(t.current),t.current=null,e.renderAll())}},[o]),j(()=>{const{canvas:c}=a.getState();t.current&&(Object.entries(g).forEach(([r,e])=>{r==="angle"?t.current?.rotate(e):t.current?.set(r,e)}),c?.requestRenderAll())},[g,a]),E(T,()=>({instance:t.current})),null});var Z=V(U);export{Z as default};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../../../src/components/BackgroundImage/index.tsx"],"sourcesContent":["import type {\n BasicTransformEvent,\n ImageProps,\n ObjectEvents,\n SerializedImageProps,\n TDegree,\n TPointerEvent,\n} from 'fabric'\nimport { FabricImage, util } from 'fabric'\nimport { forwardRef, memo, useCallback, useEffect, useImperativeHandle, useRef } from 'react'\nimport { useDidUpdate } from '../../hooks/useDidUpdate'\nimport { useStore, useStoreApi } from '../../hooks/useStore'\nimport type { ReactFabricState } from '../../types/store'\n\nexport type Handle = {}\n\ntype ScaleMode = {\n scaleToFit?: boolean\n scaleToCover?: boolean\n}\nexport type BackgroundImageProps = Partial<ImageProps> & {\n src: string\n onLoad?: (imageSource: FabricImage<Partial<ImageProps>, SerializedImageProps, ObjectEvents>) => void\n onScaling?: (scale: BasicTransformEvent<TPointerEvent>) => void\n\n /** 自动缩放至容器宽高 */\n} & ScaleMode\n\nconst selector = (s: ReactFabricState) => ({\n width: s.width,\n height: s.height,\n})\n\nconst BackgroundImage = forwardRef<Handle, BackgroundImageProps>(\n ({ src, onLoad, onScaling, scaleToFit, scaleToCover, ...options }, ref) => {\n const backgroundImageRef = useRef<FabricImage | null>(null)\n\n const store = useStoreApi()\n\n const { width, height } = useStore(selector)\n\n const updateViewport = useCallback(\n (params: { scaleToFit?: boolean; scaleToCover?: boolean }) => {\n const { canvas, manualZoom = 1, defaultCentered } = store.getState()\n if (!backgroundImageRef.current) {\n return\n }\n if (!canvas) {\n console.warn('updateViewport: !canvas')\n return\n }\n if (!canvas.backgroundImage) {\n console.warn('updateViewport: !canvas.backgroundImage')\n return\n }\n\n // 1. 计算缩放\n const fitZoom = params.scaleToFit\n ? util.findScaleToFit(backgroundImageRef.current, canvas)\n : params.scaleToCover\n ? util.findScaleToCover(backgroundImageRef.current, canvas)\n : 1\n\n const combinedZoom = fitZoom * manualZoom\n\n // 2. 先应用基础缩放\n canvas.setViewportTransform([combinedZoom, 0, 0, combinedZoom, 0, 0])\n\n // 3. 如果需要居中,计算偏移量\n let deltaX = 0\n let deltaY = 0\n\n if (defaultCentered && canvas.backgroundImage) {\n const bgWidth = canvas.backgroundImage.width || 0\n const bgHeight = canvas.backgroundImage.height || 0\n deltaX = (canvas.width! - bgWidth * combinedZoom) / 2\n deltaY = (canvas.height! - bgHeight * combinedZoom) / 2\n // const canvasCenter = {\n // x: canvas.width! / 2,\n // y: canvas.height! / 2,\n // }\n // const bgCenter = {\n // x:\n // (canvas.backgroundImage.left! + (canvas.backgroundImage.width! * canvas.backgroundImage.scaleX!) / 2) *\n // combinedZoom,\n // y:\n // (canvas.backgroundImage.top! + (canvas.backgroundImage.height! * canvas.backgroundImage.scaleY!) / 2) *\n // combinedZoom,\n // }\n // deltaX = canvasCenter.x - bgCenter.x\n // deltaY = canvasCenter.y - bgCenter.y\n }\n\n // 4. 应用最终变换\n const finalTransform: [number, number, number, number, number, number] = [\n combinedZoom,\n 0,\n 0,\n combinedZoom,\n deltaX,\n deltaY,\n ]\n\n canvas.setViewportTransform(finalTransform)\n canvas.requestRenderAll()\n\n // 5. 更新 store\n store.setState({\n fitZoom,\n manualZoom,\n zoom: combinedZoom,\n })\n },\n [store],\n )\n\n // 监听 width, height 的变化\n useEffect(() => {\n updateViewport({\n scaleToFit,\n scaleToCover,\n })\n }, [width, height, scaleToFit, scaleToCover, updateViewport, store])\n\n useEffect(() => {\n if (!src) {\n console.warn('ReactFabricBackgroundImage: !src')\n return\n }\n const { domNode, setLoading } = store.getState()\n setLoading(true)\n FabricImage.fromURL(src, { crossOrigin: 'anonymous' })\n .then(imageSource => {\n const currentSrc = imageSource.getSrc()\n const latestSrc = backgroundImageRef.current?.getSrc()\n\n if (latestSrc && currentSrc !== latestSrc) {\n return\n }\n\n const { canvas } = store.getState()\n if (canvas) {\n // 初始化时角度的旋转,一定要放到 updateViewport 之后;先画正图片,再进行旋转\n const removeAngleOptions = { ...options, angle: 0 }\n imageSource.set({\n ...removeAngleOptions,\n objectCaching: false,\n })\n canvas.getContext().imageSmoothingEnabled = true\n canvas.getContext().imageSmoothingQuality = 'high'\n canvas.backgroundImage = imageSource\n backgroundImageRef.current = imageSource\n\n requestAnimationFrame(() => {\n updateViewport({\n scaleToFit,\n scaleToCover,\n })\n })\n\n const viewport = canvas.viewportTransform\n if (!viewport) {\n console.warn('!viewport')\n return\n }\n\n // imageSource.angle = options.angle || 0\n onLoad?.(imageSource)\n } else {\n console.warn('ReactFabric:BackgroundImage: !canvas', canvas)\n }\n })\n .catch(console.error)\n .finally(() => {\n if (domNode) domNode.dataset.src = src\n setLoading(false)\n })\n\n return () => {\n const { canvas } = store.getState()\n if (canvas?.backgroundImage) {\n canvas.backgroundImage = undefined\n canvas.remove(backgroundImageRef.current!)\n backgroundImageRef.current = null\n canvas.renderAll()\n }\n }\n }, [src])\n\n useDidUpdate(() => {\n const { canvas } = store.getState()\n\n if (backgroundImageRef.current) {\n Object.entries(options).forEach(([key, value]) => {\n if (key === 'angle') {\n backgroundImageRef.current?.rotate(value as TDegree)\n } else {\n backgroundImageRef.current?.set(key, value)\n }\n })\n canvas?.requestRenderAll()\n }\n }, [options, store])\n\n useImperativeHandle(ref, () => ({\n // 是最新的?\n instance: backgroundImageRef.current,\n }))\n\n return null\n },\n)\n\nexport default memo(BackgroundImage)\n"],"names":["selector","s","BackgroundImage","forwardRef","src","onLoad","onScaling","scaleToFit","scaleToCover","options","ref","backgroundImageRef","useRef","store","useStoreApi","width","height","useStore","updateViewport","useCallback","params","canvas","manualZoom","defaultCentered","fitZoom","util","combinedZoom","deltaX","deltaY","bgWidth","bgHeight","finalTransform","useEffect","domNode","setLoading","FabricImage","imageSource","currentSrc","latestSrc","removeAngleOptions","useDidUpdate","key","value","useImperativeHandle","memo"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../../../../src/components/BackgroundImage/index.tsx"],"sourcesContent":["import type {\n BasicTransformEvent,\n ImageProps,\n ObjectEvents,\n SerializedImageProps,\n TDegree,\n TPointerEvent,\n} from 'fabric'\nimport { FabricImage, util } from 'fabric'\nimport { forwardRef, memo, useCallback, useEffect, useImperativeHandle, useRef } from 'react'\nimport { useDidUpdate } from '../../hooks/useDidUpdate'\nimport { useStore, useStoreApi } from '../../hooks/useStore'\nimport type { ReactFabricState } from '../../types/store'\n\nexport type Handle = {\n instance: FabricImage | null\n}\n\ntype ScaleMode = {\n scaleToFit?: boolean\n scaleToCover?: boolean\n}\nexport type BackgroundImageProps = Partial<ImageProps> & {\n src: string\n onLoad?: (imageSource: FabricImage<Partial<ImageProps>, SerializedImageProps, ObjectEvents>) => void\n onScaling?: (scale: BasicTransformEvent<TPointerEvent>) => void\n onError?: (e: any) => void\n\n /** 自动缩放至容器宽高 */\n} & ScaleMode\n\nconst selector = (s: ReactFabricState) => ({\n width: s.width,\n height: s.height,\n})\n\nconst BackgroundImage = forwardRef<Handle, BackgroundImageProps>(\n ({ src, onLoad, onScaling, onError, scaleToFit, scaleToCover, ...options }, ref) => {\n const backgroundImageRef = useRef<FabricImage | null>(null)\n\n const store = useStoreApi()\n const newestSrcRef = useRef(src)\n\n const { width, height } = useStore(selector)\n\n const updateViewport = useCallback(\n (params: { scaleToFit?: boolean; scaleToCover?: boolean }) => {\n const { canvas, manualZoom = 1, defaultCentered } = store.getState()\n if (!backgroundImageRef.current) {\n return\n }\n if (!canvas) {\n console.warn('updateViewport: !canvas')\n return\n }\n if (!canvas.backgroundImage) {\n console.warn('updateViewport: !canvas.backgroundImage')\n return\n }\n\n // 1. 计算缩放\n const fitZoom = params.scaleToFit\n ? util.findScaleToFit(backgroundImageRef.current, canvas)\n : params.scaleToCover\n ? util.findScaleToCover(backgroundImageRef.current, canvas)\n : 1\n\n const combinedZoom = fitZoom * manualZoom\n\n // 2. 先应用基础缩放\n canvas.setViewportTransform([combinedZoom, 0, 0, combinedZoom, 0, 0])\n\n // 3. 如果需要居中,计算偏移量\n let deltaX = 0\n let deltaY = 0\n\n if (defaultCentered && canvas.backgroundImage) {\n const bgWidth = canvas.backgroundImage.width || 0\n const bgHeight = canvas.backgroundImage.height || 0\n deltaX = (canvas.width! - bgWidth * combinedZoom) / 2\n deltaY = (canvas.height! - bgHeight * combinedZoom) / 2\n // const canvasCenter = {\n // x: canvas.width! / 2,\n // y: canvas.height! / 2,\n // }\n // const bgCenter = {\n // x:\n // (canvas.backgroundImage.left! + (canvas.backgroundImage.width! * canvas.backgroundImage.scaleX!) / 2) *\n // combinedZoom,\n // y:\n // (canvas.backgroundImage.top! + (canvas.backgroundImage.height! * canvas.backgroundImage.scaleY!) / 2) *\n // combinedZoom,\n // }\n // deltaX = canvasCenter.x - bgCenter.x\n // deltaY = canvasCenter.y - bgCenter.y\n }\n\n // 4. 应用最终变换\n const finalTransform: [number, number, number, number, number, number] = [\n combinedZoom,\n 0,\n 0,\n combinedZoom,\n deltaX,\n deltaY,\n ]\n\n canvas.setViewportTransform(finalTransform)\n canvas.requestRenderAll()\n\n // 5. 更新 store\n store.setState({\n fitZoom,\n manualZoom,\n zoom: combinedZoom,\n })\n },\n [store],\n )\n\n // 监听 width, height 的变化\n useEffect(() => {\n updateViewport({\n scaleToFit,\n scaleToCover,\n })\n }, [width, height, scaleToFit, scaleToCover, updateViewport, store])\n\n useEffect(() => {\n if (!src) {\n console.warn('ReactFabricBackgroundImage: !src')\n return\n }\n const { domNode, setLoading } = store.getState()\n setLoading(true)\n newestSrcRef.current = src\n\n FabricImage.fromURL(src, { crossOrigin: 'anonymous' })\n .then(imageSource => {\n onLoad?.(imageSource)\n const currentSrc = imageSource.getSrc()\n\n if (currentSrc !== newestSrcRef.current) {\n return\n }\n\n const { canvas } = store.getState()\n if (canvas) {\n // 初始化时角度的旋转,一定要放到 updateViewport 之后;先画正图片,再进行旋转\n const removeAngleOptions = { ...options, angle: 0 }\n imageSource.set({\n ...removeAngleOptions,\n objectCaching: false,\n })\n canvas.getContext().imageSmoothingEnabled = true\n canvas.getContext().imageSmoothingQuality = 'high'\n canvas.backgroundImage = imageSource\n backgroundImageRef.current = imageSource\n\n requestAnimationFrame(() => {\n updateViewport({\n scaleToFit,\n scaleToCover,\n })\n })\n\n const viewport = canvas.viewportTransform\n if (!viewport) {\n console.warn('!viewport')\n return\n }\n\n // imageSource.angle = options.angle || 0\n } else {\n console.warn('ReactFabric:BackgroundImage: !canvas', canvas)\n }\n })\n .catch(e => {\n onError?.(e)\n console.error('[ReactFabric] BackgroundImage: fromURL error', e)\n })\n .finally(() => {\n if (domNode) domNode.dataset.src = src\n setLoading(false)\n })\n\n return () => {\n const { canvas } = store.getState()\n if (canvas?.backgroundImage) {\n canvas.backgroundImage = undefined\n canvas.remove(backgroundImageRef.current!)\n backgroundImageRef.current = null\n canvas.renderAll()\n }\n }\n }, [src])\n\n useDidUpdate(() => {\n const { canvas } = store.getState()\n\n if (backgroundImageRef.current) {\n Object.entries(options).forEach(([key, value]) => {\n if (key === 'angle') {\n backgroundImageRef.current?.rotate(value as TDegree)\n } else {\n backgroundImageRef.current?.set(key, value)\n }\n })\n canvas?.requestRenderAll()\n }\n }, [options, store])\n\n useImperativeHandle(ref, () => ({\n // 是最新的?\n instance: backgroundImageRef.current,\n }))\n\n return null\n },\n)\n\nexport default memo(BackgroundImage)\n"],"names":["selector","s","BackgroundImage","forwardRef","src","onLoad","onScaling","onError","scaleToFit","scaleToCover","options","ref","backgroundImageRef","useRef","store","useStoreApi","newestSrcRef","width","height","useStore","updateViewport","useCallback","params","canvas","manualZoom","defaultCentered","fitZoom","util","combinedZoom","deltaX","deltaY","bgWidth","bgHeight","finalTransform","useEffect","domNode","setLoading","FabricImage","imageSource","removeAngleOptions","useDidUpdate","key","value","useImperativeHandle","memo"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use client";import{jsxs as y,jsx as h}from"react/jsx-runtime";import{Canvas as z,Point as w}from"fabric";import{useRef as c,useLayoutEffect as M,useEffect as i}from"react";import _ from"../../hooks/useDraggable.mjs";import g from"../../hooks/useResizeHandler.mjs";import{useSplitProps as A}from"../../hooks/useSplitProps.mjs";import{useStoreApi as D,useStore as E}from"../../hooks/useStore.mjs";import{bindEvents as j}from"../../utils/events.mjs";const C={position:"absolute",width:"100%",height:"100%",top:0,left:0},L=({children:S,onMouseWheel:l,...b})=>{const e=c(),s=D(),u=c(null);_();const m=c(null),N=E(t=>t.controls),[P,n]=A(b);return M(()=>{const t=u.current;e.current=new z(t||void 0,{...n});const r=j(e.current,P);return s.setState({canvas:e.current}),window.canvas=e.current,()=>{r(),e.current?.dispose(),t?.remove(),e.current=void 0,s.setState({canvas:null})}},[]),g(),i(()=>{const t=r=>{const{zoomable:Y,panAble:Z,maxManualZoom:f,minManualZoom:d,fitZoom:p=1,zoom:x}=s.getState();if(r.e.preventDefault(),r.e.stopPropagation(),r.e.wheelDeltaY!==0){if(r.e.ctrlKey||r.e.wheelDeltaY===void 0){if(!Y)return;const a=r.e.deltaY>0?.95:1.05;let o=x/p*a;o>f&&(o=f),o<d&&(o=d);const v=o*p;e.current?.zoomToPoint(new w(r.e.offsetX,r.e.offsetY),v),s.setState({manualZoom:o,zoom:v})}else{if(!Z)return;const a=1.5,o=new w(-r.e.deltaX*a,-r.e.deltaY*a);e.current?.relativePan(o)}l?.(r)}};return e.current?.on("mouse:wheel",t),()=>{e.current?.off("mouse:wheel",t)}},[l,s]),i(()=>{s.setState({domNode:m.current?.closest(".react-fabric")})},[s]),i(()=>{e.current&&(e.current.set(n),e.current.requestRenderAll())},[n]),y("div",{className:"react-fabric__canvas",ref:m,style:C,children:[h("canvas",{ref:u}),S,N.map(t=>h("div",{id:t.id,style:{position:"absolute"},className:`react-fabric__control ${t.className}`,ref:t.ref,children:t.children},t.id))]})};export{L as default};
1
+ "use client";import{jsxs as y,jsx as h}from"react/jsx-runtime";import{Canvas as z,Point as w}from"fabric";import{useRef as c,useLayoutEffect as M,useEffect as i}from"react";import _ from"../../hooks/useDraggable.mjs";import g from"../../hooks/useResizeHandler.mjs";import{useSplitProps as A}from"../../hooks/useSplitProps.mjs";import{useStoreApi as D,useStore as E}from"../../hooks/useStore.mjs";import{bindEvents as j}from"../../utils/events.mjs";const C={position:"absolute",width:"100%",height:"100%",top:0,left:0},L=({children:S,onMouseWheel:l,...b})=>{const e=c(),n=D(),u=c(null);_();const f=c(null),N=E(r=>r.controls),[P,a]=A(b);return M(()=>{const r=u.current;e.current=new z(r||void 0,{...a});const t=j(e.current,P);return n.setState({canvas:e.current}),window.canvas=e.current,()=>{t(),e.current?.dispose(),e.current=void 0,n.setState({canvas:null})}},[]),g(),i(()=>{const r=t=>{const{zoomable:Y,panAble:Z,maxManualZoom:m,minManualZoom:d,fitZoom:p=1,zoom:x}=n.getState();if(t.e.preventDefault(),t.e.stopPropagation(),t.e.wheelDeltaY!==0){if(t.e.ctrlKey||t.e.wheelDeltaY===void 0){if(!Y)return;const s=t.e.deltaY>0?.95:1.05;let o=x/p*s;o>m&&(o=m),o<d&&(o=d);const v=o*p;e.current?.zoomToPoint(new w(t.e.offsetX,t.e.offsetY),v),n.setState({manualZoom:o,zoom:v})}else{if(!Z)return;const s=1.5,o=new w(-t.e.deltaX*s,-t.e.deltaY*s);e.current?.relativePan(o)}l?.(t)}};return e.current?.on("mouse:wheel",r),()=>{e.current?.off("mouse:wheel",r)}},[l,n]),i(()=>{n.setState({domNode:f.current?.closest(".react-fabric")})},[n]),i(()=>{e.current&&(e.current.set(a),e.current.requestRenderAll())},[a]),y("div",{className:"react-fabric__canvas",ref:f,style:C,children:[h("canvas",{ref:u}),S,N.map(r=>h("div",{id:r.id,style:{position:"absolute"},className:`react-fabric__control ${r.className}`,ref:r.ref,children:r.children},r.id))]})};export{L as default};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../../../src/components/Canvas/index.tsx"],"sourcesContent":["import type { CanvasEvents, CanvasOptions, TPointerEventInfo } from 'fabric'\nimport { Canvas as BaseCanvas, Point } from 'fabric'\nimport type { CSSProperties, PropsWithChildren } from 'react'\nimport { useEffect, useLayoutEffect, useRef } from 'react'\nimport useDraggable from '../../hooks/useDraggable'\nimport useResizeHandler from '../../hooks/useResizeHandler'\nimport { useSplitProps } from '../../hooks/useSplitProps'\nimport { useStore, useStoreApi } from '../../hooks/useStore'\nimport type { AllCanvasEvents } from '../../types/canvas'\nimport { bindEvents } from '../../utils/events'\n\nconst style: CSSProperties = {\n position: 'absolute',\n width: '100%',\n height: '100%',\n top: 0,\n left: 0,\n}\n\n// 首先定义事件类型\ntype CanvasEventProps = {\n [K in keyof AllCanvasEvents]: AllCanvasEvents[K]\n}\n\n// 分离配置属性类型\ntype CanvasConfigProps = Omit<CanvasOptions, keyof CanvasEventProps>\n\n// 重新定义 CanvasProps\nexport type CanvasProps = PropsWithChildren<Partial<CanvasConfigProps> & Partial<CanvasEventProps>>\n\nconst Canvas = ({ children, onMouseWheel, ...props }: CanvasProps) => {\n const canvasRef = useRef<BaseCanvas>()\n const store = useStoreApi()\n const canvasDomRef = useRef<HTMLCanvasElement | null>(null)\n useDraggable()\n const domRef = useRef<HTMLDivElement>(null)\n const controls = useStore(state => state.controls)\n\n const [listeners, attributes] = useSplitProps(props)\n\n useLayoutEffect(() => {\n const canvas = canvasDomRef.current\n\n canvasRef.current = new BaseCanvas(canvas || undefined, {\n ...attributes,\n })\n\n // 绑定事件并获取清理函数\n const unbindEvents = bindEvents<CanvasEvents>(canvasRef.current, listeners)\n\n store.setState({\n canvas: canvasRef.current,\n })\n //@ts-expect-error 报错撒撒\n window.canvas = canvasRef.current\n\n return () => {\n unbindEvents() // 调用清理函数\n canvasRef.current?.dispose()\n canvas?.remove()\n canvasRef.current = undefined // 清除引用\n store.setState({\n canvas: null,\n })\n }\n }, [])\n\n useResizeHandler()\n\n useEffect(() => {\n const onMouseWheelHandler = (opt: TPointerEventInfo<WheelEvent>) => {\n const { zoomable, panAble, maxManualZoom, minManualZoom, fitZoom = 1, zoom } = store.getState()\n\n // 阻止默认行为\n opt.e.preventDefault()\n opt.e.stopPropagation()\n\n // 如果是惯性滚动,直接返回\n if ((opt.e as any).wheelDeltaY === 0) return\n\n // 检查是否为缩放手势(Mac 上的双指捏合/张开)\n if (opt.e.ctrlKey || (opt.e as any).wheelDeltaY === undefined) {\n // 缩放逻辑\n if (!zoomable) return\n\n const delta = opt.e.deltaY\n const zoomFactor = delta > 0 ? 0.95 : 1.05\n const currentManualZoom = zoom / fitZoom\n let newManualZoom = currentManualZoom * zoomFactor\n\n if (newManualZoom > maxManualZoom) newManualZoom = maxManualZoom\n if (newManualZoom < minManualZoom) newManualZoom = minManualZoom\n\n const combinedZoom = newManualZoom * fitZoom\n\n canvasRef.current?.zoomToPoint(new Point(opt.e.offsetX, opt.e.offsetY), combinedZoom)\n\n store.setState({\n manualZoom: newManualZoom,\n zoom: combinedZoom,\n })\n } else {\n if (!panAble) return\n // 平移逻辑\n // 如果觉得太灵敏了,可以调小这个值,比如改为 1.2 或更小\n const sensitivityFactor = 1.5\n const delta = new Point(-opt.e.deltaX * sensitivityFactor, -opt.e.deltaY * sensitivityFactor)\n canvasRef.current?.relativePan(delta)\n }\n\n onMouseWheel?.(opt)\n }\n\n canvasRef.current?.on('mouse:wheel', onMouseWheelHandler)\n\n return () => {\n canvasRef.current?.off('mouse:wheel', onMouseWheelHandler)\n }\n }, [onMouseWheel, store])\n\n useEffect(() => {\n store.setState({\n domNode: domRef.current?.closest('.react-fabric') as HTMLDivElement,\n })\n }, [store])\n\n useEffect(() => {\n if (canvasRef.current) {\n canvasRef.current.set(attributes)\n canvasRef.current.requestRenderAll()\n }\n }, [attributes])\n\n return (\n <div className=\"react-fabric__canvas\" ref={domRef} style={style}>\n <canvas ref={canvasDomRef}></canvas>\n {children}\n {controls.map(control => (\n <div\n key={control.id}\n id={control.id}\n style={{\n position: 'absolute',\n }}\n className={`react-fabric__control ${control.className}`}\n ref={control.ref}\n >\n {control.children}\n </div>\n ))}\n </div>\n )\n}\n\nexport default Canvas\n"],"names":["style","Canvas","children","onMouseWheel","props","canvasRef","useRef","store","useStoreApi","canvasDomRef","useDraggable","domRef","controls","useStore","state","listeners","attributes","useSplitProps","useLayoutEffect","canvas","BaseCanvas","unbindEvents","bindEvents","useResizeHandler","useEffect","onMouseWheelHandler","opt","zoomable","panAble","maxManualZoom","minManualZoom","fitZoom","zoom","zoomFactor","newManualZoom","combinedZoom","Point","sensitivityFactor","delta","jsxs","jsx","control"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../../../../src/components/Canvas/index.tsx"],"sourcesContent":["import type { CanvasEvents, CanvasOptions, TPointerEventInfo } from 'fabric'\nimport { Canvas as BaseCanvas, Point } from 'fabric'\nimport type { CSSProperties, PropsWithChildren } from 'react'\nimport { useEffect, useLayoutEffect, useRef } from 'react'\nimport useDraggable from '../../hooks/useDraggable'\nimport useResizeHandler from '../../hooks/useResizeHandler'\nimport { useSplitProps } from '../../hooks/useSplitProps'\nimport { useStore, useStoreApi } from '../../hooks/useStore'\nimport type { AllCanvasEvents } from '../../types/canvas'\nimport { bindEvents } from '../../utils/events'\n\nconst style: CSSProperties = {\n position: 'absolute',\n width: '100%',\n height: '100%',\n top: 0,\n left: 0,\n}\n\n// 首先定义事件类型\ntype CanvasEventProps = {\n [K in keyof AllCanvasEvents]: AllCanvasEvents[K]\n}\n\n// 分离配置属性类型\ntype CanvasConfigProps = Omit<CanvasOptions, keyof CanvasEventProps>\n\n// 重新定义 CanvasProps\nexport type CanvasProps = PropsWithChildren<Partial<CanvasConfigProps> & Partial<CanvasEventProps>>\n\nconst Canvas = ({ children, onMouseWheel, ...props }: CanvasProps) => {\n const canvasRef = useRef<BaseCanvas>()\n const store = useStoreApi()\n const canvasDomRef = useRef<HTMLCanvasElement | null>(null)\n useDraggable()\n const domRef = useRef<HTMLDivElement>(null)\n const controls = useStore(state => state.controls)\n\n const [listeners, attributes] = useSplitProps(props)\n\n useLayoutEffect(() => {\n const canvas = canvasDomRef.current\n\n canvasRef.current = new BaseCanvas(canvas || undefined, {\n ...attributes,\n })\n\n // 绑定事件并获取清理函数\n const unbindEvents = bindEvents<CanvasEvents>(canvasRef.current, listeners)\n\n store.setState({\n canvas: canvasRef.current,\n })\n //@ts-expect-error 报错撒撒\n window.canvas = canvasRef.current\n\n return () => {\n unbindEvents() // 调用清理函数\n canvasRef.current?.dispose()\n canvasRef.current = undefined // 清除引用\n store.setState({\n canvas: null,\n })\n }\n }, [])\n\n useResizeHandler()\n\n useEffect(() => {\n const onMouseWheelHandler = (opt: TPointerEventInfo<WheelEvent>) => {\n const { zoomable, panAble, maxManualZoom, minManualZoom, fitZoom = 1, zoom } = store.getState()\n\n // 阻止默认行为\n opt.e.preventDefault()\n opt.e.stopPropagation()\n\n // 如果是惯性滚动,直接返回\n if ((opt.e as any).wheelDeltaY === 0) return\n\n // 检查是否为缩放手势(Mac 上的双指捏合/张开)\n if (opt.e.ctrlKey || (opt.e as any).wheelDeltaY === undefined) {\n // 缩放逻辑\n if (!zoomable) return\n\n const delta = opt.e.deltaY\n const zoomFactor = delta > 0 ? 0.95 : 1.05\n const currentManualZoom = zoom / fitZoom\n let newManualZoom = currentManualZoom * zoomFactor\n\n if (newManualZoom > maxManualZoom) newManualZoom = maxManualZoom\n if (newManualZoom < minManualZoom) newManualZoom = minManualZoom\n\n const combinedZoom = newManualZoom * fitZoom\n\n canvasRef.current?.zoomToPoint(new Point(opt.e.offsetX, opt.e.offsetY), combinedZoom)\n\n store.setState({\n manualZoom: newManualZoom,\n zoom: combinedZoom,\n })\n } else {\n if (!panAble) return\n // 平移逻辑\n // 如果觉得太灵敏了,可以调小这个值,比如改为 1.2 或更小\n const sensitivityFactor = 1.5\n const delta = new Point(-opt.e.deltaX * sensitivityFactor, -opt.e.deltaY * sensitivityFactor)\n canvasRef.current?.relativePan(delta)\n }\n\n onMouseWheel?.(opt)\n }\n\n canvasRef.current?.on('mouse:wheel', onMouseWheelHandler)\n\n return () => {\n canvasRef.current?.off('mouse:wheel', onMouseWheelHandler)\n }\n }, [onMouseWheel, store])\n\n useEffect(() => {\n store.setState({\n domNode: domRef.current?.closest('.react-fabric') as HTMLDivElement,\n })\n }, [store])\n\n useEffect(() => {\n if (canvasRef.current) {\n canvasRef.current.set(attributes)\n canvasRef.current.requestRenderAll()\n }\n }, [attributes])\n\n return (\n <div className=\"react-fabric__canvas\" ref={domRef} style={style}>\n <canvas ref={canvasDomRef}></canvas>\n {children}\n {controls.map(control => (\n <div\n key={control.id}\n id={control.id}\n style={{\n position: 'absolute',\n }}\n className={`react-fabric__control ${control.className}`}\n ref={control.ref}\n >\n {control.children}\n </div>\n ))}\n </div>\n )\n}\n\nexport default Canvas\n"],"names":["style","Canvas","children","onMouseWheel","props","canvasRef","useRef","store","useStoreApi","canvasDomRef","useDraggable","domRef","controls","useStore","state","listeners","attributes","useSplitProps","useLayoutEffect","canvas","BaseCanvas","unbindEvents","bindEvents","useResizeHandler","useEffect","onMouseWheelHandler","opt","zoomable","panAble","maxManualZoom","minManualZoom","fitZoom","zoom","zoomFactor","newManualZoom","combinedZoom","Point","sensitivityFactor","delta","jsxs","jsx","control"],"mappings":"gcAWMA,MAAAA,EAAuB,CAC3B,SAAU,WACV,MAAO,OACP,OAAQ,OACR,IAAK,EACL,KAAM,CACR,EAaMC,EAAS,CAAC,CAAE,SAAAC,EAAU,aAAAC,EAAc,GAAGC,CAAM,IAAmB,CACpE,MAAMC,EAAYC,EACZC,EAAAA,EAAQC,EAAY,EACpBC,EAAeH,EAAiC,IAAI,EAC1DI,EAAAA,EACA,MAAMC,EAASL,EAAuB,IAAI,EACpCM,EAAWC,EAASC,GAASA,EAAM,QAAQ,EAE3C,CAACC,EAAWC,CAAU,EAAIC,EAAcb,CAAK,EAEnD,OAAAc,EAAgB,IAAM,CACpB,MAAMC,EAASV,EAAa,QAE5BJ,EAAU,QAAU,IAAIe,EAAWD,GAAU,OAAW,CACtD,GAAGH,CACL,CAAC,EAGD,MAAMK,EAAeC,EAAyBjB,EAAU,QAASU,CAAS,EAE1E,OAAAR,EAAM,SAAS,CACb,OAAQF,EAAU,OACpB,CAAC,EAED,OAAO,OAASA,EAAU,QAEnB,IAAM,CACXgB,EAAa,EACbhB,EAAU,SAAS,UACnBA,EAAU,QAAU,OACpBE,EAAM,SAAS,CACb,OAAQ,IACV,CAAC,CACH,CACF,EAAG,CAAE,CAAA,EAELgB,EAEAC,EAAAA,EAAU,IAAM,CACd,MAAMC,EAAuBC,GAAuC,CAClE,KAAM,CAAE,SAAAC,EAAU,QAAAC,EAAS,cAAAC,EAAe,cAAAC,EAAe,QAAAC,EAAU,EAAG,KAAAC,CAAK,EAAIzB,EAAM,SAAS,EAO9F,GAJAmB,EAAI,EAAE,iBACNA,EAAI,EAAE,kBAGDA,EAAI,EAAU,cAAgB,EAGnC,IAAIA,EAAI,EAAE,SAAYA,EAAI,EAAU,cAAgB,OAAW,CAE7D,GAAI,CAACC,EAAU,OAGf,MAAMM,EADQP,EAAI,EAAE,OACO,EAAI,IAAO,KAEtC,IAAIQ,EADsBF,EAAOD,EACOE,EAEpCC,EAAgBL,IAAeK,EAAgBL,GAC/CK,EAAgBJ,IAAeI,EAAgBJ,GAEnD,MAAMK,EAAeD,EAAgBH,EAErC1B,EAAU,SAAS,YAAY,IAAI+B,EAAMV,EAAI,EAAE,QAASA,EAAI,EAAE,OAAO,EAAGS,CAAY,EAEpF5B,EAAM,SAAS,CACb,WAAY2B,EACZ,KAAMC,CACR,CAAC,CACH,KAAO,CACL,GAAI,CAACP,EAAS,OAGd,MAAMS,EAAoB,IACpBC,EAAQ,IAAIF,EAAM,CAACV,EAAI,EAAE,OAASW,EAAmB,CAACX,EAAI,EAAE,OAASW,CAAiB,EAC5FhC,EAAU,SAAS,YAAYiC,CAAK,CACtC,CAEAnC,IAAeuB,CAAG,CAAA,CACpB,EAEA,OAAArB,EAAU,SAAS,GAAG,cAAeoB,CAAmB,EAEjD,IAAM,CACXpB,EAAU,SAAS,IAAI,cAAeoB,CAAmB,CAC3D,CACF,EAAG,CAACtB,EAAcI,CAAK,CAAC,EAExBiB,EAAU,IAAM,CACdjB,EAAM,SAAS,CACb,QAASI,EAAO,SAAS,QAAQ,eAAe,CAClD,CAAC,CACH,EAAG,CAACJ,CAAK,CAAC,EAEViB,EAAU,IAAM,CACVnB,EAAU,UACZA,EAAU,QAAQ,IAAIW,CAAU,EAChCX,EAAU,QAAQ,iBAAA,EAEtB,EAAG,CAACW,CAAU,CAAC,EAGbuB,EAAC,MAAA,CAAI,UAAU,uBAAuB,IAAK5B,EAAQ,MAAOX,EACxD,UAAAwC,EAAC,SAAA,CAAO,IAAK/B,CAAc,CAAA,EAC1BP,EACAU,EAAS,IAAI6B,GACZD,EAAC,MAEC,CAAA,GAAIC,EAAQ,GACZ,MAAO,CACL,SAAU,UACZ,EACA,UAAW,yBAAyBA,EAAQ,SAAS,GACrD,IAAKA,EAAQ,IAEZ,SAAAA,EAAQ,QARJA,EAAAA,EAAQ,EASf,CACD,CAAA,CAAA,CACH,CAEJ"}
@@ -1,2 +1,2 @@
1
- "use client";import{IText as r,Point as p,util as u}from"fabric";import{forwardRef as f,useImperativeHandle as d,memo as c}from"react";import{useCreateObject as h}from"../../hooks/useCreateObject.mjs";import{useSplitProps as l}from"../../hooks/useSplitProps.mjs";import{useInstancePosition as g}from"../../hooks/useInstancePosition.mjs";r.prototype.set({_getNonTransformedDimensions(){return new p(this.width,this.height).scalarAdd(this.padding)},_calculateCurrentDimensions(){return u.transformPoint(this._getTransformedDimensions(),this.getViewportTransform(),!0)}});const w=f(({group:e,text:o,children:s,...i},n)=>{const[a,m]=l(i),t=h({Constructor:r,param:o,attributes:m,group:e,listeners:a});return d(n,()=>t,[t]),g(t,s)});var x=c(w);export{x as default};
1
+ "use client";import{IText as r,Point as p,util as u}from"fabric";import{forwardRef as f,useImperativeHandle as d,memo as c}from"react";import{useCreateObject as h}from"../../hooks/useCreateObject.mjs";import{useSplitProps as l}from"../../hooks/useSplitProps.mjs";import{useInstancePosition as g}from"../../hooks/useInstancePosition.mjs";r.prototype.set({_getNonTransformedDimensions(){return new p(this.width,this.height).scalarAdd(this.padding)},_calculateCurrentDimensions(){return u.transformPoint(this._getTransformedDimensions(),this.getViewportTransform(),!0)}});const w=f(({group:e,text:o,children:s,...i},n)=>{const[a,m]=l(i),t=h({Constructor:r,param:o,attributes:m,group:e,listeners:a});return d(n,()=>t,[t]),g(t,s)});var P=c(w);export{P as default};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../../../src/components/IText/index.tsx"],"sourcesContent":["import type { Group as BaseGroup } from 'fabric'\nimport { IText, util, Point } from 'fabric'\nimport { forwardRef, memo, useImperativeHandle, type ReactNode } from 'react'\nimport { useCreateObject } from '../../hooks/useCreateObject'\nimport { useSplitProps } from '../../hooks/useSplitProps'\nimport type { AllObjectEvents } from '../../types/object'\nimport { useInstancePosition } from '../../hooks/useInstancePosition'\n\nexport type ITextProps<T = unknown> = Partial<ConstructorParameters<typeof IText>[1] & AllObjectEvents> & {\n group?: BaseGroup\n text: string\n children?: ReactNode\n} & T\n\nIText.prototype.set({\n _getNonTransformedDimensions() {\n // Object dimensions\n return new Point(this.width, this.height).scalarAdd(this.padding)\n },\n _calculateCurrentDimensions() {\n // Controls dimensions\n return util.transformPoint(this._getTransformedDimensions(), this.getViewportTransform(), true)\n },\n})\n\nconst ITextBox = forwardRef<IText | undefined, ITextProps>(({ group, text, children, ...props }, ref) => {\n const [listeners, attributes] = useSplitProps(props)\n\n const instance = useCreateObject({\n Constructor: IText,\n param: text,\n attributes,\n group,\n listeners,\n })\n\n useImperativeHandle(ref, () => instance, [instance])\n\n return useInstancePosition(instance, children)\n})\n\nexport default memo(ITextBox)\n"],"names":["IText","Point","util","ITextBox","forwardRef","group","text","children","props","ref","listeners","attributes","useSplitProps","instance","useCreateObject","useImperativeHandle","useInstancePosition","memo"],"mappings":"iVAcAA,EAAM,UAAU,IAAI,CAClB,8BAA+B,CAE7B,OAAO,IAAIC,EAAM,KAAK,MAAO,KAAK,MAAM,EAAE,UAAU,KAAK,OAAO,CAClE,EACA,6BAA8B,CAE5B,OAAOC,EAAK,eAAe,KAAK,4BAA6B,KAAK,uBAAwB,EAAI,CAChG,CACF,CAAC,EAED,MAAMC,EAAWC,EAA0C,CAAC,CAAE,MAAAC,EAAO,KAAAC,EAAM,SAAAC,EAAU,GAAGC,CAAM,EAAGC,IAAQ,CACvG,KAAM,CAACC,EAAWC,CAAU,EAAIC,EAAcJ,CAAK,EAE7CK,EAAWC,EAAgB,CAC/B,YAAad,EACb,MAAOM,EACP,WAAAK,EACA,MAAAN,EACA,UAAAK,CACF,CAAC,EAED,OAAAK,EAAoBN,EAAK,IAAMI,EAAU,CAACA,CAAQ,CAAC,EAE5CG,EAAoBH,EAAUN,CAAQ,CAC/C,CAAC,EAED,IAAA,EAAeU,EAAKd,CAAQ"}
1
+ {"version":3,"file":"index.mjs","sources":["../../../../src/components/IText/index.tsx"],"sourcesContent":["import type { Group as BaseGroup } from 'fabric'\nimport { IText, util, Point } from 'fabric'\nimport { forwardRef, memo, useImperativeHandle, type ReactNode } from 'react'\nimport { useCreateObject } from '../../hooks/useCreateObject'\nimport { useSplitProps } from '../../hooks/useSplitProps'\nimport type { AllObjectEvents } from '../../types/object'\nimport { useInstancePosition } from '../../hooks/useInstancePosition'\n\nexport type ITextProps<T = unknown> = Partial<ConstructorParameters<typeof IText>[1] & AllObjectEvents> & {\n group?: BaseGroup\n text: string\n children?: ReactNode\n} & T\n\nIText.prototype.set({\n _getNonTransformedDimensions() {\n // Object dimensions\n return new Point(this.width, this.height).scalarAdd(this.padding)\n },\n _calculateCurrentDimensions() {\n // Controls dimensions\n return util.transformPoint(this._getTransformedDimensions(), this.getViewportTransform(), true)\n },\n})\n\nconst ITextBox = forwardRef<IText | undefined, ITextProps>(({ group, text, children, ...props }, ref) => {\n const [listeners, attributes] = useSplitProps(props)\n\n const instance = useCreateObject({\n Constructor: IText,\n param: text,\n attributes,\n group,\n listeners,\n })\n\n useImperativeHandle(ref, () => instance, [instance])\n\n return useInstancePosition(instance, children)\n})\n\nexport default memo(ITextBox)\n"],"names":["IText","Point","util","ITextBox","forwardRef","group","text","children","props","ref","listeners","attributes","useSplitProps","instance","useCreateObject","useImperativeHandle","useInstancePosition","a","memo"],"mappings":"iVAcAA,EAAM,UAAU,IAAI,CAClB,8BAA+B,CAE7B,OAAO,IAAIC,EAAM,KAAK,MAAO,KAAK,MAAM,EAAE,UAAU,KAAK,OAAO,CAClE,EACA,6BAA8B,CAE5B,OAAOC,EAAK,eAAe,KAAK,4BAA6B,KAAK,uBAAwB,EAAI,CAChG,CACF,CAAC,EAED,MAAMC,EAAWC,EAA0C,CAAC,CAAE,MAAAC,EAAO,KAAAC,EAAM,SAAAC,EAAU,GAAGC,CAAM,EAAGC,IAAQ,CACvG,KAAM,CAACC,EAAWC,CAAU,EAAIC,EAAcJ,CAAK,EAE7CK,EAAWC,EAAgB,CAC/B,YAAad,EACb,MAAOM,EACP,WAAAK,EACA,MAAAN,EACA,UAAAK,CACF,CAAC,EAED,OAAAK,EAAoBN,EAAK,IAAMI,EAAU,CAACA,CAAQ,CAAC,EAE5CG,EAAoBH,EAAUN,CAAQ,CAC/C,CAAC,EAED,IAAAU,EAAeC,EAAKf,CAAQ"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../../../src/components/Objects/index.tsx"],"sourcesContent":["import { memo } from 'react'\nimport Path from '../Path'\nimport Text from '../Text'\nimport Rect from '../Rect'\nimport Line from '../Line'\nimport IText from '../IText'\n\nexport type ObjectsProps = {\n objects: { type: string;[index: string]: any }[]\n}\n\nconst Objects = ({ objects }: ObjectsProps) => {\n const components = {\n rect: Rect,\n path: Path,\n text: Text,\n line: Line,\n 'i-text': Text,\n itext: IText,\n }\n\n if (!objects) return null\n return (\n <>\n {objects?.map(({ type, ...options }) => {\n const Component = components[type.toLowerCase() as keyof typeof components]\n if (!Component) {\n return null\n }\n return <Component {...options} />\n })}\n </>\n )\n}\n\nexport default memo(Objects)\n"],"names":["Objects","objects","components","Rect","Path","Text","Line","IText","jsx","Fragment","type","options","Component","memo"],"mappings":"sQAWA,MAAMA,EAAU,CAAC,CAAE,QAAAC,CAAQ,IAAoB,CAC7C,MAAMC,EAAa,CACjB,KAAMC,EACN,KAAMC,EACN,KAAMC,EACN,KAAMC,EACN,SAAUD,EACV,MAAOE,CACT,EAEA,OAAKN,EAEHO,EAAAC,EAAA,CACG,SAAAR,GAAS,IAAI,CAAC,CAAE,KAAAS,EAAM,GAAGC,CAAQ,IAAM,CACtC,MAAMC,EAAYV,EAAWQ,EAAK,YAAwC,CAAA,EAC1E,OAAKE,EAGEJ,EAACI,EAAA,CAAW,GAAGD,EAAS,EAFtB,IAGX,CAAC,CACH,CAAA,EAVmB,IAYvB,EAEA,IAAeE,EAAAA,EAAKb,CAAO"}
1
+ {"version":3,"file":"index.mjs","sources":["../../../../src/components/Objects/index.tsx"],"sourcesContent":["import { memo } from 'react'\nimport Path from '../Path'\nimport Text from '../Text'\nimport Rect from '../Rect'\nimport Line from '../Line'\nimport IText from '../IText'\n\nexport type ObjectsProps = {\n objects: { type: string; [index: string]: any }[]\n}\n\nconst Objects = ({ objects }: ObjectsProps) => {\n const components = {\n rect: Rect,\n path: Path,\n text: Text,\n line: Line,\n 'i-text': Text,\n itext: IText,\n }\n\n if (!objects) return null\n return (\n <>\n {objects?.map(({ type, ...options }) => {\n const Component = components[type.toLowerCase() as keyof typeof components]\n if (!Component) {\n return null\n }\n return <Component {...(options as any)} />\n })}\n </>\n )\n}\n\nexport default memo(Objects)\n"],"names":["Objects","objects","components","Rect","Path","Text","Line","IText","jsx","Fragment","type","options","Component","memo"],"mappings":"sQAWA,MAAMA,EAAU,CAAC,CAAE,QAAAC,CAAQ,IAAoB,CAC7C,MAAMC,EAAa,CACjB,KAAMC,EACN,KAAMC,EACN,KAAMC,EACN,KAAMC,EACN,SAAUD,EACV,MAAOE,CACT,EAEA,OAAKN,EAEHO,EAAAC,EAAA,CACG,SAAAR,GAAS,IAAI,CAAC,CAAE,KAAAS,EAAM,GAAGC,CAAQ,IAAM,CACtC,MAAMC,EAAYV,EAAWQ,EAAK,YAAwC,CAAA,EAC1E,OAAKE,EAGEJ,EAACI,EAAA,CAAW,GAAID,EAAiB,EAF/B,IAGX,CAAC,CACH,CAAA,EAVmB,IAYvB,EAEA,IAAeE,EAAAA,EAAKb,CAAO"}
@@ -1,2 +1,2 @@
1
- "use client";import{FabricText as r,Point as l,util as p}from"fabric";import{forwardRef as d,useEffect as h,useImperativeHandle as F,memo as g}from"react";import{useCreateObject as y}from"../../hooks/useCreateObject.mjs";import{useSplitProps as w}from"../../hooks/useSplitProps.mjs";import{useStoreApi as D}from"../../hooks/useStore.mjs";import b from"fontfaceobserver";import{useInstancePosition as A}from"../../hooks/useInstancePosition.mjs";r.prototype.set({_getNonTransformedDimensions(){return new l(this.width,this.height).scalarAdd(this.padding)},_calculateCurrentDimensions(){return p.transformPoint(this._getTransformedDimensions(),this.getViewportTransform(),!0)}});const P=d(({group:o,text:i,children:n,...s},a)=>{const m=D(),[u,t]=w(s),e=y({Constructor:r,param:i,attributes:t,group:o,listeners:u});return h(()=>{const{canvas:f}=m.getState();!t.fontFamily||!e||new b(t.fontFamily).load().then(()=>{e.set({fontFamily:t.fontFamily}),f?.requestRenderAll()}).catch(c=>{console.error(`ReactFabric: \u5B57\u4F53\u52A0\u8F7D\u5931\u8D25: ${t.fontFamily}`,c)})},[t.fontFamily,e]),F(a,()=>e,[e]),A(e,n)});var T=g(P);export{T as default};
1
+ "use client";import{FabricText as r,Point as c,util as d}from"fabric";import{forwardRef as h,useEffect as F,useImperativeHandle as g,memo as y}from"react";import{useCreateObject as w}from"../../hooks/useCreateObject.mjs";import{useSplitProps as D}from"../../hooks/useSplitProps.mjs";import{useStoreApi as P}from"../../hooks/useStore.mjs";import T from"fontfaceobserver";import{useInstancePosition as b}from"../../hooks/useInstancePosition.mjs";r.prototype.set({_getNonTransformedDimensions(){return new c(this.width,this.height).scalarAdd(this.padding)},_calculateCurrentDimensions(){return d.transformPoint(this._getTransformedDimensions(),this.getViewportTransform(),!0)}});const o=h(({group:i,text:n,children:s,...a},m)=>{const u=P(),[f,t]=D(a),e=w({Constructor:r,param:n,attributes:t,group:i,listeners:f});return F(()=>{const{canvas:l}=u.getState();!t.fontFamily||!e||new T(t.fontFamily).load().then(()=>{e.set({fontFamily:t.fontFamily}),l?.requestRenderAll()}).catch(p=>{console.error(`ReactFabric: \u5B57\u4F53\u52A0\u8F7D\u5931\u8D25: ${t.fontFamily}`,p)})},[t.fontFamily,e]),g(m,()=>e,[e]),b(e,s)});o.displayName="Text";var x=y(o);export{x as default};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../../../src/components/Text/index.tsx"],"sourcesContent":["import type { Group as BaseGroup } from 'fabric'\nimport { FabricText, Point, util } from 'fabric'\nimport { forwardRef, memo, useEffect, useImperativeHandle, type ReactNode } from 'react'\nimport { useCreateObject } from '../../hooks/useCreateObject'\nimport { useSplitProps } from '../../hooks/useSplitProps'\nimport { useStoreApi } from '../../hooks/useStore'\nimport type { AllObjectEvents } from '../../types/object'\nimport FontFaceObserver from 'fontfaceobserver'\nimport { useInstancePosition } from '../../hooks/useInstancePosition'\n\nexport type Handle = FabricText | undefined\n\nexport type TextProps<T = unknown> = Partial<ConstructorParameters<typeof FabricText>[1] & AllObjectEvents> & {\n group?: BaseGroup\n text: string\n children?: ReactNode\n} & T\n\nFabricText.prototype.set({\n _getNonTransformedDimensions() {\n // Object dimensions\n return new Point(this.width, this.height).scalarAdd(this.padding)\n },\n _calculateCurrentDimensions() {\n // Controls dimensions\n return util.transformPoint(this._getTransformedDimensions(), this.getViewportTransform(), true)\n },\n})\n\nconst Text = forwardRef<Handle, TextProps>(({ group, text, children, ...props }, ref) => {\n const store = useStoreApi()\n\n const [listeners, attributes] = useSplitProps(props)\n\n const instance = useCreateObject({\n Constructor: FabricText,\n param: text,\n attributes,\n group,\n listeners,\n })\n\n /**\n * 字体只有被使用了才会加载;先由 Text 使用一次, 监听加载完成,之后再 set 一次\n */\n useEffect(() => {\n const { canvas } = store.getState()\n if (!attributes.fontFamily || !instance) return\n const font = new FontFaceObserver(attributes.fontFamily)\n font\n .load()\n .then(() => {\n instance.set({\n fontFamily: attributes.fontFamily,\n })\n canvas?.requestRenderAll()\n })\n .catch(error => {\n // 加载失败\n console.error(`ReactFabric: 字体加载失败: ${attributes.fontFamily}`, error)\n })\n }, [attributes.fontFamily, instance])\n\n useImperativeHandle(ref, () => instance, [instance])\n return useInstancePosition(instance, children)\n})\n\nexport default memo(Text)\n"],"names":["FabricText","Point","util","Text","forwardRef","group","text","children","props","ref","store","useStoreApi","listeners","attributes","useSplitProps","instance","useCreateObject","useEffect","canvas","FontFaceObserver","error","useImperativeHandle","useInstancePosition","memo"],"mappings":"4bAkBAA,EAAW,UAAU,IAAI,CACvB,8BAA+B,CAE7B,OAAO,IAAIC,EAAM,KAAK,MAAO,KAAK,MAAM,EAAE,UAAU,KAAK,OAAO,CAClE,EACA,6BAA8B,CAE5B,OAAOC,EAAK,eAAe,KAAK,4BAA6B,KAAK,qBAAwB,EAAA,EAAI,CAChG,CACF,CAAC,EAED,MAAMC,EAAOC,EAA8B,CAAC,CAAE,MAAAC,EAAO,KAAAC,EAAM,SAAAC,EAAU,GAAGC,CAAM,EAAGC,IAAQ,CACvF,MAAMC,EAAQC,EAAY,EAEpB,CAACC,EAAWC,CAAU,EAAIC,EAAcN,CAAK,EAE7CO,EAAWC,EAAgB,CAC/B,YAAahB,EACb,MAAOM,EACP,WAAAO,EACA,MAAAR,EACA,UAAAO,CACF,CAAC,EAKD,OAAAK,EAAU,IAAM,CACd,KAAM,CAAE,OAAAC,CAAO,EAAIR,EAAM,SAAS,EAC9B,CAACG,EAAW,YAAc,CAACE,GAClB,IAAII,EAAiBN,EAAW,UAAU,EAEpD,OACA,KAAK,IAAM,CACVE,EAAS,IAAI,CACX,WAAYF,EAAW,UACzB,CAAC,EACDK,GAAQ,iBAAiB,CAC3B,CAAC,EACA,MAAME,GAAS,CAEd,QAAQ,MAAM,sDAAwBP,EAAW,UAAU,GAAIO,CAAK,CACtE,CAAC,CACL,EAAG,CAACP,EAAW,WAAYE,CAAQ,CAAC,EAEpCM,EAAoBZ,EAAK,IAAMM,EAAU,CAACA,CAAQ,CAAC,EAC5CO,EAAoBP,EAAUR,CAAQ,CAC/C,CAAC,EAED,IAAegB,EAAAA,EAAKpB,CAAI"}
1
+ {"version":3,"file":"index.mjs","sources":["../../../../src/components/Text/index.tsx"],"sourcesContent":["import type { Group as BaseGroup } from 'fabric'\nimport { FabricText, Point, util } from 'fabric'\nimport { forwardRef, memo, useEffect, useImperativeHandle, type ReactNode } from 'react'\nimport { useCreateObject } from '../../hooks/useCreateObject'\nimport { useSplitProps } from '../../hooks/useSplitProps'\nimport { useStoreApi } from '../../hooks/useStore'\nimport type { AllObjectEvents } from '../../types/object'\nimport FontFaceObserver from 'fontfaceobserver'\nimport { useInstancePosition } from '../../hooks/useInstancePosition'\n\nexport type Handle = FabricText | undefined\n\nexport type TextProps<T = unknown> = Partial<FabricText & AllObjectEvents> & {\n group?: BaseGroup\n text: string\n children?: ReactNode\n} & T\n\nFabricText.prototype.set({\n _getNonTransformedDimensions() {\n // Object dimensions\n return new Point(this.width, this.height).scalarAdd(this.padding)\n },\n _calculateCurrentDimensions() {\n // Controls dimensions\n return util.transformPoint(this._getTransformedDimensions(), this.getViewportTransform(), true)\n },\n})\n\nconst Text = forwardRef<Handle, TextProps>(({ group, text, children, ...props }, ref) => {\n const store = useStoreApi()\n\n const [listeners, attributes] = useSplitProps(props)\n\n const instance = useCreateObject({\n Constructor: FabricText,\n param: text,\n attributes,\n group,\n listeners,\n })\n\n /**\n * 字体只有被使用了才会加载;先由 Text 使用一次, 监听加载完成,之后再 set 一次\n */\n useEffect(() => {\n const { canvas } = store.getState()\n if (!attributes.fontFamily || !instance) return\n const font = new FontFaceObserver(attributes.fontFamily)\n font\n .load()\n .then(() => {\n instance.set({\n fontFamily: attributes.fontFamily,\n })\n canvas?.requestRenderAll()\n })\n .catch(error => {\n // 加载失败\n console.error(`ReactFabric: 字体加载失败: ${attributes.fontFamily}`, error)\n })\n }, [attributes.fontFamily, instance])\n\n useImperativeHandle(ref, () => instance, [instance])\n return useInstancePosition(instance, children)\n})\n\nText.displayName = 'Text'\nexport default memo(Text)\n"],"names":["FabricText","Point","util","Text","forwardRef","group","text","children","props","ref","store","useStoreApi","listeners","attributes","useSplitProps","instance","useCreateObject","useEffect","canvas","FontFaceObserver","error","useImperativeHandle","useInstancePosition","memo"],"mappings":"4bAkBAA,EAAW,UAAU,IAAI,CACvB,8BAA+B,CAE7B,OAAO,IAAIC,EAAM,KAAK,MAAO,KAAK,MAAM,EAAE,UAAU,KAAK,OAAO,CAClE,EACA,6BAA8B,CAE5B,OAAOC,EAAK,eAAe,KAAK,4BAA6B,KAAK,qBAAA,EAAwB,EAAI,CAChG,CACF,CAAC,EAED,MAAMC,EAAOC,EAA8B,CAAC,CAAE,MAAAC,EAAO,KAAAC,EAAM,SAAAC,EAAU,GAAGC,CAAM,EAAGC,IAAQ,CACvF,MAAMC,EAAQC,IAER,CAACC,EAAWC,CAAU,EAAIC,EAAcN,CAAK,EAE7CO,EAAWC,EAAgB,CAC/B,YAAahB,EACb,MAAOM,EACP,WAAAO,EACA,MAAAR,EACA,UAAAO,CACF,CAAC,EAKD,OAAAK,EAAU,IAAM,CACd,KAAM,CAAE,OAAAC,CAAO,EAAIR,EAAM,SAAA,EACrB,CAACG,EAAW,YAAc,CAACE,GAClB,IAAII,EAAiBN,EAAW,UAAU,EAEpD,KAAK,EACL,KAAK,IAAM,CACVE,EAAS,IAAI,CACX,WAAYF,EAAW,UACzB,CAAC,EACDK,GAAQ,iBACV,CAAA,CAAC,EACA,MAAME,GAAS,CAEd,QAAQ,MAAM,sDAAwBP,EAAW,UAAU,GAAIO,CAAK,CACtE,CAAC,CACL,EAAG,CAACP,EAAW,WAAYE,CAAQ,CAAC,EAEpCM,EAAoBZ,EAAK,IAAMM,EAAU,CAACA,CAAQ,CAAC,EAC5CO,EAAoBP,EAAUR,CAAQ,CAC/C,CAAC,EAEDJ,EAAK,YAAc,OACnB,IAAeoB,EAAAA,EAAKpB,CAAI"}
@@ -1,2 +1,2 @@
1
- "use client";import{jsx as e,jsxs as v}from"react/jsx-runtime";import{forwardRef as D,memo as N}from"react";import{Wrapper as y}from"./Wrapper.mjs";import z from"../../components/Canvas/index.mjs";import{StoreUpdater as S}from"../../components/StoreUpdater/index.mjs";import U from"../../components/Loading/index.mjs";const W={width:"100%",height:"100%",overflow:"hidden",position:"relative",zIndex:0},j=D(({minManualZoom:a,maxManualZoom:l,className:n,children:t,width:r,height:i,selection:m,style:s,onMouseWheel:d,onMouseDown:u,onMouseMove:f,onMouseUp:c,zoomable:h,panAble:p,defaultSelection:M,defaultCentered:b,defaultDraggable:g,manualZoom:w,...x},Z)=>e("div",{style:{...W,...s},ref:Z,className:`react-fabric ${n||""}`,children:v(y,{width:r,height:i,children:[e(S,{minManualZoom:a,maxManualZoom:l,zoomable:h,panAble:p,defaultCentered:b,selection:m,defaultSelection:M,defaultDraggable:g,manualZoom:w}),e(z,{onMouseDown:u,onMouseMove:f,onMouseUp:c,onMouseWheel:d,...x,children:t}),e(U,{})]})})),o=N(j);o.displayName="ReactFabric";export{o as default};
1
+ "use client";import{jsx as e,jsxs as v}from"react/jsx-runtime";import{forwardRef as D,memo as N}from"react";import{Wrapper as y}from"./Wrapper.mjs";import z from"../../components/Canvas/index.mjs";import{StoreUpdater as S}from"../../components/StoreUpdater/index.mjs";import U from"../../components/Loading/index.mjs";const W={width:"100%",height:"100%",overflow:"hidden",position:"relative",zIndex:0},j=D(({minManualZoom:l,maxManualZoom:n,className:r,children:i,width:o,height:a,selection:m,style:d,onMouseWheel:s,onMouseDown:u,onMouseMove:h,onMouseUp:f,zoomable:c,panAble:p,defaultSelection:M,defaultCentered:b,defaultDraggable:g,manualZoom:w,...x},Z)=>e("div",{style:{...W,...d},ref:Z,className:`react-fabric ${r||""}`,children:v(y,{width:o,height:a,children:[e(S,{minManualZoom:l,maxManualZoom:n,zoomable:c,panAble:p,defaultCentered:b,selection:m,defaultSelection:M,defaultDraggable:g,manualZoom:w,width:o,height:a}),e(z,{onMouseDown:u,onMouseMove:h,onMouseUp:f,onMouseWheel:s,...x,children:i}),e(U,{})]})})),t=N(j);t.displayName="ReactFabric";export{t as default};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../../../src/container/ReactFabric/index.tsx"],"sourcesContent":["import type { CSSProperties } from 'react'\nimport { forwardRef, memo } from 'react'\nimport { Wrapper } from './Wrapper'\nimport Canvas from '../../components/Canvas'\nimport { StoreUpdater } from '../../components/StoreUpdater'\nimport Loading from '../../components/Loading'\n\n// 自定义基础事件类型\ntype FabricEvent = {\n e: Event\n pointer: { x: number; y: number }\n target?: unknown\n subTargets?: unknown[]\n button?: number\n isClick?: boolean\n transform?: unknown\n}\n\n// 重新定义 CanvasProps,不再从 components/Canvas 导入\ntype BaseCanvasProps = {\n width?: number\n height?: number\n selection?: boolean\n children?: React.ReactNode\n // 添加其他必要的 Canvas 属性\n}\n\nconst wrapperStyle: CSSProperties = {\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n position: 'relative',\n zIndex: 0,\n}\n\nexport type ReactFabricProps = BaseCanvasProps & {\n style?: CSSProperties\n className?: string\n zoomable?: boolean\n panAble?: boolean\n manualZoom?: number\n minManualZoom?: number\n maxManualZoom?: number\n /** 背景图是否默认居中显示\n * @default false\n */\n defaultCentered?: boolean\n /** 是否启用选择功能\n * @default true\n * */\n defaultSelection?: boolean\n /**\n * 是否默认可拖拽\n */\n defaultDraggable?: boolean\n onMouseDown?: (e: FabricEvent) => void\n onMouseMove?: (e: FabricEvent) => void\n onMouseUp?: (e: FabricEvent) => void\n onMouseWheel?: (e: FabricEvent) => void\n}\n\nconst ForwardReactFabric = forwardRef<HTMLDivElement, ReactFabricProps>(\n (\n {\n minManualZoom,\n maxManualZoom,\n className,\n children,\n width,\n height,\n selection,\n style,\n onMouseWheel,\n onMouseDown,\n onMouseMove,\n onMouseUp,\n zoomable,\n panAble,\n defaultSelection,\n defaultCentered,\n defaultDraggable,\n manualZoom,\n ...rest\n },\n ref,\n ) => {\n return (\n <div style={{ ...wrapperStyle, ...style }} ref={ref} className={`react-fabric ${className || ''}`}>\n <Wrapper width={width} height={height}>\n <StoreUpdater\n minManualZoom={minManualZoom}\n maxManualZoom={maxManualZoom}\n zoomable={zoomable}\n panAble={panAble}\n defaultCentered={defaultCentered}\n selection={selection}\n defaultSelection={defaultSelection}\n defaultDraggable={defaultDraggable}\n manualZoom={manualZoom}\n />\n\n <Canvas\n onMouseDown={onMouseDown}\n onMouseMove={onMouseMove}\n onMouseUp={onMouseUp}\n onMouseWheel={onMouseWheel}\n {...rest}\n >\n {children}\n </Canvas>\n <Loading />\n </Wrapper>\n </div>\n )\n },\n)\n\ntype ReactFabricComponent = React.MemoExoticComponent<typeof ForwardReactFabric>\n\nconst ReactFabric: ReactFabricComponent = memo(ForwardReactFabric)\nReactFabric.displayName = 'ReactFabric'\n\nexport default ReactFabric\n"],"names":["wrapperStyle","ForwardReactFabric","forwardRef","minManualZoom","maxManualZoom","className","children","width","height","selection","style","onMouseWheel","onMouseDown","onMouseMove","onMouseUp","zoomable","panAble","defaultSelection","defaultCentered","defaultDraggable","manualZoom","rest","ref","jsx","jsxs","Wrapper","StoreUpdater","Canvas","Loading","ReactFabric","memo"],"mappings":"oUA2BMA,EAA8B,CAClC,MAAO,OACP,OAAQ,OACR,SAAU,SACV,SAAU,WACV,OAAQ,CACV,EA4BMC,EAAqBC,EACzB,CACE,CACE,cAAAC,EACA,cAAAC,EACA,UAAAC,EACA,SAAAC,EACA,MAAAC,EACA,OAAAC,EACA,UAAAC,EACA,MAAAC,EACA,aAAAC,EACA,YAAAC,EACA,YAAAC,EACA,UAAAC,EACA,SAAAC,EACA,QAAAC,EACA,iBAAAC,EACA,gBAAAC,EACA,iBAAAC,EACA,WAAAC,EACA,GAAGC,CACL,EACAC,IAGEC,EAAC,MAAA,CAAI,MAAO,CAAE,GAAGvB,EAAc,GAAGU,CAAM,EAAG,IAAKY,EAAK,UAAW,gBAAgBjB,GAAa,EAAE,GAC7F,SAAAmB,EAACC,EAAA,CAAQ,MAAOlB,EAAO,OAAQC,EAC7B,UAAAe,EAACG,EAAA,CACC,cAAevB,EACf,cAAeC,EACf,SAAUW,EACV,QAASC,EACT,gBAAiBE,EACjB,UAAWT,EACX,iBAAkBQ,EAClB,iBAAkBE,EAClB,WAAYC,EACd,EAEAG,EAACI,EAAA,CACC,YAAaf,EACb,YAAaC,EACb,UAAWC,EACX,aAAcH,EACb,GAAGU,EAEH,SAAAf,CACH,CAAA,EACAiB,EAACK,EAAA,CAAA,CAAQ,CACX,CAAA,CAAA,CAAA,CACF,CAGN,EAIMC,EAAoCC,EAAK7B,CAAkB,EACjE4B,EAAY,YAAc"}
1
+ {"version":3,"file":"index.mjs","sources":["../../../../src/container/ReactFabric/index.tsx"],"sourcesContent":["import type { CSSProperties } from 'react'\nimport { forwardRef, memo } from 'react'\nimport { Wrapper } from './Wrapper'\nimport Canvas, { type CanvasProps } from '../../components/Canvas'\nimport { StoreUpdater } from '../../components/StoreUpdater'\nimport Loading from '../../components/Loading'\n\n// 重新定义 CanvasProps,不再从 components/Canvas 导入\ntype BaseCanvasProps = {\n width?: number\n height?: number\n selection?: boolean\n children?: React.ReactNode\n // 添加其他必要的 Canvas 属性\n}\n\nconst wrapperStyle: CSSProperties = {\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n position: 'relative',\n zIndex: 0,\n}\n\nexport type ReactFabricProps = BaseCanvasProps &\n CanvasProps & {\n style?: CSSProperties\n className?: string\n zoomable?: boolean\n panAble?: boolean\n manualZoom?: number\n minManualZoom?: number\n maxManualZoom?: number\n /** 背景图是否默认居中显示\n * @default false\n */\n defaultCentered?: boolean\n /** 是否启用选择功能\n * @default true\n * */\n defaultSelection?: boolean\n /**\n * 是否默认可拖拽\n */\n defaultDraggable?: boolean\n }\n\nconst ForwardReactFabric = forwardRef<HTMLDivElement, ReactFabricProps>(\n (\n {\n minManualZoom,\n maxManualZoom,\n className,\n children,\n width,\n height,\n selection,\n style,\n onMouseWheel,\n onMouseDown,\n onMouseMove,\n onMouseUp,\n zoomable,\n panAble,\n defaultSelection,\n defaultCentered,\n defaultDraggable,\n manualZoom,\n ...rest\n },\n ref,\n ) => {\n return (\n <div style={{ ...wrapperStyle, ...style }} ref={ref} className={`react-fabric ${className || ''}`}>\n <Wrapper width={width} height={height}>\n <StoreUpdater\n minManualZoom={minManualZoom}\n maxManualZoom={maxManualZoom}\n zoomable={zoomable}\n panAble={panAble}\n defaultCentered={defaultCentered}\n selection={selection}\n defaultSelection={defaultSelection}\n defaultDraggable={defaultDraggable}\n manualZoom={manualZoom}\n width={width}\n height={height}\n />\n\n <Canvas\n onMouseDown={onMouseDown}\n onMouseMove={onMouseMove}\n onMouseUp={onMouseUp}\n onMouseWheel={onMouseWheel}\n {...rest}\n >\n {children}\n </Canvas>\n <Loading />\n </Wrapper>\n </div>\n )\n },\n)\n\ntype ReactFabricComponent = React.MemoExoticComponent<typeof ForwardReactFabric>\n\nconst ReactFabric: ReactFabricComponent = memo(ForwardReactFabric)\nReactFabric.displayName = 'ReactFabric'\n\nexport default ReactFabric\n"],"names":["wrapperStyle","ForwardReactFabric","forwardRef","minManualZoom","maxManualZoom","className","children","width","height","selection","style","onMouseWheel","onMouseDown","onMouseMove","onMouseUp","zoomable","panAble","defaultSelection","defaultCentered","defaultDraggable","manualZoom","rest","ref","jsx","jsxs","Wrapper","StoreUpdater","Canvas","Loading","ReactFabric","memo"],"mappings":"8TAgBA,MAAMA,EAA8B,CAClC,MAAO,OACP,OAAQ,OACR,SAAU,SACV,SAAU,WACV,OAAQ,CACV,EAyBMC,EAAqBC,EACzB,CACE,CACE,cAAAC,EACA,cAAAC,EACA,UAAAC,EACA,SAAAC,EACA,MAAAC,EACA,OAAAC,EACA,UAAAC,EACA,MAAAC,EACA,aAAAC,EACA,YAAAC,EACA,YAAAC,EACA,UAAAC,EACA,SAAAC,EACA,QAAAC,EACA,iBAAAC,EACA,gBAAAC,EACA,iBAAAC,EACA,WAAAC,EACA,GAAGC,CACL,EACAC,IAGEC,EAAC,OAAI,MAAO,CAAE,GAAGvB,EAAc,GAAGU,CAAM,EAAG,IAAKY,EAAK,UAAW,gBAAgBjB,GAAa,EAAE,GAC7F,SAAAmB,EAACC,EAAA,CAAQ,MAAOlB,EAAO,OAAQC,EAC7B,SAAA,CAAAe,EAACG,EAAA,CACC,cAAevB,EACf,cAAeC,EACf,SAAUW,EACV,QAASC,EACT,gBAAiBE,EACjB,UAAWT,EACX,iBAAkBQ,EAClB,iBAAkBE,EAClB,WAAYC,EACZ,MAAOb,EACP,OAAQC,CACV,CAAA,EAEAe,EAACI,EAAA,CACC,YAAaf,EACb,YAAaC,EACb,UAAWC,EACX,aAAcH,EACb,GAAGU,EAEH,SAAAf,CACH,CAAA,EACAiB,EAACK,EAAA,CAAQ,CAAA,CACX,CAAA,CAAA,CAAA,CACF,CAGN,EAIMC,EAAoCC,EAAK7B,CAAkB,EACjE4B,EAAY,YAAc"}
@@ -1,6 +1,8 @@
1
1
  import type { BasicTransformEvent, ImageProps, ObjectEvents, SerializedImageProps, TPointerEvent } from 'fabric';
2
2
  import { FabricImage } from 'fabric';
3
- export type Handle = {};
3
+ export type Handle = {
4
+ instance: FabricImage | null;
5
+ };
4
6
  type ScaleMode = {
5
7
  scaleToFit?: boolean;
6
8
  scaleToCover?: boolean;
@@ -9,11 +11,13 @@ export type BackgroundImageProps = Partial<ImageProps> & {
9
11
  src: string;
10
12
  onLoad?: (imageSource: FabricImage<Partial<ImageProps>, SerializedImageProps, ObjectEvents>) => void;
11
13
  onScaling?: (scale: BasicTransformEvent<TPointerEvent>) => void;
14
+ onError?: (e: any) => void;
12
15
  } & ScaleMode;
13
16
  declare const _default: import("react").MemoExoticComponent<import("react").ForwardRefExoticComponent<Partial<ImageProps> & {
14
17
  src: string;
15
18
  onLoad?: (imageSource: FabricImage<Partial<ImageProps>, SerializedImageProps, ObjectEvents>) => void;
16
19
  onScaling?: (scale: BasicTransformEvent<TPointerEvent>) => void;
20
+ onError?: (e: any) => void;
17
21
  } & ScaleMode & import("react").RefAttributes<Handle>>>;
18
22
  export default _default;
19
23
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/BackgroundImage/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,UAAU,EACV,YAAY,EACZ,oBAAoB,EAEpB,aAAa,EACd,MAAM,QAAQ,CAAA;AACf,OAAO,EAAE,WAAW,EAAQ,MAAM,QAAQ,CAAA;AAM1C,MAAM,MAAM,MAAM,GAAG,EAAE,CAAA;AAEvB,KAAK,SAAS,GAAG;IACf,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB,CAAA;AACD,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG;IACvD,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,oBAAoB,EAAE,YAAY,CAAC,KAAK,IAAI,CAAA;IACpG,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,mBAAmB,CAAC,aAAa,CAAC,KAAK,IAAI,CAAA;CAGhE,GAAG,SAAS,CAAA;;SALN,MAAM;aACF,CAAC,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,oBAAoB,EAAE,YAAY,CAAC,KAAK,IAAI;gBACxF,CAAC,KAAK,EAAE,mBAAmB,CAAC,aAAa,CAAC,KAAK,IAAI;;AA8LjE,wBAAoC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/BackgroundImage/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,UAAU,EACV,YAAY,EACZ,oBAAoB,EAEpB,aAAa,EACd,MAAM,QAAQ,CAAA;AACf,OAAO,EAAE,WAAW,EAAQ,MAAM,QAAQ,CAAA;AAM1C,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAA;CAC7B,CAAA;AAED,KAAK,SAAS,GAAG;IACf,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB,CAAA;AACD,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG;IACvD,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,oBAAoB,EAAE,YAAY,CAAC,KAAK,IAAI,CAAA;IACpG,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,mBAAmB,CAAC,aAAa,CAAC,KAAK,IAAI,CAAA;IAC/D,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,IAAI,CAAA;CAG3B,GAAG,SAAS,CAAA;;SANN,MAAM;aACF,CAAC,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,oBAAoB,EAAE,YAAY,CAAC,KAAK,IAAI;gBACxF,CAAC,KAAK,EAAE,mBAAmB,CAAC,aAAa,CAAC,KAAK,IAAI;cACrD,CAAC,CAAC,EAAE,GAAG,KAAK,IAAI;;AAmM5B,wBAAoC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/Canvas/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,aAAa,EAAqB,MAAM,QAAQ,CAAA;AAE5E,OAAO,KAAK,EAAiB,iBAAiB,EAAE,MAAM,OAAO,CAAA;AAM7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAYzD,KAAK,gBAAgB,GAAG;KACrB,CAAC,IAAI,MAAM,eAAe,GAAG,eAAe,CAAC,CAAC,CAAC;CACjD,CAAA;AAGD,KAAK,iBAAiB,GAAG,IAAI,CAAC,aAAa,EAAE,MAAM,gBAAgB,CAAC,CAAA;AAGpE,MAAM,MAAM,WAAW,GAAG,iBAAiB,CAAC,OAAO,CAAC,iBAAiB,CAAC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAA;AAEnG,QAAA,MAAM,MAAM,yCAA0C,WAAW,4CA0HhE,CAAA;AAED,eAAe,MAAM,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/Canvas/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,aAAa,EAAqB,MAAM,QAAQ,CAAA;AAE5E,OAAO,KAAK,EAAiB,iBAAiB,EAAE,MAAM,OAAO,CAAA;AAM7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAYzD,KAAK,gBAAgB,GAAG;KACrB,CAAC,IAAI,MAAM,eAAe,GAAG,eAAe,CAAC,CAAC,CAAC;CACjD,CAAA;AAGD,KAAK,iBAAiB,GAAG,IAAI,CAAC,aAAa,EAAE,MAAM,gBAAgB,CAAC,CAAA;AAGpE,MAAM,MAAM,WAAW,GAAG,iBAAiB,CAAC,OAAO,CAAC,iBAAiB,CAAC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAA;AAEnG,QAAA,MAAM,MAAM,yCAA0C,WAAW,4CAyHhE,CAAA;AAED,eAAe,MAAM,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/Objects/index.tsx"],"names":[],"mappings":"AAOA,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAA,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,EAAE,CAAA;CACjD,CAAA;0EAE6B,YAAY;AAwB1C,wBAA4B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/Objects/index.tsx"],"names":[],"mappings":"AAOA,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,EAAE,CAAA;CAClD,CAAA;0EAE6B,YAAY;AAwB1C,wBAA4B"}
@@ -3,11 +3,15 @@ import { FabricText } from 'fabric';
3
3
  import { type ReactNode } from 'react';
4
4
  import type { AllObjectEvents } from '../../types/object';
5
5
  export type Handle = FabricText | undefined;
6
- export type TextProps<T = unknown> = Partial<ConstructorParameters<typeof FabricText>[1] & AllObjectEvents> & {
6
+ export type TextProps<T = unknown> = Partial<FabricText & AllObjectEvents> & {
7
7
  group?: BaseGroup;
8
8
  text: string;
9
9
  children?: ReactNode;
10
10
  } & T;
11
- declare const _default: import("react").MemoExoticComponent<import("react").ForwardRefExoticComponent<Omit<TextProps<unknown>, "ref"> & import("react").RefAttributes<Handle>>>;
11
+ declare const _default: import("react").MemoExoticComponent<import("react").ForwardRefExoticComponent<Partial<FabricText<Partial<import("fabric").TextProps>, import("fabric").SerializedTextProps, import("fabric").ObjectEvents> & AllObjectEvents> & {
12
+ group?: BaseGroup;
13
+ text: string;
14
+ children?: ReactNode;
15
+ } & import("react").RefAttributes<Handle>>>;
12
16
  export default _default;
13
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/Text/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,QAAQ,CAAA;AAChD,OAAO,EAAE,UAAU,EAAe,MAAM,QAAQ,CAAA;AAChD,OAAO,EAAoD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAIxF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAIzD,MAAM,MAAM,MAAM,GAAG,UAAU,GAAG,SAAS,CAAA;AAE3C,MAAM,MAAM,SAAS,CAAC,CAAC,GAAG,OAAO,IAAI,OAAO,CAAC,qBAAqB,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,GAAG;IAC5G,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB,GAAG,CAAC,CAAA;;AAmDL,wBAAyB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/Text/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,QAAQ,CAAA;AAChD,OAAO,EAAE,UAAU,EAAe,MAAM,QAAQ,CAAA;AAChD,OAAO,EAAoD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAIxF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAIzD,MAAM,MAAM,MAAM,GAAG,UAAU,GAAG,SAAS,CAAA;AAE3C,MAAM,MAAM,SAAS,CAAC,CAAC,GAAG,OAAO,IAAI,OAAO,CAAC,UAAU,GAAG,eAAe,CAAC,GAAG;IAC3E,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB,GAAG,CAAC,CAAA;;YAHK,SAAS;UACX,MAAM;eACD,SAAS;;AAqDtB,wBAAyB"}
@@ -1,23 +1,12 @@
1
1
  import type { CSSProperties } from 'react';
2
- type FabricEvent = {
3
- e: Event;
4
- pointer: {
5
- x: number;
6
- y: number;
7
- };
8
- target?: unknown;
9
- subTargets?: unknown[];
10
- button?: number;
11
- isClick?: boolean;
12
- transform?: unknown;
13
- };
2
+ import { type CanvasProps } from '../../components/Canvas';
14
3
  type BaseCanvasProps = {
15
4
  width?: number;
16
5
  height?: number;
17
6
  selection?: boolean;
18
7
  children?: React.ReactNode;
19
8
  };
20
- export type ReactFabricProps = BaseCanvasProps & {
9
+ export type ReactFabricProps = BaseCanvasProps & CanvasProps & {
21
10
  style?: CSSProperties;
22
11
  className?: string;
23
12
  zoomable?: boolean;
@@ -37,12 +26,110 @@ export type ReactFabricProps = BaseCanvasProps & {
37
26
  * 是否默认可拖拽
38
27
  */
39
28
  defaultDraggable?: boolean;
40
- onMouseDown?: (e: FabricEvent) => void;
41
- onMouseMove?: (e: FabricEvent) => void;
42
- onMouseUp?: (e: FabricEvent) => void;
43
- onMouseWheel?: (e: FabricEvent) => void;
44
29
  };
45
- declare const ForwardReactFabric: import("react").ForwardRefExoticComponent<BaseCanvasProps & {
30
+ declare const ForwardReactFabric: import("react").ForwardRefExoticComponent<BaseCanvasProps & Partial<{
31
+ width: number;
32
+ height: number;
33
+ selection: boolean;
34
+ hoverCursor: CSSStyleDeclaration["cursor"];
35
+ moveCursor: CSSStyleDeclaration["cursor"];
36
+ perPixelTargetFind: boolean;
37
+ clipPath?: import("fabric").FabricObject | undefined;
38
+ includeDefaultValues: boolean;
39
+ backgroundColor: import("fabric").TFiller | string;
40
+ centeredRotation: boolean;
41
+ centeredScaling: boolean;
42
+ containerClass: string;
43
+ preserveObjectStacking: boolean;
44
+ controlsAboveOverlay: boolean;
45
+ allowTouchScrolling: boolean;
46
+ viewportTransform: import("fabric").TMat2D;
47
+ backgroundVpt: boolean;
48
+ backgroundImage?: import("fabric").FabricObject | undefined;
49
+ overlayVpt: boolean;
50
+ overlayColor: import("fabric").TFiller | string;
51
+ overlayImage?: import("fabric").FabricObject | undefined;
52
+ renderOnAddRemove: boolean;
53
+ skipOffscreen: boolean;
54
+ enableRetinaScaling: boolean;
55
+ imageSmoothingEnabled: boolean;
56
+ svgViewportTransformation: boolean;
57
+ uniformScaling: boolean;
58
+ uniScaleKey: import("fabric").TOptionalModifierKey;
59
+ centeredKey: import("fabric").TOptionalModifierKey;
60
+ altActionKey: import("fabric").TOptionalModifierKey;
61
+ selectionKey: import("fabric").TOptionalModifierKey | import("fabric").ModifierKey[];
62
+ altSelectionKey: import("fabric").TOptionalModifierKey;
63
+ selectionColor: string;
64
+ selectionDashArray: number[];
65
+ selectionBorderColor: string;
66
+ selectionLineWidth: number;
67
+ selectionFullyContained: boolean;
68
+ defaultCursor: CSSStyleDeclaration["cursor"];
69
+ freeDrawingCursor: CSSStyleDeclaration["cursor"];
70
+ notAllowedCursor: CSSStyleDeclaration["cursor"];
71
+ targetFindTolerance: number;
72
+ skipTargetFind: boolean;
73
+ stopContextMenu: boolean;
74
+ fireRightClick: boolean;
75
+ fireMiddleClick: boolean;
76
+ enablePointerEvents: boolean;
77
+ }> & Partial<{
78
+ onBeforePathCreated: (opt: import("../../types/canvas").FabricPublicEvent) => void;
79
+ onPathCreated: (opt: import("../../types/canvas").FabricPublicEvent) => void;
80
+ onErasingStart: (opt: import("../../types/canvas").FabricPublicEvent) => void;
81
+ onErasingEnd: (opt: import("../../types/canvas").FabricPublicEvent) => void;
82
+ onTextSelectionChanged: (opt: import("../../types/canvas").FabricPublicEvent) => void;
83
+ onTextChanged: (opt: import("../../types/canvas").FabricPublicEvent) => void;
84
+ onTextEditingEntered: (opt: import("../../types/canvas").FabricPublicEvent) => void;
85
+ onTextEditingExited: (opt: import("../../types/canvas").FabricPublicEvent) => void;
86
+ onCanvasCleared: (opt: import("../../types/canvas").FabricPublicEvent) => void;
87
+ onBeforeRender: (opt: import("../../types/canvas").FabricPublicEvent) => void;
88
+ onAfterRender: (opt: import("../../types/canvas").FabricPublicEvent) => void;
89
+ onObjectLayoutBefore: (opt: import("../../types/canvas").FabricPublicEvent) => void;
90
+ onObjectLayoutAfter: (opt: import("../../types/canvas").FabricPublicEvent) => void;
91
+ onObjectAdded: (opt: import("../../types/canvas").FabricPublicEvent) => void;
92
+ onObjectRemoved: (opt: import("../../types/canvas").FabricPublicEvent) => void;
93
+ onMouseDown: (opt: import("../../types/canvas").FabricPublicEvent) => void;
94
+ onMouseDownBefore: (opt: import("../../types/canvas").FabricPublicEvent) => void;
95
+ onMouseMove: (opt: import("../../types/canvas").FabricPublicEvent) => void;
96
+ onMouseMoveBefore: (opt: import("../../types/canvas").FabricPublicEvent) => void;
97
+ onMouseDblclick: (opt: import("../../types/canvas").FabricPublicEvent) => void;
98
+ onMouseTripleclick: (opt: import("../../types/canvas").FabricPublicEvent) => void;
99
+ onMouseUp: (opt: import("../../types/canvas").FabricPublicEvent) => void;
100
+ onMouseUpBefore: (opt: import("../../types/canvas").FabricPublicEvent) => void;
101
+ onMouseWheel: (opt: import("../../types/canvas").FabricPublicEvent) => void;
102
+ onMouseOver: (opt: import("../../types/canvas").FabricPublicEvent) => void;
103
+ onMouseOut: (opt: import("../../types/canvas").FabricPublicEvent) => void;
104
+ onDragEnter: (opt: import("../../types/canvas").FabricPublicEvent) => void;
105
+ onDragLeave: (opt: import("../../types/canvas").FabricPublicEvent) => void;
106
+ onDragstart: (opt: import("../../types/canvas").FabricPublicEvent) => void;
107
+ onDrag: (opt: import("../../types/canvas").FabricPublicEvent) => void;
108
+ onDragover: (opt: import("../../types/canvas").FabricPublicEvent) => void;
109
+ onDragenter: (opt: import("../../types/canvas").FabricPublicEvent) => void;
110
+ onDragleave: (opt: import("../../types/canvas").FabricPublicEvent) => void;
111
+ onDragend: (opt: import("../../types/canvas").FabricPublicEvent) => void;
112
+ onDropBefore: (opt: import("../../types/canvas").FabricPublicEvent) => void;
113
+ onDrop: (opt: import("../../types/canvas").FabricPublicEvent) => void;
114
+ onDropAfter: (opt: import("../../types/canvas").FabricPublicEvent) => void;
115
+ onContextmenuBefore: (opt: import("../../types/canvas").FabricPublicEvent) => void;
116
+ onContextmenu: (opt: import("../../types/canvas").FabricPublicEvent) => void;
117
+ onBeforeTransform: (opt: import("../../types/canvas").FabricPublicEvent) => void;
118
+ onObjectMoving: (opt: import("../../types/canvas").FabricPublicEvent) => void;
119
+ onObjectScaling: (opt: import("../../types/canvas").FabricPublicEvent) => void;
120
+ onObjectRotating: (opt: import("../../types/canvas").FabricPublicEvent) => void;
121
+ onObjectSkewing: (opt: import("../../types/canvas").FabricPublicEvent) => void;
122
+ onObjectResizing: (opt: import("../../types/canvas").FabricPublicEvent) => void;
123
+ onObjectModifyPoly: (opt: import("../../types/canvas").FabricPublicEvent) => void;
124
+ onObjectModifyPath: (opt: import("../../types/canvas").FabricPublicEvent) => void;
125
+ onObjectModified: (opt: import("../../types/canvas").FabricPublicEvent) => void;
126
+ onSelectionCreated: (opt: import("../../types/canvas").FabricPublicEvent) => void;
127
+ onSelectionUpdated: (opt: import("../../types/canvas").FabricPublicEvent) => void;
128
+ onBeforeSelectionCleared: (opt: import("../../types/canvas").FabricPublicEvent) => void;
129
+ onSelectionCleared: (opt: import("../../types/canvas").FabricPublicEvent) => void;
130
+ }> & {
131
+ children?: import("react").ReactNode | undefined;
132
+ } & {
46
133
  style?: CSSProperties;
47
134
  className?: string;
48
135
  zoomable?: boolean;
@@ -62,10 +149,6 @@ declare const ForwardReactFabric: import("react").ForwardRefExoticComponent<Base
62
149
  * 是否默认可拖拽
63
150
  */
64
151
  defaultDraggable?: boolean;
65
- onMouseDown?: (e: FabricEvent) => void;
66
- onMouseMove?: (e: FabricEvent) => void;
67
- onMouseUp?: (e: FabricEvent) => void;
68
- onMouseWheel?: (e: FabricEvent) => void;
69
152
  } & import("react").RefAttributes<HTMLDivElement>>;
70
153
  type ReactFabricComponent = React.MemoExoticComponent<typeof ForwardReactFabric>;
71
154
  declare const ReactFabric: ReactFabricComponent;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/container/ReactFabric/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAQ1C,KAAK,WAAW,GAAG;IACjB,CAAC,EAAE,KAAK,CAAA;IACR,OAAO,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACjC,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,UAAU,CAAC,EAAE,OAAO,EAAE,CAAA;IACtB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAGD,KAAK,eAAe,GAAG;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAE3B,CAAA;AAUD,MAAM,MAAM,gBAAgB,GAAG,eAAe,GAAG;IAC/C,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB;;UAEM;IACN,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B;;OAEG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,KAAK,IAAI,CAAA;IACtC,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,KAAK,IAAI,CAAA;IACtC,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,KAAK,IAAI,CAAA;IACpC,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,KAAK,IAAI,CAAA;CACxC,CAAA;AAED,QAAA,MAAM,kBAAkB;YAzBd,aAAa;gBACT,MAAM;eACP,OAAO;cACR,OAAO;iBACJ,MAAM;oBACH,MAAM;oBACN,MAAM;IACtB;;OAEG;sBACe,OAAO;IACzB;;UAEM;uBACa,OAAO;IAC1B;;OAEG;uBACgB,OAAO;kBACZ,CAAC,CAAC,EAAE,WAAW,KAAK,IAAI;kBACxB,CAAC,CAAC,EAAE,WAAW,KAAK,IAAI;gBAC1B,CAAC,CAAC,EAAE,WAAW,KAAK,IAAI;mBACrB,CAAC,CAAC,EAAE,WAAW,KAAK,IAAI;kDAyDxC,CAAA;AAED,KAAK,oBAAoB,GAAG,KAAK,CAAC,mBAAmB,CAAC,OAAO,kBAAkB,CAAC,CAAA;AAEhF,QAAA,MAAM,WAAW,EAAE,oBAA+C,CAAA;AAGlE,eAAe,WAAW,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/container/ReactFabric/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAG1C,OAAe,EAAE,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAKlE,KAAK,eAAe,GAAG;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAE3B,CAAA;AAUD,MAAM,MAAM,gBAAgB,GAAG,eAAe,GAC5C,WAAW,GAAG;IACZ,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB;;UAEM;IACN,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B;;OAEG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B,CAAA;AAEH,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YArBZ,aAAa;gBACT,MAAM;eACP,OAAO;cACR,OAAO;iBACJ,MAAM;oBACH,MAAM;oBACN,MAAM;IACtB;;OAEG;sBACe,OAAO;IACzB;;UAEM;uBACa,OAAO;IAC1B;;OAEG;uBACgB,OAAO;kDA2D7B,CAAA;AAED,KAAK,oBAAoB,GAAG,KAAK,CAAC,mBAAmB,CAAC,OAAO,kBAAkB,CAAC,CAAA;AAEhF,QAAA,MAAM,WAAW,EAAE,oBAA+C,CAAA;AAGlE,eAAe,WAAW,CAAA"}
@@ -1,4 +1,4 @@
1
- import type { CanvasEvents } from 'fabric';
1
+ import type { CanvasEvents, TPointerEvent, TPointerEventInfo } from 'fabric';
2
2
  import type { MyCapitalize } from './utils';
3
3
  export type RawEventNames<Events extends Record<string, any>> = {
4
4
  [K in keyof Events]: MyCapitalize<K & string>;
@@ -7,8 +7,9 @@ type InvertedEventType<T extends Record<string, string>> = {
7
7
  [P in keyof T as T[P]]: P;
8
8
  };
9
9
  type InvertedEventNames<Events extends Record<string, any>> = InvertedEventType<RawEventNames<Events>>;
10
+ export type FabricPublicEvent = TPointerEventInfo<TPointerEvent | MouseEvent | WheelEvent | TouchEvent>;
10
11
  export type AllEvents<Events extends Record<string, any>> = {
11
- [K in keyof InvertedEventNames<Events>]: (opt: Events[InvertedEventNames<Events>[K] & keyof Events]) => void;
12
+ [K in keyof InvertedEventNames<Events>]: (opt: FabricPublicEvent) => void;
12
13
  };
13
14
  export type AllCanvasEvents = AllEvents<CanvasEvents>;
14
15
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"canvas.d.ts","sourceRoot":"","sources":["../../../src/types/canvas.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAE3C,MAAM,MAAM,aAAa,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI;KAC7D,CAAC,IAAI,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,GAAG,MAAM,CAAC;CAC9C,CAAA;AAGD,KAAK,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI;KACxD,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;CAC1B,CAAA;AAGD,KAAK,kBAAkB,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,iBAAiB,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAA;AAGtG,MAAM,MAAM,SAAS,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI;KACzD,CAAC,IAAI,MAAM,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,MAAM,CAAC,KAAK,IAAI;CAC7G,CAAA;AAGD,MAAM,MAAM,eAAe,GAAG,SAAS,CAAC,YAAY,CAAC,CAAA"}
1
+ {"version":3,"file":"canvas.d.ts","sourceRoot":"","sources":["../../../src/types/canvas.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAA;AAC5E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAE3C,MAAM,MAAM,aAAa,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI;KAC7D,CAAC,IAAI,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,GAAG,MAAM,CAAC;CAC9C,CAAA;AAGD,KAAK,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI;KACxD,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;CAC1B,CAAA;AAGD,KAAK,kBAAkB,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,iBAAiB,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAA;AAGtG,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,CAAC,CAAA;AAGvG,MAAM,MAAM,SAAS,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI;KACzD,CAAC,IAAI,MAAM,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,iBAAiB,KAAK,IAAI;CAC1E,CAAA;AAGD,MAAM,MAAM,eAAe,GAAG,SAAS,CAAC,YAAY,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cs-open/react-fabric",
3
3
  "type": "module",
4
- "version": "0.0.13",
4
+ "version": "1.0.0",
5
5
  "description": "React Fabric",
6
6
  "keywords": [
7
7
  "@cs-open/react-fabric",
@@ -14,12 +14,12 @@
14
14
  ],
15
15
  "repository": {
16
16
  "type": "git",
17
- "url": "https://github.com/cs-open/react-fabric.git",
17
+ "url": "https://github.com/vaynevayne/react-fabric.git",
18
18
  "directory": "packages/react"
19
19
  },
20
- "homepage": "https://cs-open.github.io/react-fabric/",
20
+ "homepage": "https://vaynevayne.github.io/react-fabric/",
21
21
  "bugs": {
22
- "url": "https://github.com/cs-open/react-fabric/issues"
22
+ "url": "https://github.com/vaynevayne/react-fabric/issues"
23
23
  },
24
24
  "files": [
25
25
  "dist"
@@ -50,7 +50,7 @@
50
50
  "peerDependencies": {
51
51
  "@floating-ui/core": "^1.6.9",
52
52
  "@floating-ui/react": "^0.27.16",
53
- "fabric": "^6.6.1",
53
+ "fabric": ">=6.6.1",
54
54
  "react": ">=17.0.0",
55
55
  "react-dom": ">=17.0.0",
56
56
  "use-sync-external-store": "^1.4.0",
@@ -88,16 +88,16 @@
88
88
  "typescript-eslint": "^8.17.0",
89
89
  "use-sync-external-store": "^1.4.0",
90
90
  "zustand": "^4.0.0 || ^5.0.0",
91
- "@cs-open/rollup-config": "0.0.10",
92
- "@cs-open/tsconfig": "0.0.10",
93
- "@cs-open/eslint-config": "0.0.10"
91
+ "@cs-open/eslint-config": "1.0.0",
92
+ "@cs-open/rollup-config": "1.0.0",
93
+ "@cs-open/tsconfig": "1.0.0"
94
94
  },
95
95
  "dependencies": {
96
96
  "es-toolkit": "^1.39.10",
97
97
  "fontfaceobserver": "^2.3.0"
98
98
  },
99
99
  "scripts": {
100
- "dev": "concurrently \"rollup --config node:@cs-open/rollup-config --watch\" \"pnpm typecheck\"",
100
+ "dev": "concurrently \"rollup --config node:@cs-open/rollup-config --watch\" \"pnpm tsc --watch\"",
101
101
  "build": "rimraf dist && concurrently \"rollup --config node:@cs-open/rollup-config --environment NODE_ENV:production\" \"pnpm tsc\"",
102
102
  "tsc": "tsc -p tsconfig.json --declaration true --emitDeclarationOnly --declarationDir dist/types",
103
103
  "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",