@cs-open/react-fabric 0.0.6 → 0.0.8
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.
- package/README.md +132 -0
- package/dist/cjs/components/BackgroundImage/index.cjs +1 -1
- package/dist/cjs/components/BackgroundImage/index.cjs.map +1 -1
- package/dist/cjs/components/Canvas/index.cjs +1 -1
- package/dist/cjs/components/Canvas/index.cjs.map +1 -1
- package/dist/cjs/components/Control/index.cjs +1 -1
- package/dist/cjs/components/Control/index.cjs.map +1 -1
- package/dist/cjs/components/Control2/index.cjs +2 -0
- package/dist/cjs/components/Control2/index.cjs.map +1 -0
- package/dist/cjs/components/Ellipse/index.cjs +1 -1
- package/dist/cjs/components/Ellipse/index.cjs.map +1 -1
- package/dist/cjs/components/Group/index.cjs +1 -1
- package/dist/cjs/components/Group/index.cjs.map +1 -1
- package/dist/cjs/components/IText/index.cjs +2 -0
- package/dist/cjs/components/IText/index.cjs.map +1 -0
- package/dist/cjs/components/Image/index.cjs +1 -1
- package/dist/cjs/components/Image/index.cjs.map +1 -1
- package/dist/cjs/components/Line/index.cjs +1 -1
- package/dist/cjs/components/Line/index.cjs.map +1 -1
- package/dist/cjs/components/Loading/index.cjs +11 -0
- package/dist/cjs/components/Loading/index.cjs.map +1 -0
- package/dist/cjs/components/NodeToolbarPortal/index.cjs +1 -1
- package/dist/cjs/components/NodeToolbarPortal/index.cjs.map +1 -1
- package/dist/cjs/components/Objects/index.cjs +1 -1
- package/dist/cjs/components/Objects/index.cjs.map +1 -1
- package/dist/cjs/components/Path/index.cjs +1 -1
- package/dist/cjs/components/Path/index.cjs.map +1 -1
- package/dist/cjs/components/Polyline/index.cjs +2 -0
- package/dist/cjs/components/Polyline/index.cjs.map +1 -0
- package/dist/cjs/components/ReactFabricProvider.cjs +1 -1
- package/dist/cjs/components/Rect/index.cjs +1 -1
- package/dist/cjs/components/Rect/index.cjs.map +1 -1
- package/dist/cjs/components/StoreUpdater/index.cjs +1 -1
- package/dist/cjs/components/StoreUpdater/index.cjs.map +1 -1
- package/dist/cjs/components/Text/index.cjs +1 -1
- package/dist/cjs/components/Text/index.cjs.map +1 -1
- package/dist/cjs/components/Textbox/index.cjs +2 -0
- package/dist/cjs/components/Textbox/index.cjs.map +1 -0
- package/dist/cjs/components/WavyLine/index.cjs +2 -0
- package/dist/cjs/components/WavyLine/index.cjs.map +1 -0
- package/dist/cjs/container/ReactFabric/index.cjs +1 -1
- package/dist/cjs/container/ReactFabric/index.cjs.map +1 -1
- package/dist/cjs/hooks/useCreateObject.cjs +1 -1
- package/dist/cjs/hooks/useCreateObject.cjs.map +1 -1
- package/dist/cjs/hooks/useDidUpdate.cjs +1 -1
- package/dist/cjs/hooks/useDraggable.cjs +1 -1
- package/dist/cjs/hooks/useInstancePosition.cjs +2 -0
- package/dist/cjs/hooks/useInstancePosition.cjs.map +1 -0
- package/dist/cjs/hooks/useReactFabric.cjs +1 -1
- package/dist/cjs/hooks/useReactFabric.cjs.map +1 -1
- package/dist/cjs/hooks/useResizeHandler.cjs +1 -1
- package/dist/cjs/hooks/useResizeHandler.cjs.map +1 -1
- package/dist/cjs/hooks/useSplitProps.cjs +1 -1
- package/dist/cjs/hooks/useStore.cjs +1 -1
- package/dist/cjs/hooks/useStore.cjs.map +1 -1
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/plugins/FreeDraw.cjs +2 -0
- package/dist/cjs/plugins/FreeDraw.cjs.map +1 -0
- package/dist/cjs/plugins/FreeRect.cjs +1 -1
- package/dist/cjs/plugins/FreeText.cjs +2 -0
- package/dist/cjs/plugins/FreeText.cjs.map +1 -0
- package/dist/cjs/plugins/Mask.cjs +2 -0
- package/dist/cjs/plugins/Mask.cjs.map +1 -0
- package/dist/cjs/plugins/Pinch.cjs +1 -1
- package/dist/cjs/plugins/Pinch.cjs.map +1 -1
- package/dist/cjs/plugins/index.cjs +2 -0
- package/dist/cjs/plugins/index.cjs.map +1 -0
- package/dist/cjs/store/index.cjs +1 -1
- package/dist/cjs/store/index.cjs.map +1 -1
- package/dist/cjs/store/initialState.cjs +1 -1
- package/dist/cjs/store/initialState.cjs.map +1 -1
- package/dist/cjs/utils/business.cjs +2 -0
- package/dist/cjs/utils/business.cjs.map +1 -0
- package/dist/cjs/utils/childrenWithPosition.cjs +2 -0
- package/dist/cjs/utils/childrenWithPosition.cjs.map +1 -0
- package/dist/esm/components/BackgroundImage/index.mjs +1 -1
- package/dist/esm/components/BackgroundImage/index.mjs.map +1 -1
- package/dist/esm/components/Canvas/index.mjs +1 -1
- package/dist/esm/components/Canvas/index.mjs.map +1 -1
- package/dist/esm/components/Control/index.mjs +1 -1
- package/dist/esm/components/Control/index.mjs.map +1 -1
- package/dist/esm/components/Control2/index.mjs +2 -0
- package/dist/esm/components/Control2/index.mjs.map +1 -0
- package/dist/esm/components/Ellipse/index.mjs +1 -1
- package/dist/esm/components/Ellipse/index.mjs.map +1 -1
- package/dist/esm/components/Group/index.mjs.map +1 -1
- package/dist/esm/components/IText/index.mjs +2 -0
- package/dist/esm/components/IText/index.mjs.map +1 -0
- package/dist/esm/components/Image/index.mjs +2 -0
- package/dist/esm/components/Image/index.mjs.map +1 -0
- package/dist/esm/components/Line/index.mjs +1 -1
- package/dist/esm/components/Line/index.mjs.map +1 -1
- package/dist/esm/components/Loading/index.mjs +11 -0
- package/dist/esm/components/Loading/index.mjs.map +1 -0
- package/dist/esm/components/NodeToolbarPortal/index.mjs +1 -1
- package/dist/esm/components/NodeToolbarPortal/index.mjs.map +1 -1
- package/dist/esm/components/Objects/index.mjs +1 -1
- package/dist/esm/components/Objects/index.mjs.map +1 -1
- package/dist/esm/components/Path/index.mjs +1 -1
- package/dist/esm/components/Path/index.mjs.map +1 -1
- package/dist/esm/components/Rect/index.mjs +1 -1
- package/dist/esm/components/Rect/index.mjs.map +1 -1
- package/dist/esm/components/StoreUpdater/index.mjs +1 -1
- package/dist/esm/components/StoreUpdater/index.mjs.map +1 -1
- package/dist/esm/components/Text/index.mjs +1 -1
- package/dist/esm/components/Text/index.mjs.map +1 -1
- package/dist/esm/components/Textbox/index.mjs +2 -0
- package/dist/esm/components/Textbox/index.mjs.map +1 -0
- package/dist/esm/components/WavyLine/index.mjs +2 -0
- package/dist/esm/components/WavyLine/index.mjs.map +1 -0
- package/dist/esm/container/ReactFabric/index.mjs +1 -1
- package/dist/esm/container/ReactFabric/index.mjs.map +1 -1
- package/dist/esm/hooks/useCreateObject.mjs.map +1 -1
- package/dist/esm/hooks/useInstancePosition.mjs +2 -0
- package/dist/esm/hooks/useInstancePosition.mjs.map +1 -0
- package/dist/esm/hooks/useReactFabric.mjs +1 -1
- package/dist/esm/hooks/useReactFabric.mjs.map +1 -1
- package/dist/esm/hooks/useResizeHandler.mjs +1 -1
- package/dist/esm/hooks/useResizeHandler.mjs.map +1 -1
- package/dist/esm/hooks/useStore.mjs +1 -1
- package/dist/esm/hooks/useStore.mjs.map +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/plugins/FreeDraw.mjs +2 -0
- package/dist/esm/plugins/FreeDraw.mjs.map +1 -0
- package/dist/esm/plugins/FreeText.mjs +2 -0
- package/dist/esm/plugins/FreeText.mjs.map +1 -0
- package/dist/esm/plugins/Pinch.mjs +1 -1
- package/dist/esm/plugins/Pinch.mjs.map +1 -1
- package/dist/esm/store/index.mjs +1 -1
- package/dist/esm/store/index.mjs.map +1 -1
- package/dist/esm/store/initialState.mjs +1 -1
- package/dist/esm/store/initialState.mjs.map +1 -1
- package/dist/esm/utils/business.mjs +2 -0
- package/dist/esm/utils/business.mjs.map +1 -0
- package/dist/esm/utils/childrenWithPosition.mjs +2 -0
- package/dist/esm/utils/childrenWithPosition.mjs.map +1 -0
- package/dist/esm/utils/constants.mjs +1 -1
- package/dist/esm/utils/constants.mjs.map +1 -1
- package/dist/esm/utils/dom.mjs +2 -0
- package/dist/esm/utils/dom.mjs.map +1 -0
- package/dist/esm/utils/position.mjs +2 -0
- package/dist/esm/utils/position.mjs.map +1 -0
- package/dist/esm/utils/props.mjs +1 -1
- package/dist/esm/utils/props.mjs.map +1 -1
- package/dist/types/components/BackgroundImage/index.d.ts.map +1 -1
- package/dist/types/components/Canvas/index.d.ts.map +1 -1
- package/dist/types/components/Control/index.d.ts.map +1 -1
- package/dist/types/components/Control2/index.d.ts +28 -0
- package/dist/types/components/Control2/index.d.ts.map +1 -0
- package/dist/types/components/Ellipse/index.d.ts +3 -0
- package/dist/types/components/Ellipse/index.d.ts.map +1 -1
- package/dist/types/components/Group/index.d.ts.map +1 -1
- package/dist/types/components/IText/index.d.ts +12 -0
- package/dist/types/components/IText/index.d.ts.map +1 -0
- package/dist/types/components/Image/index.d.ts +4 -4
- package/dist/types/components/Image/index.d.ts.map +1 -1
- package/dist/types/components/Line/index.d.ts +2 -0
- package/dist/types/components/Line/index.d.ts.map +1 -1
- package/dist/types/components/Loading/index.d.ts +3 -0
- package/dist/types/components/Loading/index.d.ts.map +1 -0
- package/dist/types/components/NodeToolbarPortal/index.d.ts.map +1 -1
- package/dist/types/components/Objects/index.d.ts.map +1 -1
- package/dist/types/components/Path/index.d.ts +2 -0
- package/dist/types/components/Path/index.d.ts.map +1 -1
- package/dist/types/components/Polyline/index.d.ts +12 -0
- package/dist/types/components/Polyline/index.d.ts.map +1 -0
- package/dist/types/components/Rect/index.d.ts +4 -2
- package/dist/types/components/Rect/index.d.ts.map +1 -1
- package/dist/types/components/StoreUpdater/index.d.ts +1 -1
- package/dist/types/components/StoreUpdater/index.d.ts.map +1 -1
- package/dist/types/components/Text/index.d.ts +2 -0
- package/dist/types/components/Text/index.d.ts.map +1 -1
- package/dist/types/components/Textbox/index.d.ts +12 -0
- package/dist/types/components/Textbox/index.d.ts.map +1 -0
- package/dist/types/components/WavyLine/index.d.ts +12 -0
- package/dist/types/components/WavyLine/index.d.ts.map +1 -0
- package/dist/types/container/ReactFabric/index.d.ts +4 -0
- package/dist/types/container/ReactFabric/index.d.ts.map +1 -1
- package/dist/types/hooks/useCreateObject.d.ts.map +1 -1
- package/dist/types/hooks/useInstancePosition.d.ts +12 -0
- package/dist/types/hooks/useInstancePosition.d.ts.map +1 -0
- package/dist/types/hooks/useReactFabric.d.ts +1 -1
- package/dist/types/hooks/useReactFabric.d.ts.map +1 -1
- package/dist/types/hooks/useResizeHandler.d.ts.map +1 -1
- package/dist/types/index.d.ts +13 -6
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/plugins/FreeDraw.d.ts +9 -0
- package/dist/types/plugins/FreeDraw.d.ts.map +1 -0
- package/dist/types/plugins/FreeText.d.ts +11 -0
- package/dist/types/plugins/FreeText.d.ts.map +1 -0
- package/dist/types/plugins/Mask.d.ts +8 -0
- package/dist/types/plugins/Mask.d.ts.map +1 -0
- package/dist/types/plugins/Pinch.d.ts +15 -3
- package/dist/types/plugins/Pinch.d.ts.map +1 -1
- package/dist/types/plugins/index.d.ts +7 -0
- package/dist/types/plugins/index.d.ts.map +1 -0
- package/dist/types/store/index.d.ts.map +1 -1
- package/dist/types/store/initialState.d.ts.map +1 -1
- package/dist/types/types/component-props.d.ts +0 -35
- package/dist/types/types/component-props.d.ts.map +1 -1
- package/dist/types/types/store.d.ts +13 -0
- package/dist/types/types/store.d.ts.map +1 -1
- package/dist/types/utils/business.d.ts +83 -0
- package/dist/types/utils/business.d.ts.map +1 -0
- package/dist/types/utils/childrenWithPosition.d.ts +6 -0
- package/dist/types/utils/childrenWithPosition.d.ts.map +1 -0
- package/package.json +22 -18
- package/dist/cjs/toolbar/Vertical/index.cjs +0 -2
- package/dist/cjs/toolbar/Vertical/index.cjs.map +0 -1
- package/dist/esm/toolbar/Vertical/index.mjs +0 -2
- package/dist/esm/toolbar/Vertical/index.mjs.map +0 -1
- package/dist/types/toolbar/Vertical/index.d.ts +0 -10
- package/dist/types/toolbar/Vertical/index.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../src/store/index.ts"],"sourcesContent":["import { createWithEqualityFn } from 'zustand/traditional'\nimport type { Node } from '../types/nodes'\nimport type { ReactFabricState } from '../types/store'\nimport getInitialState from './initialState'\n\nconst createStore = ({\n nodes,\n defaultNodes,\n width,\n height,\n}: {\n nodes?: Node[]\n defaultNodes?: Node[]\n width?: number\n height?: number\n}) =>\n createWithEqualityFn<ReactFabricState>(\n (set, get) => ({\n ...getInitialState({ nodes, width, height, defaultNodes }),\n setDimensions: (options: { width?: number; height?: number }) => {\n const { width, height } = options\n const currentState = get()\n\n // 合并现有尺寸和新尺寸\n const newDimensions = {\n width: width ?? currentState.width,\n height: height ?? currentState.height,\n }\n\n get().canvas?.setDimensions(newDimensions)\n set(newDimensions)\n },\n setLoading: loading => {\n set({ loading })\n },\n setDraggable: draggable => {\n set({ draggable })\n const canvas = get().canvas\n // TODO 无效\n if (canvas) {\n canvas.setCursor(draggable ? 'grab' : 'default')\n canvas.hoverCursor = draggable ? 'grab' : 'default'\n canvas.requestRenderAll()\n }\n },\n setZoomable: zoomable => {\n set({ zoomable })\n },\n\n setIsDragging: isDragging => {\n set({ isDragging })\n },\n setSelection: selection => {\n const canvas = get().canvas\n if (!canvas) return\n set({ selection })\n canvas.set('selection', selection)\n canvas.requestRenderAll()\n },\n setDefaultDraggable: defaultDraggable => {\n if (defaultDraggable === undefined) return\n const { setDraggable } = get()\n set({ hasDefaultDraggable: true })\n setDraggable(defaultDraggable)\n },\n setDefaultSelection: defaultSelection => {\n if (defaultSelection === undefined) return\n const { setSelection } = get()\n set({ hasDefaultSelection: true })\n setSelection(defaultSelection)\n },\n setFitZoom: (fitZoom: number) => {\n set({ fitZoom: fitZoom })\n },\n setManualZoom: (manualZoom: number) => {\n set({ manualZoom: manualZoom })\n },\n setMinManualZoom: (zoom: number) => {\n set({ minManualZoom: zoom })\n },\n setZoom: (zoom: number) => {\n set({ zoom: zoom })\n },\n setMaxManualZoom: (zoom: number) => {\n set({ maxManualZoom: zoom })\n },\n\n reset: () => set({ ...getInitialState() }),\n }),\n Object.is,\n )\n\nexport { createStore }\n"],"names":["createStore","nodes","defaultNodes","width","height","createWithEqualityFn","set","get","getInitialState","options","currentState","newDimensions","loading","draggable","canvas","zoomable","isDragging","selection","defaultDraggable","setDraggable","defaultSelection","setSelection","fitZoom","manualZoom","zoom"],"mappings":"kFAKMA,MAAAA,EAAc,CAAC,CACnB,MAAAC,EACA,aAAAC,EACA,MAAAC,EACA,OAAAC,CACF,IAMEC,
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../src/store/index.ts"],"sourcesContent":["import { createWithEqualityFn } from 'zustand/traditional'\nimport type { Node } from '../types/nodes'\nimport type { ReactFabricState } from '../types/store'\nimport getInitialState from './initialState'\n\nconst createStore = ({\n nodes,\n defaultNodes,\n width,\n height,\n}: {\n nodes?: Node[]\n defaultNodes?: Node[]\n width?: number\n height?: number\n}) =>\n createWithEqualityFn<ReactFabricState>(\n (set, get) => ({\n ...getInitialState({ nodes, width, height, defaultNodes }),\n setDimensions: (options: { width?: number; height?: number }) => {\n const { width, height } = options\n const currentState = get()\n\n // 合并现有尺寸和新尺寸\n const newDimensions = {\n width: width ?? currentState.width,\n height: height ?? currentState.height,\n }\n\n get().canvas?.setDimensions(newDimensions)\n set(newDimensions)\n },\n setLoading: loading => {\n set({ loading })\n },\n setDraggable: draggable => {\n set({ draggable })\n const canvas = get().canvas\n // TODO 无效\n if (canvas) {\n canvas.setCursor(draggable ? 'grab' : 'default')\n canvas.hoverCursor = draggable ? 'grab' : 'default'\n canvas.requestRenderAll()\n }\n },\n setZoomable: zoomable => {\n set({ zoomable })\n },\n\n setIsDragging: isDragging => {\n set({ isDragging })\n },\n setSelection: selection => {\n const canvas = get().canvas\n if (!canvas) return\n set({ selection })\n canvas.set('selection', selection)\n canvas.requestRenderAll()\n },\n setDefaultDraggable: defaultDraggable => {\n if (defaultDraggable === undefined) return\n const { setDraggable } = get()\n set({ hasDefaultDraggable: true })\n setDraggable(defaultDraggable)\n },\n setDefaultSelection: defaultSelection => {\n if (defaultSelection === undefined) return\n const { setSelection } = get()\n set({ hasDefaultSelection: true })\n setSelection(defaultSelection)\n },\n setFitZoom: (fitZoom: number) => {\n set({ fitZoom: fitZoom })\n },\n setManualZoom: (manualZoom: number) => {\n set({ manualZoom: manualZoom })\n },\n setMinManualZoom: (zoom: number) => {\n set({ minManualZoom: zoom })\n },\n setZoom: (zoom: number) => {\n set({ zoom: zoom })\n },\n setMaxManualZoom: (zoom: number) => {\n set({ maxManualZoom: zoom })\n },\n setControls: (controls) => {\n set({ controls })\n },\n reset: () => set({ ...getInitialState() }),\n }),\n Object.is,\n )\n\nexport { createStore }\n"],"names":["createStore","nodes","defaultNodes","width","height","createWithEqualityFn","set","get","getInitialState","options","currentState","newDimensions","loading","draggable","canvas","zoomable","isDragging","selection","defaultDraggable","setDraggable","defaultSelection","setSelection","fitZoom","manualZoom","zoom","controls"],"mappings":"kFAKMA,MAAAA,EAAc,CAAC,CACnB,MAAAC,EACA,aAAAC,EACA,MAAAC,EACA,OAAAC,CACF,IAMEC,EACE,qBAAA,CAACC,EAAKC,KAAS,CACb,GAAGC,EAAAA,QAAgB,CAAE,MAAAP,EAAO,MAAAE,EAAO,OAAAC,EAAQ,aAAAF,CAAa,CAAC,EACzD,cAAgBO,GAAiD,CAC/D,KAAM,CAAE,MAAAN,EAAO,OAAAC,CAAO,EAAIK,EACpBC,EAAeH,IAGfI,EAAgB,CACpB,MAAOR,GAASO,EAAa,MAC7B,OAAQN,GAAUM,EAAa,MACjC,EAEAH,EAAM,EAAA,QAAQ,cAAcI,CAAa,EACzCL,EAAIK,CAAa,CACnB,EACA,WAAYC,GAAW,CACrBN,EAAI,CAAE,QAAAM,CAAQ,CAAC,CACjB,EACA,aAAcC,GAAa,CACzBP,EAAI,CAAE,UAAAO,CAAU,CAAC,EACjB,MAAMC,EAASP,EAAAA,EAAM,OAEjBO,IACFA,EAAO,UAAUD,EAAY,OAAS,SAAS,EAC/CC,EAAO,YAAcD,EAAY,OAAS,UAC1CC,EAAO,mBAEX,EACA,YAAaC,GAAY,CACvBT,EAAI,CAAE,SAAAS,CAAS,CAAC,CAClB,EAEA,cAAeC,GAAc,CAC3BV,EAAI,CAAE,WAAAU,CAAW,CAAC,CACpB,EACA,aAAcC,GAAa,CACzB,MAAMH,EAASP,EAAI,EAAE,OAChBO,IACLR,EAAI,CAAE,UAAAW,CAAU,CAAC,EACjBH,EAAO,IAAI,YAAaG,CAAS,EACjCH,EAAO,mBACT,EACA,oBAAqBI,GAAoB,CACvC,GAAIA,IAAqB,OAAW,OACpC,KAAM,CAAE,aAAAC,CAAa,EAAIZ,EAAAA,EACzBD,EAAI,CAAE,oBAAqB,EAAK,CAAC,EACjCa,EAAaD,CAAgB,CAC/B,EACA,oBAAqBE,GAAoB,CACvC,GAAIA,IAAqB,OAAW,OACpC,KAAM,CAAE,aAAAC,CAAa,EAAId,EAAAA,EACzBD,EAAI,CAAE,oBAAqB,EAAK,CAAC,EACjCe,EAAaD,CAAgB,CAC/B,EACA,WAAaE,GAAoB,CAC/BhB,EAAI,CAAE,QAASgB,CAAQ,CAAC,CAC1B,EACA,cAAgBC,GAAuB,CACrCjB,EAAI,CAAE,WAAYiB,CAAW,CAAC,CAChC,EACA,iBAAmBC,GAAiB,CAClClB,EAAI,CAAE,cAAekB,CAAK,CAAC,CAC7B,EACA,QAAUA,GAAiB,CACzBlB,EAAI,CAAE,KAAMkB,CAAK,CAAC,CACpB,EACA,iBAAmBA,GAAiB,CAClClB,EAAI,CAAE,cAAekB,CAAK,CAAC,CAC7B,EACA,YAAcC,GAAa,CACzBnB,EAAI,CAAE,SAAAmB,CAAS,CAAC,CAClB,EACA,MAAO,IAAMnB,EAAI,CAAE,GAAGE,EAAgB,QAAA,CAAE,CAAC,CAC3C,GACA,OAAO,EACT"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});const d=({nodes:o,defaultNodes:e,defaultSelection:a,defaultDraggable:l}={})=>({width:200,height:200,canvas:null,nodes:e??o??[],onNodesChange:null,hasDefaultNodes:e!==void 0,hasDefaultSelection:a!==void 0,hasDefaultDraggable:l!==void 0,zoom:1,minManualZoom:.4,maxManualZoom:3,domNode:null,debug:!1,isDragging:!1,selection:a??!0,zoomable:!0,draggable:!1,scale:1,lastPosX:void 0,lastPosY:void 0,loading:!1,fitZoom:1,manualZoom:1,defaultCentered:!1});exports.default=d;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});const d=({nodes:o,defaultNodes:e,defaultSelection:a,defaultDraggable:l}={})=>({width:200,height:200,canvas:null,nodes:e??o??[],onNodesChange:null,hasDefaultNodes:e!==void 0,hasDefaultSelection:a!==void 0,hasDefaultDraggable:l!==void 0,zoom:1,minManualZoom:.4,maxManualZoom:3,domNode:null,debug:!1,isDragging:!1,selection:a??!0,zoomable:!0,panAble:!0,draggable:!1,scale:1,lastPosX:void 0,lastPosY:void 0,loading:!1,fitZoom:1,manualZoom:1,defaultCentered:!1,controls:[]});exports.default=d;
|
|
2
2
|
//# sourceMappingURL=initialState.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initialState.cjs","sources":["../../../src/store/initialState.ts"],"sourcesContent":["import type { Node } from '../types/nodes'\nimport type { ReactFabricStore } from '../types/store'\n\nconst getInitialState = ({\n nodes,\n defaultNodes,\n defaultSelection,\n defaultDraggable,\n}: {\n nodes?: Node[]\n defaultNodes?: Node[]\n width?: number\n defaultSelection?: boolean\n defaultDraggable?: boolean\n height?: number\n} = {}): ReactFabricStore => {\n const storeNodes = defaultNodes ?? nodes ?? []\n\n return {\n width: 200,\n height: 200,\n canvas: null,\n nodes: storeNodes,\n onNodesChange: null,\n hasDefaultNodes: defaultNodes !== undefined,\n hasDefaultSelection: defaultSelection !== undefined,\n hasDefaultDraggable: defaultDraggable !== undefined,\n zoom: 1,\n minManualZoom: 0.4,\n maxManualZoom: 3,\n domNode: null,\n debug: false,\n isDragging: false,\n selection: defaultSelection ?? true, // 必须跟着 fabric 默认值 true\n zoomable: true,\n draggable: false,\n scale: 1,\n lastPosX: undefined,\n lastPosY: undefined,\n loading: false,\n fitZoom: 1,\n manualZoom: 1,\n defaultCentered: false,\n }\n}\n\nexport default getInitialState\n"],"names":["getInitialState","nodes","defaultNodes","defaultSelection","defaultDraggable"],"mappings":"oEAGA,MAAMA,EAAkB,CAAC,CACvB,MAAAC,EACA,aAAAC,EACA,iBAAAC,EACA,iBAAAC,CACF,EAOI,CAAA,KAGK,CACL,MAAO,IACP,OAAQ,IACR,OAAQ,KACR,MANiBF,GAAgBD,GAAS,CAAA,EAO1C,cAAe,KACf,gBAAiBC,IAAiB,OAClC,oBAAqBC,IAAqB,OAC1C,oBAAqBC,IAAqB,OAC1C,KAAM,EACN,cAAe,GACf,cAAe,EACf,QAAS,KACT,MAAO,GACP,WAAY,GACZ,UAAWD,GAAoB,GAC/B,SAAU,GACV,UAAW,GACX,MAAO,EACP,SAAU,OACV,SAAU,OACV,QAAS,GACT,QAAS,EACT,WAAY,EACZ,gBAAiB,
|
|
1
|
+
{"version":3,"file":"initialState.cjs","sources":["../../../src/store/initialState.ts"],"sourcesContent":["import type { Node } from '../types/nodes'\nimport type { ReactFabricStore } from '../types/store'\n\nconst getInitialState = ({\n nodes,\n defaultNodes,\n defaultSelection,\n defaultDraggable,\n}: {\n nodes?: Node[]\n defaultNodes?: Node[]\n width?: number\n defaultSelection?: boolean\n defaultDraggable?: boolean\n height?: number\n} = {}): ReactFabricStore => {\n const storeNodes = defaultNodes ?? nodes ?? []\n\n return {\n width: 200,\n height: 200,\n canvas: null,\n nodes: storeNodes,\n onNodesChange: null,\n hasDefaultNodes: defaultNodes !== undefined,\n hasDefaultSelection: defaultSelection !== undefined,\n hasDefaultDraggable: defaultDraggable !== undefined,\n zoom: 1,\n minManualZoom: 0.4,\n maxManualZoom: 3,\n domNode: null,\n debug: false,\n isDragging: false,\n selection: defaultSelection ?? true, // 必须跟着 fabric 默认值 true\n zoomable: true,\n panAble: true,\n draggable: false,\n scale: 1,\n lastPosX: undefined,\n lastPosY: undefined,\n loading: false,\n fitZoom: 1,\n manualZoom: 1,\n defaultCentered: false,\n controls: []\n }\n}\n\nexport default getInitialState\n"],"names":["getInitialState","nodes","defaultNodes","defaultSelection","defaultDraggable"],"mappings":"oEAGA,MAAMA,EAAkB,CAAC,CACvB,MAAAC,EACA,aAAAC,EACA,iBAAAC,EACA,iBAAAC,CACF,EAOI,CAAA,KAGK,CACL,MAAO,IACP,OAAQ,IACR,OAAQ,KACR,MANiBF,GAAgBD,GAAS,CAAA,EAO1C,cAAe,KACf,gBAAiBC,IAAiB,OAClC,oBAAqBC,IAAqB,OAC1C,oBAAqBC,IAAqB,OAC1C,KAAM,EACN,cAAe,GACf,cAAe,EACf,QAAS,KACT,MAAO,GACP,WAAY,GACZ,UAAWD,GAAoB,GAC/B,SAAU,GACV,QAAS,GACT,UAAW,GACX,MAAO,EACP,SAAU,OACV,SAAU,OACV,QAAS,GACT,QAAS,EACT,WAAY,EACZ,gBAAiB,GACjB,SAAU,EACZ"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var i=require("fabric");const p=(t,e=1)=>{if(!t)return console.warn("getRectProps: points is required"),null;const L=Array.isArray(t)?t:t.split(",").map(Number);if(L.length===0)return console.warn("getRectProps: points array is empty"),null;if(L.length!==8)return console.warn(`getRectProps: points must contain exactly 8 numbers, got ${L.length}`),null;if(L.some(g=>Number.isNaN(g)))return console.warn("getRectProps: all points must be valid numbers"),null;const[s,C,r,l,c,a,j,v]=L;return{left:Number(s),top:Number(C),width:Math.abs(Number(r)-Number(s))-e,height:Math.abs(Number(a)-Number(C))-e,strokeWidth:e}},m=t=>{if(!t)return console.warn("getObjectPoints: object is required"),null;const{left:e,top:L,width:s,height:C}=t;return[e,L,e+s,L,e+s,L+C,e,L+C]},n=t=>{const e=new i.Path(i.util.parsePath(t));return{width:e.width,height:e.height}},o="M0.0654297 47.7528C1.00227 47.8765 1.87859 47.6528 2.54701 47.4107C3.28908 47.1264 4.00202 46.7713 4.67596 46.3502C6.08911 45.4897 7.7049 44.2581 9.43385 42.7949C12.9023 39.8581 17.0917 35.7633 21.4391 31.2476C22.5023 30.1423 23.576 29.0133 24.6549 27.866C25.6549 28.8054 26.6365 29.7423 27.597 30.666C32.0707 34.9765 36.0154 39.0186 38.7812 42.2844C40.1654 43.9239 41.2023 45.3002 41.8523 46.3739C42.1786 46.9107 42.3681 47.3081 42.4681 47.5765C42.5207 47.7212 42.5312 47.787 42.5312 47.787C42.5312 47.787 42.5181 47.7081 42.5365 47.5686L47.7549 48.2502C47.876 47.316 47.6549 46.437 47.4128 45.7712C47.1279 45.0281 46.7719 44.3143 46.3496 43.6397C45.4917 42.2265 44.2575 40.6107 42.797 38.8818C39.8602 35.4133 35.7654 31.2265 31.247 26.8765C30.2628 25.9291 29.2575 24.9712 28.2338 24.0081C34.2525 17.4362 40.131 10.7373 45.8654 3.91597L41.8338 0.534393C36.1573 7.28575 30.3384 13.9162 24.3812 20.4212C17.6908 14.2829 10.8681 8.29029 3.91806 2.44755L0.533851 6.48176C6.03385 11.0949 13.5838 17.6397 20.7996 24.2818C19.7417 25.4081 18.6891 26.516 17.6496 27.5976C13.3391 32.0712 9.29701 36.0133 6.03385 38.7765C4.39438 40.166 3.01543 41.1976 1.94438 41.8502C1.56348 42.0923 1.16087 42.2985 0.741745 42.466C0.594377 42.5186 0.531219 42.5291 0.531219 42.5291C0.531219 42.5291 0.610166 42.516 0.747009 42.5344L0.0654297 47.7528V47.7528Z",u="M46.5079 2.50162L49.9999 5.55541L47.3484 10.151L45.4673 13.2534L44.0748 15.5229L42.2457 18.4638L40.4512 21.3007L38.6971 24.0242L36.9853 26.6284L35.7332 28.496L34.508 30.2886L33.3155 32.0004L32.1557 33.6256L31.3998 34.6623L30.2977 36.1414L29.5822 37.0762L28.8841 37.9667L27.8724 39.2226L27.2184 40.0016L26.5837 40.7344L25.9702 41.421L25.3758 42.0577L24.8027 42.6462L24.5238 42.9213L23.9814 43.431L23.4621 43.8907C22.1888 44.9677 21.1271 45.5467 20.3116 45.5467C18.6498 45.5467 16.3899 44.3196 13.7953 42.25L12.9644 41.5691L12.1142 40.8363C11.8257 40.5825 11.5372 40.3209 11.2429 40.0516L10.3582 39.2188L9.45422 38.3417L8.54062 37.4224L7.6174 36.4626L6.68072 35.4663L5.73827 34.4354L4.79005 33.3737L3.83799 32.2831L2.88207 31.1676L1.92808 30.027L0.974095 28.8653L0.499023 28.2787L4.30734 24.7839L5.12477 25.7899L5.95759 26.79L6.7981 27.7805L8.06944 29.2423L8.92149 30.1963L9.77162 31.1291L10.6179 32.0369L11.4546 32.9198L12.2816 33.7699L13.0952 34.5873L13.8934 35.3682L14.6704 36.1087L15.0513 36.4626L15.7937 37.1358L16.5072 37.7609L17.192 38.3321L17.5228 38.5995L18.1556 39.088L18.7499 39.5169C19.8039 40.2478 19.7596 40.0515 20.3116 40.0515C20.4212 40.0515 20.6001 39.9495 20.8444 39.7534L21.1098 39.5264L21.4156 39.2379L21.7618 38.8917L22.3465 38.2589L22.7831 37.7685L23.2524 37.2222L24.016 36.3067L24.8469 35.2758L25.4374 34.5276L26.6895 32.8927L27.6896 31.5521L28.736 30.1173L29.8207 28.5978L31.321 26.4398C34.5388 21.7545 38.1547 16.1537 41.5821 10.6221L43.6113 7.31965C44.2768 6.22718 44.9307 5.14625 45.5673 4.08262L46.5079 2.50162Z",b="M27.862 45.101L27.962 45.412L28.2036 46.3368C28.378 47.0217 28.2849 47.7472 27.943 48.3657C27.6012 48.9842 27.0364 49.4492 26.3638 49.6658C25.6911 49.8825 24.9612 49.8346 24.3226 49.5319C23.6841 49.2291 23.1849 48.6944 22.9269 48.0365L22.8241 47.731L22.5853 46.8034C22.4136 46.1438 22.4905 45.4441 22.8013 44.8375C23.1121 44.2309 23.6351 43.7598 24.2708 43.5138C24.9064 43.2679 25.6103 43.2643 26.2485 43.5037C26.8866 43.7431 27.4144 44.2088 27.7315 44.8121L27.862 45.101V45.101ZM28.2342 0.320863C35.9965 1.78169 40.7539 7.85272 38.3433 15.5123C37.2435 19.0116 35.7827 20.9557 32.9888 23.283L30.8225 25.0382L30.4448 25.3715C29.034 26.6296 28.0009 27.9266 27.0705 29.7873C25.7346 32.4534 25.5541 33.656 25.9041 35.0668L26.1762 36.0277C26.2595 36.3416 26.3262 36.6221 26.3706 36.9165C26.4151 37.2025 26.4373 37.4858 26.4373 37.7746C26.4365 38.4825 26.1655 39.1633 25.6795 39.6781C25.1936 40.1928 24.5295 40.5025 23.8228 40.544C23.1162 40.5855 22.4204 40.3556 21.8775 39.9013C21.3347 39.4469 20.9859 38.8025 20.9023 38.0996L20.8689 37.6913L20.6523 36.922C19.8108 34.0281 20.0413 31.4148 22.102 27.3017C23.1077 25.2436 24.4712 23.3807 26.129 21.8L27.2621 20.7724L28.9396 19.4199C31.3308 17.5036 32.2584 16.3538 33.0443 13.8488C34.3496 9.70791 31.9723 6.67517 27.2066 5.7809C22.152 4.82831 17.0558 6.93346 15.0701 11.2243C14.9275 11.5707 14.7163 11.8847 14.4492 12.1474C14.1822 12.41 13.8647 12.616 13.516 12.7527C13.1672 12.8895 12.7944 12.9544 12.42 12.9433C12.0455 12.9323 11.6772 12.8456 11.3371 12.6885C10.9971 12.5314 10.6923 12.3071 10.4412 12.0292C10.19 11.7512 9.99771 11.4253 9.8758 11.0711C9.75389 10.7169 9.70489 10.3417 9.73177 9.96806C9.75864 9.59442 9.86082 9.23008 10.0322 8.89696C13.1732 2.09829 20.8467 -1.06775 28.2342 0.320863Z",h="M47.1047 5.83231L43.7817 2.77777L42.8867 4.35916C42.2809 5.42304 41.6586 6.50424 41.0253 7.59698L39.0944 10.9002C38.1277 12.5401 37.1453 14.1861 36.1616 15.8125L34.792 14.4103L32.9661 12.5637L30.4656 10.0614L26.7341 6.48651L23.1841 9.24437L24.462 10.5019C25.321 11.3517 26.1925 12.2222 27.0724 13.1063L29.7286 15.7962C31.0497 17.1441 32.3732 18.5096 33.678 19.872C32.1854 22.2824 30.7187 24.5963 29.3299 26.7218L27.9023 28.8804L26.8701 30.4002L25.8744 31.8354L24.9227 33.1763L23.7312 34.8116L23.1693 35.5599L22.3786 36.5911L21.652 37.5068L21.2054 38.0532L20.7899 38.5438L20.2335 39.1767L19.9041 39.523L19.6131 39.8116L19.3605 40.0386C19.1281 40.2348 18.9578 40.3368 18.8535 40.3368C18.7508 40.3368 18.6698 40.3443 18.5984 40.3509C18.3048 40.3781 18.1743 40.3902 17.3674 39.8021L16.8018 39.3731L16.1997 38.8844L15.8849 38.617L15.2333 38.0456L14.5543 37.4204L13.8478 36.7471L13.4854 36.3931L12.746 35.6524L11.9864 34.8713L11.2122 34.0537L10.4252 33.2033L9.62905 32.3203L8.82374 31.4123L8.01476 30.4792L7.20396 29.525L5.99415 28.0629L5.19433 27.0721L4.40183 26.0717L3.62397 25.0655L0 28.5611L0.452074 29.1479L1.35988 30.3099L2.26769 31.4507L3.17733 32.5666L4.08331 33.6574L4.98563 34.7193L5.88246 35.7505L6.7738 36.7471L7.65232 37.707L8.5217 38.6266L9.38192 39.5039L10.2238 40.3369C10.5039 40.6063 10.7784 40.8679 11.0529 41.1219L11.8619 41.8548L12.6526 42.5359C15.1216 44.6059 17.2722 45.8333 18.8535 45.8333C19.6295 45.8333 20.6399 45.2543 21.8515 44.1769L22.3457 43.7171L22.8618 43.2073L23.1272 42.9322L23.6726 42.3435L24.2381 41.7067L24.822 41.0199L25.426 40.2869L26.0483 39.5078L27.011 38.2515L27.6754 37.3608L28.3562 36.4258L29.405 34.9463L30.1243 33.9094L31.2279 32.2838L32.3627 30.5715L33.5286 28.7785L34.7201 26.9105L36.349 24.3056L36.9499 23.3249C38.8545 25.3573 40.6757 27.3426 42.3409 29.2094L44.0412 31.1374L45.2325 32.5227L46.353 33.8523L50 30.8934L49.1904 29.9328L47.916 28.4516L46.5678 26.9199L45.1512 25.3389L43.6703 23.7155L41.5984 21.4853L39.4451 19.2102L39.7258 18.7438L41.4664 15.8023L42.7915 13.5321L44.5815 10.429L47.1047 5.83231Z",d=[{name:"\u6B63\u786E",scale:.02,path:u,...n(u),midScale:.03,result:1},{name:"\u9519\u8BEF",scale:.02,path:o,...n(o),midScale:.03,result:2},{name:"\u95EE\u53F7\u5B58\u7591",scale:.02,path:b,...n(b),midScale:.03,result:3},{name:"\u534A\u5BF9",scale:1,path:h,...n(h),midScale:.3,result:4},{name:"\u5360\u4F4D",scale:1,path:"M 0 0",...n("M 0 0"),midScale:.3,result:5}],P=t=>{const e=t.getObjects().map(L=>({object:L,selectable:L.selectable,evented:L.evented}));return t.getObjects().forEach(L=>{L.selectable=!1,L.evented=!1}),()=>{e.forEach(L=>{L.object.selectable=L.selectable,L.object.evented=L.evented})}},f=(t,e,L)=>Math.round(t/e*(L||14)),N=({brush:t,scale:e=1,expanded_points:L,imgTop:s=0,imgLeft:C=0})=>{const r=JSON.parse(JSON.stringify(t)),[l,c]=L?L.split(","):[0,0],a=t.scaleX||1;return r.top=(t.top-s)/e+ +c,r.left=(t.left-C)/e+ +l,r.scaleX=a/e,r.scaleY=a/e,r};exports.PATH_LIST=d,exports.disableCanvasObjects=P,exports.getObjectPoints=m,exports.getPathBounds=n,exports.getRectProps=p,exports.getRelativeTextFontSize=f,exports.restore2Origin=N;
|
|
2
|
+
//# sourceMappingURL=business.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"business.cjs","sources":["../../../src/utils/business.ts"],"sourcesContent":["import type { Canvas, FabricObject } from 'fabric'\nimport { Path, util } from 'fabric'\n\n/**\n * 将points转换为rect\n * @param points 支持字符串(以逗号分隔的8个数字)或数字数组\n * @returns 返回矩形属性或null\n */\nexport const getRectProps = (points: string | number[] | undefined, strokeWidth = 1) => {\n if (!points) {\n console.warn('getRectProps: points is required')\n return null\n }\n\n const coordinates = Array.isArray(points) ? points : points.split(',').map(Number)\n\n if (coordinates.length === 0) {\n console.warn('getRectProps: points array is empty')\n return null\n }\n\n if (coordinates.length !== 8) {\n console.warn(`getRectProps: points must contain exactly 8 numbers, got ${coordinates.length}`)\n return null\n }\n\n if (coordinates.some(n => Number.isNaN(n))) {\n console.warn('getRectProps: all points must be valid numbers')\n return null\n }\n\n // 按顺时针顺序:左上(x1,y1)、右上(x2,y2)、右下(x3,y3)、左下(x4,y4)\n\n const [x1, y1, x2, _y2, _x3, y3, _x4, _y4] = coordinates\n const result = {\n left: Number(x1),\n top: Number(y1),\n width: Math.abs(Number(x2) - Number(x1)) - strokeWidth,\n height: Math.abs(Number(y3) - Number(y1)) - strokeWidth,\n strokeWidth,\n }\n\n return result\n}\n// 将object转换成points\nexport const getObjectPoints = (object: FabricObject) => {\n if (!object) {\n console.warn('getObjectPoints: object is required')\n return null\n }\n const { left, top, width, height } = object\n return [left, top, left + width, top, left + width, top + height, left, top + height]\n}\n\n/**\n * 获取路径的宽高\n * @param pathString\n * @returns\n */\nexport const getPathBounds = (pathString: string) => {\n const path = new Path(util.parsePath(pathString))\n return {\n width: path.width!,\n height: path.height!,\n }\n}\n\nconst 错误Path =\n 'M0.0654297 47.7528C1.00227 47.8765 1.87859 47.6528 2.54701 47.4107C3.28908 47.1264 4.00202 46.7713 4.67596 46.3502C6.08911 45.4897 7.7049 44.2581 9.43385 42.7949C12.9023 39.8581 17.0917 35.7633 21.4391 31.2476C22.5023 30.1423 23.576 29.0133 24.6549 27.866C25.6549 28.8054 26.6365 29.7423 27.597 30.666C32.0707 34.9765 36.0154 39.0186 38.7812 42.2844C40.1654 43.9239 41.2023 45.3002 41.8523 46.3739C42.1786 46.9107 42.3681 47.3081 42.4681 47.5765C42.5207 47.7212 42.5312 47.787 42.5312 47.787C42.5312 47.787 42.5181 47.7081 42.5365 47.5686L47.7549 48.2502C47.876 47.316 47.6549 46.437 47.4128 45.7712C47.1279 45.0281 46.7719 44.3143 46.3496 43.6397C45.4917 42.2265 44.2575 40.6107 42.797 38.8818C39.8602 35.4133 35.7654 31.2265 31.247 26.8765C30.2628 25.9291 29.2575 24.9712 28.2338 24.0081C34.2525 17.4362 40.131 10.7373 45.8654 3.91597L41.8338 0.534393C36.1573 7.28575 30.3384 13.9162 24.3812 20.4212C17.6908 14.2829 10.8681 8.29029 3.91806 2.44755L0.533851 6.48176C6.03385 11.0949 13.5838 17.6397 20.7996 24.2818C19.7417 25.4081 18.6891 26.516 17.6496 27.5976C13.3391 32.0712 9.29701 36.0133 6.03385 38.7765C4.39438 40.166 3.01543 41.1976 1.94438 41.8502C1.56348 42.0923 1.16087 42.2985 0.741745 42.466C0.594377 42.5186 0.531219 42.5291 0.531219 42.5291C0.531219 42.5291 0.610166 42.516 0.747009 42.5344L0.0654297 47.7528V47.7528Z'\n\nconst 正确Path =\n 'M46.5079 2.50162L49.9999 5.55541L47.3484 10.151L45.4673 13.2534L44.0748 15.5229L42.2457 18.4638L40.4512 21.3007L38.6971 24.0242L36.9853 26.6284L35.7332 28.496L34.508 30.2886L33.3155 32.0004L32.1557 33.6256L31.3998 34.6623L30.2977 36.1414L29.5822 37.0762L28.8841 37.9667L27.8724 39.2226L27.2184 40.0016L26.5837 40.7344L25.9702 41.421L25.3758 42.0577L24.8027 42.6462L24.5238 42.9213L23.9814 43.431L23.4621 43.8907C22.1888 44.9677 21.1271 45.5467 20.3116 45.5467C18.6498 45.5467 16.3899 44.3196 13.7953 42.25L12.9644 41.5691L12.1142 40.8363C11.8257 40.5825 11.5372 40.3209 11.2429 40.0516L10.3582 39.2188L9.45422 38.3417L8.54062 37.4224L7.6174 36.4626L6.68072 35.4663L5.73827 34.4354L4.79005 33.3737L3.83799 32.2831L2.88207 31.1676L1.92808 30.027L0.974095 28.8653L0.499023 28.2787L4.30734 24.7839L5.12477 25.7899L5.95759 26.79L6.7981 27.7805L8.06944 29.2423L8.92149 30.1963L9.77162 31.1291L10.6179 32.0369L11.4546 32.9198L12.2816 33.7699L13.0952 34.5873L13.8934 35.3682L14.6704 36.1087L15.0513 36.4626L15.7937 37.1358L16.5072 37.7609L17.192 38.3321L17.5228 38.5995L18.1556 39.088L18.7499 39.5169C19.8039 40.2478 19.7596 40.0515 20.3116 40.0515C20.4212 40.0515 20.6001 39.9495 20.8444 39.7534L21.1098 39.5264L21.4156 39.2379L21.7618 38.8917L22.3465 38.2589L22.7831 37.7685L23.2524 37.2222L24.016 36.3067L24.8469 35.2758L25.4374 34.5276L26.6895 32.8927L27.6896 31.5521L28.736 30.1173L29.8207 28.5978L31.321 26.4398C34.5388 21.7545 38.1547 16.1537 41.5821 10.6221L43.6113 7.31965C44.2768 6.22718 44.9307 5.14625 45.5673 4.08262L46.5079 2.50162Z'\n\nconst 问号Path =\n 'M27.862 45.101L27.962 45.412L28.2036 46.3368C28.378 47.0217 28.2849 47.7472 27.943 48.3657C27.6012 48.9842 27.0364 49.4492 26.3638 49.6658C25.6911 49.8825 24.9612 49.8346 24.3226 49.5319C23.6841 49.2291 23.1849 48.6944 22.9269 48.0365L22.8241 47.731L22.5853 46.8034C22.4136 46.1438 22.4905 45.4441 22.8013 44.8375C23.1121 44.2309 23.6351 43.7598 24.2708 43.5138C24.9064 43.2679 25.6103 43.2643 26.2485 43.5037C26.8866 43.7431 27.4144 44.2088 27.7315 44.8121L27.862 45.101V45.101ZM28.2342 0.320863C35.9965 1.78169 40.7539 7.85272 38.3433 15.5123C37.2435 19.0116 35.7827 20.9557 32.9888 23.283L30.8225 25.0382L30.4448 25.3715C29.034 26.6296 28.0009 27.9266 27.0705 29.7873C25.7346 32.4534 25.5541 33.656 25.9041 35.0668L26.1762 36.0277C26.2595 36.3416 26.3262 36.6221 26.3706 36.9165C26.4151 37.2025 26.4373 37.4858 26.4373 37.7746C26.4365 38.4825 26.1655 39.1633 25.6795 39.6781C25.1936 40.1928 24.5295 40.5025 23.8228 40.544C23.1162 40.5855 22.4204 40.3556 21.8775 39.9013C21.3347 39.4469 20.9859 38.8025 20.9023 38.0996L20.8689 37.6913L20.6523 36.922C19.8108 34.0281 20.0413 31.4148 22.102 27.3017C23.1077 25.2436 24.4712 23.3807 26.129 21.8L27.2621 20.7724L28.9396 19.4199C31.3308 17.5036 32.2584 16.3538 33.0443 13.8488C34.3496 9.70791 31.9723 6.67517 27.2066 5.7809C22.152 4.82831 17.0558 6.93346 15.0701 11.2243C14.9275 11.5707 14.7163 11.8847 14.4492 12.1474C14.1822 12.41 13.8647 12.616 13.516 12.7527C13.1672 12.8895 12.7944 12.9544 12.42 12.9433C12.0455 12.9323 11.6772 12.8456 11.3371 12.6885C10.9971 12.5314 10.6923 12.3071 10.4412 12.0292C10.19 11.7512 9.99771 11.4253 9.8758 11.0711C9.75389 10.7169 9.70489 10.3417 9.73177 9.96806C9.75864 9.59442 9.86082 9.23008 10.0322 8.89696C13.1732 2.09829 20.8467 -1.06775 28.2342 0.320863Z'\n\nconst 半对Path =\n 'M47.1047 5.83231L43.7817 2.77777L42.8867 4.35916C42.2809 5.42304 41.6586 6.50424 41.0253 7.59698L39.0944 10.9002C38.1277 12.5401 37.1453 14.1861 36.1616 15.8125L34.792 14.4103L32.9661 12.5637L30.4656 10.0614L26.7341 6.48651L23.1841 9.24437L24.462 10.5019C25.321 11.3517 26.1925 12.2222 27.0724 13.1063L29.7286 15.7962C31.0497 17.1441 32.3732 18.5096 33.678 19.872C32.1854 22.2824 30.7187 24.5963 29.3299 26.7218L27.9023 28.8804L26.8701 30.4002L25.8744 31.8354L24.9227 33.1763L23.7312 34.8116L23.1693 35.5599L22.3786 36.5911L21.652 37.5068L21.2054 38.0532L20.7899 38.5438L20.2335 39.1767L19.9041 39.523L19.6131 39.8116L19.3605 40.0386C19.1281 40.2348 18.9578 40.3368 18.8535 40.3368C18.7508 40.3368 18.6698 40.3443 18.5984 40.3509C18.3048 40.3781 18.1743 40.3902 17.3674 39.8021L16.8018 39.3731L16.1997 38.8844L15.8849 38.617L15.2333 38.0456L14.5543 37.4204L13.8478 36.7471L13.4854 36.3931L12.746 35.6524L11.9864 34.8713L11.2122 34.0537L10.4252 33.2033L9.62905 32.3203L8.82374 31.4123L8.01476 30.4792L7.20396 29.525L5.99415 28.0629L5.19433 27.0721L4.40183 26.0717L3.62397 25.0655L0 28.5611L0.452074 29.1479L1.35988 30.3099L2.26769 31.4507L3.17733 32.5666L4.08331 33.6574L4.98563 34.7193L5.88246 35.7505L6.7738 36.7471L7.65232 37.707L8.5217 38.6266L9.38192 39.5039L10.2238 40.3369C10.5039 40.6063 10.7784 40.8679 11.0529 41.1219L11.8619 41.8548L12.6526 42.5359C15.1216 44.6059 17.2722 45.8333 18.8535 45.8333C19.6295 45.8333 20.6399 45.2543 21.8515 44.1769L22.3457 43.7171L22.8618 43.2073L23.1272 42.9322L23.6726 42.3435L24.2381 41.7067L24.822 41.0199L25.426 40.2869L26.0483 39.5078L27.011 38.2515L27.6754 37.3608L28.3562 36.4258L29.405 34.9463L30.1243 33.9094L31.2279 32.2838L32.3627 30.5715L33.5286 28.7785L34.7201 26.9105L36.349 24.3056L36.9499 23.3249C38.8545 25.3573 40.6757 27.3426 42.3409 29.2094L44.0412 31.1374L45.2325 32.5227L46.353 33.8523L50 30.8934L49.1904 29.9328L47.916 28.4516L46.5678 26.9199L45.1512 25.3389L43.6703 23.7155L41.5984 21.4853L39.4451 19.2102L39.7258 18.7438L41.4664 15.8023L42.7915 13.5321L44.5815 10.429L47.1047 5.83231Z'\n\n// 1正确;2错误;3问好存疑;4半对;9半对(不知道谁写的,跟4有什么区别);5 无痕迹,占位使用\nexport const PATH_LIST = [\n {\n name: '正确',\n scale: 0.02,\n path: 正确Path,\n ...getPathBounds(正确Path),\n\n midScale: 0.03,\n result: 1,\n },\n {\n name: '错误',\n scale: 0.02,\n path: 错误Path,\n ...getPathBounds(错误Path),\n midScale: 0.03,\n result: 2,\n },\n {\n name: '问号存疑',\n scale: 0.02,\n path: 问号Path,\n ...getPathBounds(问号Path),\n midScale: 0.03,\n result: 3,\n },\n {\n name: '半对',\n scale: 1,\n path: 半对Path,\n ...getPathBounds(半对Path),\n midScale: 0.3,\n result: 4,\n },\n {\n name: '占位', // 无痕迹,占位使用\n scale: 1,\n path: 'M 0 0',\n ...getPathBounds('M 0 0'),\n midScale: 0.3,\n result: 5,\n },\n] as const\n\n// 禁用所有对象并获取还原函数\nexport const disableCanvasObjects = (canvas: Canvas) => {\n // 保存所有对象的原始状态\n const originalStates = canvas.getObjects().map((obj: any) => ({\n object: obj,\n selectable: obj.selectable,\n evented: obj.evented,\n }))\n\n // 禁用所有对象的事件和选择\n canvas.getObjects().forEach((obj: any) => {\n obj.selectable = false\n obj.evented = false\n })\n\n // 返回还原函数\n return () => {\n originalStates.forEach((state: any) => {\n state.object.selectable = state.selectable\n state.object.evented = state.evented\n })\n }\n}\n\n/**\n * 计算相对 Text 字体大小\n */\nexport const getRelativeTextFontSize = (naturalWidth: number, width: number, defaultFontSize?: number) => {\n return Math.round((naturalWidth / width) * (defaultFontSize || 14))\n}\n\n/**\n * 还原痕迹至原图点位\n * @param brush 痕迹对象,canvas toJSON 后的对象\n * @param scale 当前缩放, imgTop,imgLeft 图片基于居中偏移\n * @param expanded_points 基于原图的点位,字符串\n */\nexport const restore2Origin = ({\n brush,\n scale = 1,\n expanded_points,\n imgTop = 0,\n imgLeft = 0,\n}: {\n brush: any\n scale?: number\n expanded_points?: string\n imgTop?: number\n imgLeft?: number\n}) => {\n const obj = JSON.parse(JSON.stringify(brush))\n const [left, top] = expanded_points ? expanded_points.split(',') : [0, 0]\n const item_scale = brush.scaleX || 1\n obj.top = (brush.top - imgTop) / scale + +top\n obj.left = (brush.left - imgLeft) / scale + +left\n obj.scaleX = item_scale / scale\n obj.scaleY = item_scale / scale\n return obj\n}\n"],"names":["getRectProps","points","strokeWidth","coordinates","n","x1","y1","x2","_y2","_x3","y3","_x4","_y4","getObjectPoints","object","left","top","width","height","getPathBounds","pathString","path","Path","util","错误Path","正确Path","问号Path","半对Path","PATH_LIST","disableCanvasObjects","canvas","originalStates","obj","state","getRelativeTextFontSize","naturalWidth","defaultFontSize","restore2Origin","brush","scale","expanded_points","imgTop","imgLeft","item_scale"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"childrenWithPosition.cjs","sources":["../../../src/utils/childrenWithPosition.ts"],"sourcesContent":["import { cloneElement, isValidElement, type CSSProperties } from 'react'\n\nexport const childrenWithPosition = ({\n children,\n position,\n}: {\n children: React.ReactNode\n position: CSSProperties\n}) => {\n return isValidElement(children)\n ? cloneElement(children, {\n ...(children.props as any),\n style: Object.assign({}, position, children.props.style),\n } as any)\n : null\n}\n"],"names":["childrenWithPosition","children","position","isValidElement","cloneElement"],"mappings":"oCAEa,MAAAA,EAAuB,CAAC,CACnC,SAAAC,EACA,SAAAC,CACF,IAISC,iBAAeF,CAAQ,EAC1BG,EAAAA,aAAaH,EAAU,CACrB,GAAIA,EAAS,MACb,MAAO,OAAO,OAAO,CAAA,EAAIC,EAAUD,EAAS,MAAM,KAAK,CACzD,CAAQ,EACR"}
|
|
@@ -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=
|
|
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};
|
|
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 { 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
|
|
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,2 +1,2 @@
|
|
|
1
|
-
"use client";import{jsxs as
|
|
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};
|
|
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 { 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\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
|
|
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,2 +1,2 @@
|
|
|
1
|
-
"use client";import{jsxs as
|
|
1
|
+
"use client";import{jsxs as P,Fragment as b,jsx as O}from"react/jsx-runtime";import{computePosition as j,offset as k,flip as A,shift as D}from"@floating-ui/core";import{util as F}from"fabric";import d,{useRef as w,useCallback as x,useMemo as q,useEffect as p}from"react";import{useStore as B}from"../../hooks/useStore.mjs";import L from"../NodeToolbarPortal/index.mjs";const N=d.forwardRef(({children:a,className:C,placement:f="bottom",open:n=!0,onOpenChange:l,closeOnOutsideClick:g=!0,Content:v},m)=>{const c=w(void 0),t=B(e=>e.canvas),o=w(null),h=x(e=>{e!==c.current&&(c.current=e,typeof m=="function"?m(e):m&&(m.current=e))},[m]),y=q(()=>d.Children.only(a)&&d.isValidElement(a)?d.cloneElement(a,{ref:h,...a.props}):a,[a,h]),u=x(()=>{if(!c.current||!o.current||!t)return;const e=o.current.getBoundingClientRect();if(e.width===0||e.height===0){requestAnimationFrame(u);return}const r=c.current.getCoords().map(s=>F.sendPointToPlane(s,t.viewportTransform,void 0)),i={getElementRects:s=>s,getDimensions:s=>s,getClippingRect:()=>({x:0,y:0,width:t.width,height:t.height})},E={x:r[0].x,y:r[0].y,width:r[2].x-r[0].x,height:r[2].y-r[0].y};j(E,o.current.getBoundingClientRect(),{platform:i,placement:f,middleware:[k(5),A(),D({padding:5})]}).then(({x:s,y:R})=>{o.current&&Object.assign(o.current.style,{left:`${s}px`,top:`${R}px`})})},[t,f]);return p(()=>{n&&requestAnimationFrame(u)},[n,u]),p(()=>(t?.on("after:render",u),()=>{t?.off("after:render",u)}),[t,u]),p(()=>{const e=i=>{i.e.stopPropagation(),i.e.preventDefault(),i.target===c.current?l?.(!n):n&&l?.(!1)},r=i=>{o.current?.contains(i.target)||g&&n&&l?.(!1)};return t?.on("mouse:down",e),document.addEventListener("mousedown",r,!1),()=>{t?.off("mouse:down",e),document.removeEventListener("mousedown",r,!1)}},[t,g,l,n]),P(b,{children:[y,n&&O(L,{className:`absolute ${C}`,ref:o,onClick:e=>{e.stopPropagation(),e.preventDefault()},children:v})]})});export{N as default};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../../../../src/components/Control/index.tsx"],"sourcesContent":["import { computePosition, flip, offset, shift,ComputePositionConfig } from '@floating-ui/core'\nimport type { FabricObject, FabricObjectProps, TPointerEvent, TPointerEventInfo } from 'fabric'\nimport { util } from 'fabric'\nimport
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../../../src/components/Control/index.tsx"],"sourcesContent":["import { computePosition, flip, offset, shift, ComputePositionConfig } from '@floating-ui/core'\nimport type { FabricObject, FabricObjectProps, TPointerEvent, TPointerEventInfo } from 'fabric'\nimport { util } from 'fabric'\nimport type { ReactNode } from 'react'\nimport { useMemo } from 'react'\nimport { useCallback } from 'react'\nimport { useRef } from 'react'\nimport { useEffect } from 'react'\nimport React from 'react'\nimport { useStore } from '../../hooks/useStore'\nimport type { AllObjectEvents } from '../../types/object'\nimport NodeToolbarPortal from '../NodeToolbarPortal'\n\n/**\n * @desc 不能内置支持 selected , 因为需要 rect 开启 lockMovementX lockMovementY, 这样支持的场景就受限了\n */\nexport type ControlProps = Partial<AllObjectEvents & FabricObjectProps> & {\n Content: ReactNode\n children: ReactNode\n placement?: ComputePositionConfig['placement']\n className?: string\n open?: boolean\n onOpenChange?: (open: boolean) => void\n closeOnOutsideClick?: boolean\n}\n\nconst Control = React.forwardRef(\n (\n {\n children,\n className,\n placement = 'bottom',\n open = true,\n onOpenChange,\n closeOnOutsideClick = true,\n Content,\n }: ControlProps,\n forwardRef,\n ) => {\n const instanceRef = useRef<FabricObject | undefined>(undefined)\n const canvas = useStore(state => state.canvas)\n const floatingElRef = useRef<HTMLDivElement>(null)\n\n // 使用 useCallback 创建稳定的 ref 回调\n const refCallback = useCallback(\n (node: any) => {\n // 只在节点真正改变时更新 ref\n if (node !== instanceRef.current) {\n instanceRef.current = node\n\n // 处理 forwardRef\n if (typeof forwardRef === 'function') {\n forwardRef(node)\n } else if (forwardRef) {\n forwardRef.current = node\n }\n }\n },\n [forwardRef],\n )\n\n // 使用 useMemo 缓存克隆的子元素\n const newChildren = useMemo(() => {\n if (React.Children.only(children) && React.isValidElement(children)) {\n return React.cloneElement(children, {\n ref: refCallback,\n ...children.props,\n })\n }\n return children\n }, [children, refCallback]) // 只在 children 或 refCallback 改变时重新克隆\n\n const updatePosition = useCallback(() => {\n if (!instanceRef.current || !floatingElRef.current || !canvas) {\n return\n }\n\n // 确保元素已经渲染并且有尺寸\n const floatingRect = floatingElRef.current.getBoundingClientRect()\n if (floatingRect.width === 0 || floatingRect.height === 0) {\n // 如果元素还没有尺寸,等待下一帧再试\n requestAnimationFrame(updatePosition)\n return\n }\n\n const sceneCoords = instanceRef.current.getCoords()\n const viewportCoords = sceneCoords.map(point => util.sendPointToPlane(point, canvas.viewportTransform, undefined))\n\n const platform = {\n getElementRects: (data: any) => data,\n getDimensions: (element: any) => element,\n getClippingRect: () => ({\n x: 0,\n y: 0,\n width: canvas.width,\n height: canvas.height,\n }),\n }\n\n const virtualEl = {\n x: viewportCoords[0].x,\n y: viewportCoords[0].y,\n width: viewportCoords[2].x - viewportCoords[0].x,\n height: viewportCoords[2].y - viewportCoords[0].y,\n }\n\n computePosition(virtualEl, floatingElRef.current.getBoundingClientRect(), {\n platform,\n placement,\n middleware: [offset(5), flip(), shift({ padding: 5 })],\n }).then(({ x, y }) => {\n if (!floatingElRef.current) return\n\n Object.assign(floatingElRef.current.style, {\n left: `${x}px`,\n top: `${y}px`,\n })\n })\n }, [canvas, placement])\n\n // 确保在元素挂载后更新位置\n useEffect(() => {\n if (open) {\n requestAnimationFrame(updatePosition)\n }\n }, [open, updatePosition])\n\n useEffect(() => {\n canvas?.on('after:render', updatePosition)\n\n return () => {\n canvas?.off('after:render', updatePosition)\n }\n }, [canvas, updatePosition])\n\n useEffect(() => {\n const handleCanvasClick = (e: TPointerEventInfo<TPointerEvent>) => {\n // 阻止事件冒泡到 document\n e.e.stopPropagation()\n e.e.preventDefault() // 也阻止默认行为\n\n // 使用 id 比较来确保正确匹配\n if (e.target === instanceRef.current) {\n onOpenChange?.(!open)\n }\n // 点击其他区域时关闭\n else if (open) {\n onOpenChange?.(false)\n }\n }\n\n const handleDocumentClick = (e: MouseEvent) => {\n // 如果点击在浮动内容内,不处理\n if (floatingElRef.current?.contains(e.target as Node)) {\n return\n }\n\n if (closeOnOutsideClick && open) {\n onOpenChange?.(false)\n }\n }\n\n canvas?.on('mouse:down', handleCanvasClick)\n // 改为冒泡阶段处理 document 事件\n document.addEventListener('mousedown', handleDocumentClick, false)\n\n return () => {\n canvas?.off('mouse:down', handleCanvasClick)\n document.removeEventListener('mousedown', handleDocumentClick, false)\n }\n }, [canvas, closeOnOutsideClick, onOpenChange, open])\n\n return (\n <>\n {newChildren}\n {open && (\n <NodeToolbarPortal\n className={`absolute ${className}`}\n ref={floatingElRef}\n onClick={e => {\n e.stopPropagation()\n e.preventDefault()\n }}\n >\n {Content}\n </NodeToolbarPortal>\n )}\n </>\n )\n },\n)\n\nexport default Control\n"],"names":["Control","React","children","className","placement","open","onOpenChange","closeOnOutsideClick","Content","forwardRef","instanceRef","useRef","canvas","useStore","state","floatingElRef","refCallback","useCallback","node","newChildren","useMemo","updatePosition","floatingRect","viewportCoords","point","util","platform","data","element","virtualEl","computePosition","offset","flip","shift","x","y","useEffect","handleCanvasClick","e","handleDocumentClick","jsxs","Fragment","jsx","NodeToolbarPortal"],"mappings":"iXA0BA,MAAMA,EAAUC,EAAM,WACpB,CACE,CACE,SAAAC,EACA,UAAAC,EACA,UAAAC,EAAY,SACZ,KAAAC,EAAO,GACP,aAAAC,EACA,oBAAAC,EAAsB,GACtB,QAAAC,CACF,EACAC,IACG,CACH,MAAMC,EAAcC,EAAiC,MAAS,EACxDC,EAASC,EAASC,GAASA,EAAM,MAAM,EACvCC,EAAgBJ,EAAuB,IAAI,EAG3CK,EAAcC,EACjBC,GAAc,CAETA,IAASR,EAAY,UACvBA,EAAY,QAAUQ,EAGlB,OAAOT,GAAe,WACxBA,EAAWS,CAAI,EACNT,IACTA,EAAW,QAAUS,GAG3B,EACA,CAACT,CAAU,CACb,EAGMU,EAAcC,EAAQ,IACtBnB,EAAM,SAAS,KAAKC,CAAQ,GAAKD,EAAM,eAAeC,CAAQ,EACzDD,EAAM,aAAaC,EAAU,CAClC,IAAKc,EACL,GAAGd,EAAS,KACd,CAAC,EAEIA,EACN,CAACA,EAAUc,CAAW,CAAC,EAEpBK,EAAiBJ,EAAY,IAAM,CACvC,GAAI,CAACP,EAAY,SAAW,CAACK,EAAc,SAAW,CAACH,EACrD,OAIF,MAAMU,EAAeP,EAAc,QAAQ,wBAC3C,GAAIO,EAAa,QAAU,GAAKA,EAAa,SAAW,EAAG,CAEzD,sBAAsBD,CAAc,EACpC,MACF,CAGA,MAAME,EADcb,EAAY,QAAQ,YACL,IAAIc,GAASC,EAAK,iBAAiBD,EAAOZ,EAAO,kBAAmB,MAAS,CAAC,EAE3Gc,EAAW,CACf,gBAAkBC,GAAcA,EAChC,cAAgBC,GAAiBA,EACjC,gBAAiB,KAAO,CACtB,EAAG,EACH,EAAG,EACH,MAAOhB,EAAO,MACd,OAAQA,EAAO,MACjB,EACF,EAEMiB,EAAY,CAChB,EAAGN,EAAe,CAAC,EAAE,EACrB,EAAGA,EAAe,CAAC,EAAE,EACrB,MAAOA,EAAe,CAAC,EAAE,EAAIA,EAAe,CAAC,EAAE,EAC/C,OAAQA,EAAe,CAAC,EAAE,EAAIA,EAAe,CAAC,EAAE,CAClD,EAEAO,EAAgBD,EAAWd,EAAc,QAAQ,wBAAyB,CACxE,SAAAW,EACA,UAAAtB,EACA,WAAY,CAAC2B,EAAO,CAAC,EAAGC,EAAK,EAAGC,EAAM,CAAE,QAAS,CAAE,CAAC,CAAC,CACvD,CAAC,EAAE,KAAK,CAAC,CAAE,EAAAC,EAAG,EAAAC,CAAE,IAAM,CACfpB,EAAc,SAEnB,OAAO,OAAOA,EAAc,QAAQ,MAAO,CACzC,KAAM,GAAGmB,CAAC,KACV,IAAK,GAAGC,CAAC,IACX,CAAC,CACH,CAAC,CACH,EAAG,CAACvB,EAAQR,CAAS,CAAC,EAGtB,OAAAgC,EAAU,IAAM,CACV/B,GACF,sBAAsBgB,CAAc,CAExC,EAAG,CAAChB,EAAMgB,CAAc,CAAC,EAEzBe,EAAU,KACRxB,GAAQ,GAAG,eAAgBS,CAAc,EAElC,IAAM,CACXT,GAAQ,IAAI,eAAgBS,CAAc,CAC5C,GACC,CAACT,EAAQS,CAAc,CAAC,EAE3Be,EAAU,IAAM,CACd,MAAMC,EAAqBC,GAAwC,CAEjEA,EAAE,EAAE,gBAAgB,EACpBA,EAAE,EAAE,iBAGAA,EAAE,SAAW5B,EAAY,QAC3BJ,IAAe,CAACD,CAAI,EAGbA,GACPC,IAAe,EAAK,CAExB,EAEMiC,EAAuBD,GAAkB,CAEzCvB,EAAc,SAAS,SAASuB,EAAE,MAAc,GAIhD/B,GAAuBF,GACzBC,IAAe,EAAK,CAExB,EAEA,OAAAM,GAAQ,GAAG,aAAcyB,CAAiB,EAE1C,SAAS,iBAAiB,YAAaE,EAAqB,EAAK,EAE1D,IAAM,CACX3B,GAAQ,IAAI,aAAcyB,CAAiB,EAC3C,SAAS,oBAAoB,YAAaE,EAAqB,EAAK,CACtE,CACF,EAAG,CAAC3B,EAAQL,EAAqBD,EAAcD,CAAI,CAAC,EAGlDmC,EAAAC,EAAA,CACG,SAAA,CAAAtB,EACAd,GACCqC,EAACC,EAAA,CACC,UAAW,YAAYxC,CAAS,GAChC,IAAKY,EACL,QAASuB,GAAK,CACZA,EAAE,gBAAgB,EAClBA,EAAE,eACJ,CAAA,EAEC,SAAA9B,CAAAA,CACH,CAEJ,CAAA,CAAA,CAEJ,CACF"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import{jsx as O,Fragment as P}from"react/jsx-runtime";import{computePosition as A,offset as D,flip as F,shift as L}from"@floating-ui/core";import{util as b}from"fabric";import p,{useRef as C,useState as j,useCallback as v,useMemo as k,useEffect as l}from"react";import{useStore as q,useStoreApi as B}from"../../hooks/useStore.mjs";const M=()=>Math.random().toString(36).substring(2)+Date.now().toString(36),T=p.forwardRef(({children:s,className:g,placement:w="bottom",open:a=!0,onOpenChange:S,closeOnOutsideClick:x=!0,Content:h},m)=>{const f=C(void 0),n=q(e=>e.canvas),r=C(null),[u,V]=j(M()),o=B(),y=v(e=>{e!==f.current&&(f.current=e,typeof m=="function"?m(e):m&&(m.current=e))},[m]),R=k(()=>p.Children.only(s)&&p.isValidElement(s)?p.cloneElement(s,{ref:y,...s.props}):s,[s,y]),c=v(()=>{if(!f.current||!r.current||!n)return;const e=r.current.getBoundingClientRect();if(e.width===0||e.height===0){requestAnimationFrame(c);return}const t=f.current.getCoords().map(i=>b.sendPointToPlane(i,n.viewportTransform,void 0)),d={getElementRects:i=>i,getDimensions:i=>i,getClippingRect:()=>({x:0,y:0,width:n.width,height:n.height})},E={x:t[0].x,y:t[0].y,width:t[2].x-t[0].x,height:t[2].y-t[0].y};A(E,r.current.getBoundingClientRect(),{platform:d,placement:w,middleware:[D(5),F(),L({padding:5})]}).then(({x:i,y:N})=>{r.current&&Object.assign(r.current.style,{left:`${i}px`,top:`${N}px`})})},[n,w]);return l(()=>{a&&requestAnimationFrame(c)},[a,c]),l(()=>(n?.on("after:render",c),()=>{n?.off("after:render",c)}),[n,c]),l(()=>{const e=d=>{d.e.stopPropagation(),d.e.preventDefault()},t=d=>{r.current?.contains(d.target)||x&&a&&S?.(!1)};return n?.on("mouse:down",e),document.addEventListener("mousedown",t,!1),()=>{n?.off("mouse:down",e),document.removeEventListener("mousedown",t,!1)}},[n,x,S,a]),l(()=>{const{controls:e}=o.getState();if(!e.find(t=>t.id===u))return o.setState({controls:[...e,{id:u,className:g,children:h,ref:r}]}),()=>{o.setState({controls:e.filter(t=>t.id!==u)})}},[o]),l(()=>{const{controls:e}=o.getState();e.find(t=>t.id===u)&&o.setState({controls:e.map(t=>t.id===u?{...t,children:a?h:null,className:g}:t)})},[h,g,u,o,a]),O(P,{children:R})});export{T as default};
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../../../src/components/Control2/index.tsx"],"sourcesContent":["import { computePosition, flip, offset, shift } from '@floating-ui/core'\nimport type { ComputePositionConfig } from '@floating-ui/react'\nimport type { FabricObject, FabricObjectProps, TPointerEvent, TPointerEventInfo } from 'fabric'\nimport { util } from 'fabric'\nimport type { ReactNode } from 'react'\nimport { useState } from 'react'\nimport { useMemo } from 'react'\nimport { useCallback } from 'react'\nimport { useRef } from 'react'\nimport { useEffect } from 'react'\nimport React from 'react'\nimport { useStore, useStoreApi } from '../../hooks/useStore'\nimport type { AllObjectEvents } from '../../types/object'\n\n// 生成随机ID的函数\nconst generateRandomId = (): string => {\n return Math.random().toString(36).substring(2) + Date.now().toString(36)\n}\n\n/**\n * @desc 不能内置支持 selected , 因为需要 rect 开启 lockMovementX lockMovementY, 这样支持的场景就受限了\n */\nexport type Control2Props = Partial<AllObjectEvents & FabricObjectProps> & {\n Content: ReactNode\n children: ReactNode\n placement?: ComputePositionConfig['placement']\n className?: string\n open?: boolean\n onOpenChange?: (open: boolean) => void\n closeOnOutsideClick?: boolean\n}\n\nconst Control = React.forwardRef(\n (\n {\n children,\n className,\n placement = 'bottom',\n open = true,\n onOpenChange,\n closeOnOutsideClick = true,\n Content,\n }: Control2Props,\n forwardRef,\n ) => {\n const instanceRef = useRef<FabricObject | undefined>(undefined)\n const canvas = useStore(state => state.canvas)\n const floatingElRef = useRef<HTMLDivElement>(null)\n const [id, _setId] = useState(generateRandomId())\n\n const store = useStoreApi()\n // 使用 useCallback 创建稳定的 ref 回调\n const refCallback = useCallback(\n (node: any) => {\n // 只在节点真正改变时更新 ref\n if (node !== instanceRef.current) {\n instanceRef.current = node\n\n // 处理 forwardRef\n if (typeof forwardRef === 'function') {\n forwardRef(node)\n } else if (forwardRef) {\n forwardRef.current = node\n }\n }\n },\n [forwardRef],\n )\n\n // 使用 useMemo 缓存克隆的子元素\n const newChildren = useMemo(() => {\n if (React.Children.only(children) && React.isValidElement(children)) {\n return React.cloneElement(children, {\n ref: refCallback,\n ...children.props,\n })\n }\n return children\n }, [children, refCallback]) // 只在 children 或 refCallback 改变时重新克隆\n\n const updatePosition = useCallback(() => {\n // 这里测试下来是多余的,可删除;after:render 后都有值\n if (!instanceRef.current || !floatingElRef.current || !canvas) {\n return\n }\n\n // 确保元素已经渲染并且有尺寸\n const floatingRect = floatingElRef.current.getBoundingClientRect()\n if (floatingRect.width === 0 || floatingRect.height === 0) {\n // 如果元素还没有尺寸,等待下一帧再试\n requestAnimationFrame(updatePosition)\n return\n }\n\n const sceneCoords = instanceRef.current.getCoords()\n const viewportCoords = sceneCoords.map(point => util.sendPointToPlane(point, canvas.viewportTransform, undefined))\n\n const platform = {\n getElementRects: (data: any) => data,\n getDimensions: (element: any) => element,\n getClippingRect: () => ({\n x: 0,\n y: 0,\n width: canvas.width,\n height: canvas.height,\n }),\n }\n\n const virtualEl = {\n x: viewportCoords[0].x,\n y: viewportCoords[0].y,\n width: viewportCoords[2].x - viewportCoords[0].x,\n height: viewportCoords[2].y - viewportCoords[0].y,\n }\n\n computePosition(virtualEl, floatingElRef.current.getBoundingClientRect(), {\n platform,\n placement,\n middleware: [offset(5), flip(), shift({ padding: 5 })],\n }).then(({ x, y }) => {\n if (!floatingElRef.current) return\n\n Object.assign(floatingElRef.current.style, {\n left: `${x}px`,\n top: `${y}px`,\n })\n })\n }, [canvas, placement])\n\n // 确保在元素挂载后更新位置\n // 这里测试下来是多余的,可删除;\n useEffect(() => {\n if (open) {\n requestAnimationFrame(updatePosition)\n }\n }, [open, updatePosition])\n\n useEffect(() => {\n canvas?.on('after:render', updatePosition)\n\n return () => {\n canvas?.off('after:render', updatePosition)\n }\n }, [canvas, updatePosition])\n\n useEffect(() => {\n const handleCanvasClick = (e: TPointerEventInfo<TPointerEvent>) => {\n // 阻止事件冒泡到 document\n e.e.stopPropagation()\n e.e.preventDefault() // 也阻止默认行为\n\n // 使用 id 比较来确保正确匹配\n // if (e.target === instanceRef.current) {\n // onOpenChange?.(!open)\n // }\n // // 点击其他区域时关闭\n // else if (open) {\n // onOpenChange?.(false)\n // }\n }\n\n const handleDocumentClick = (e: MouseEvent) => {\n // 如果点击在浮动内容内,不处理\n if (floatingElRef.current?.contains(e.target as Node)) {\n return\n }\n\n if (closeOnOutsideClick && open) {\n onOpenChange?.(false)\n }\n }\n\n canvas?.on('mouse:down', handleCanvasClick)\n // 改为冒泡阶段处理 document 事件\n document.addEventListener('mousedown', handleDocumentClick, false)\n\n return () => {\n canvas?.off('mouse:down', handleCanvasClick)\n document.removeEventListener('mousedown', handleDocumentClick, false)\n }\n }, [canvas, closeOnOutsideClick, onOpenChange, open])\n\n useEffect(() => {\n const { controls } = store.getState()\n\n const control = controls.find(control => control.id === id)\n\n if (control) {\n return\n }\n\n store.setState({\n controls: [\n ...controls,\n {\n id,\n className,\n children: Content,\n ref: floatingElRef,\n },\n ],\n })\n return () => {\n store.setState({\n controls: controls.filter(control => control.id !== id),\n })\n }\n }, [store])\n\n useEffect(() => {\n const { controls } = store.getState()\n const control = controls.find(control => control.id === id)\n\n if (control) {\n store.setState({\n controls: controls.map(control =>\n control.id === id ? { ...control, children: open ? Content : null, className } : control,\n ),\n })\n }\n }, [Content, className, id, store, open])\n\n return <>{newChildren}</>\n },\n)\n\nexport default Control\n"],"names":["generateRandomId","Control","React","children","className","placement","open","onOpenChange","closeOnOutsideClick","Content","forwardRef","instanceRef","useRef","canvas","useStore","state","floatingElRef","id","_setId","useState","store","useStoreApi","refCallback","useCallback","node","newChildren","useMemo","updatePosition","floatingRect","viewportCoords","point","util","platform","data","element","virtualEl","computePosition","offset","flip","shift","x","y","useEffect","handleCanvasClick","e","handleDocumentClick","controls","control","jsx","Fragment"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{Ellipse as
|
|
1
|
+
"use client";import{Ellipse as u}from"fabric";import{forwardRef as n,useImperativeHandle as a,memo as l}from"react";import{useCreateObject as f}from"../../hooks/useCreateObject.mjs";import{useSplitProps as c}from"../../hooks/useSplitProps.mjs";import{useInstancePosition as d}from"../../hooks/useInstancePosition.mjs";const b=n(({group:r,children:t,...o},s)=>{const[i,m,p]=c(o),e=f({Constructor:u,defaultValues:p,attributes:m,group:r,listeners:i});return a(s,()=>e,[e]),d(e,t)});var g=l(b);export{g as default};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../../../../src/components/Ellipse/index.tsx"],"sourcesContent":["import type { Group as BaseGroup } from 'fabric'\nimport { Ellipse as BaseEllipse } from 'fabric'\nimport { forwardRef, memo, useImperativeHandle } from 'react'\nimport { useCreateObject } from '../../hooks/useCreateObject'\nimport { useSplitProps } from '../../hooks/useSplitProps'\nimport type { AllObjectEvents } from '../../types/object'\n\nexport type EllipseProps<T = unknown> = Partial<BaseEllipse & AllObjectEvents> & {\n group?: BaseGroup\n defaultLeft?: number\n defaultTop?: number\n defaultWidth?: number\n defaultHeight?: number\n} & T\n\nconst Ellipse = forwardRef<BaseEllipse | undefined, EllipseProps>(({ group, ...props }, ref) => {\n const [listeners, attributes, defaultValues] = useSplitProps(props)\n\n const instance = useCreateObject({\n Constructor: BaseEllipse,\n defaultValues,\n attributes,\n group,\n listeners,\n })\n
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../../../src/components/Ellipse/index.tsx"],"sourcesContent":["import type { Group as BaseGroup } from 'fabric'\nimport { Ellipse as BaseEllipse } 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 EllipseProps<T = unknown> = Partial<BaseEllipse & AllObjectEvents> & {\n group?: BaseGroup\n defaultLeft?: number\n defaultTop?: number\n defaultWidth?: number\n defaultHeight?: number\n children?: ReactNode\n} & T\n\nconst Ellipse = forwardRef<BaseEllipse | undefined, EllipseProps>(({ group, children, ...props }, ref) => {\n const [listeners, attributes, defaultValues] = useSplitProps(props)\n\n const instance = useCreateObject({\n Constructor: BaseEllipse,\n defaultValues,\n attributes,\n group,\n listeners,\n })\n useImperativeHandle(ref, () => instance, [instance])\n\n return useInstancePosition(instance, children)\n})\n\nexport default memo(Ellipse)\n"],"names":["Ellipse","forwardRef","group","children","props","ref","listeners","attributes","defaultValues","useSplitProps","instance","useCreateObject","BaseEllipse","useImperativeHandle","useInstancePosition","memo"],"mappings":"8TAiBA,MAAMA,EAAUC,EAAkD,CAAC,CAAE,MAAAC,EAAO,SAAAC,EAAU,GAAGC,CAAM,EAAGC,IAAQ,CACxG,KAAM,CAACC,EAAWC,EAAYC,CAAa,EAAIC,EAAcL,CAAK,EAE5DM,EAAWC,EAAgB,CAC/B,YAAaC,EACb,cAAAJ,EACA,WAAAD,EACA,MAAAL,EACA,UAAAI,CACF,CAAC,EACD,OAAAO,EAAoBR,EAAK,IAAMK,EAAU,CAACA,CAAQ,CAAC,EAE5CI,EAAoBJ,EAAUP,CAAQ,CAC/C,CAAC,EAED,MAAeY,EAAKf,CAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../../../../src/components/Group/index.tsx"],"sourcesContent":["import type { GroupEvents, GroupProps } from 'fabric'\nimport { Group as BaseGroup } from 'fabric'\nimport { Children, cloneElement, isValidElement, memo, useEffect, useLayoutEffect, useState } from 'react'\nimport { useDidUpdate } from '../../hooks/useDidUpdate'\nimport { useSplitProps } from '../../hooks/useSplitProps'\nimport { useStoreApi } from '../../hooks/useStore'\nimport type { AllEvents } from '../../types/canvas'\nimport { bindEvents } from '../../utils/events'\n\nexport type MyGroupProps = Partial<GroupProps & AllEvents<GroupEvents>> & {\n children: React.ReactElement<{ group?: BaseGroup }>[] | React.ReactElement<{ group?: BaseGroup }>\n controlsVisibility?: {\n ml?: boolean\n mt?: boolean\n mr?: boolean\n mb?: boolean\n mtr?: boolean\n tl?: boolean\n tr?: boolean\n bl?: boolean\n br?: boolean\n }\n}\n\nconst Group = memo(({ children, controlsVisibility, ...props }: MyGroupProps) => {\n const store = useStoreApi()\n const [instance, setInstance] = useState<BaseGroup | null>(null)\n\n const [listeners, attributes] = useSplitProps(props)\n\n // 创建 Group 实例,但不立即添加到 canvas\n useLayoutEffect(() => {\n const newInstance = new BaseGroup([], {\n ...attributes,\n })\n setInstance(newInstance)\n\n return () => {\n const { canvas } = store.getState()\n if (newInstance && canvas) {\n canvas.remove(newInstance)\n }\n setInstance(null)\n }\n
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../../../src/components/Group/index.tsx"],"sourcesContent":["import type { GroupEvents, GroupProps } from 'fabric'\nimport { Group as BaseGroup } from 'fabric'\nimport { Children, cloneElement, isValidElement, memo, useEffect, useLayoutEffect, useState } from 'react'\nimport { useDidUpdate } from '../../hooks/useDidUpdate'\nimport { useSplitProps } from '../../hooks/useSplitProps'\nimport { useStoreApi } from '../../hooks/useStore'\nimport type { AllEvents } from '../../types/canvas'\nimport { bindEvents } from '../../utils/events'\n\nexport type MyGroupProps = Partial<GroupProps & AllEvents<GroupEvents>> & {\n children: React.ReactElement<{ group?: BaseGroup }>[] | React.ReactElement<{ group?: BaseGroup }>\n controlsVisibility?: {\n ml?: boolean\n mt?: boolean\n mr?: boolean\n mb?: boolean\n mtr?: boolean\n tl?: boolean\n tr?: boolean\n bl?: boolean\n br?: boolean\n }\n}\n\nconst Group = memo(({ children, controlsVisibility, ...props }: MyGroupProps) => {\n const store = useStoreApi()\n const [instance, setInstance] = useState<BaseGroup | null>(null)\n\n const [listeners, attributes] = useSplitProps(props)\n\n // 创建 Group 实例,但不立即添加到 canvas\n useLayoutEffect(() => {\n const newInstance = new BaseGroup([], {\n ...attributes,\n })\n setInstance(newInstance)\n\n return () => {\n const { canvas } = store.getState()\n if (newInstance && canvas) {\n canvas.remove(newInstance)\n }\n setInstance(null)\n }\n }, [store])\n\n // 等待子元素添加完成后,再将 group 添加到 canvas\n useEffect(() => {\n const { canvas } = store.getState()\n if (!instance || !canvas) return\n\n canvas.add(instance)\n }, [store, instance])\n\n // 单独处理事件绑定\n useEffect(() => {\n if (!instance) return\n\n const cleanup = bindEvents(instance, listeners)\n return cleanup\n }, [instance, listeners])\n\n // 专门处理 setControlsVisibility\n useEffect(() => {\n if (!instance || !controlsVisibility) return\n instance.setControlsVisibility(controlsVisibility)\n }, [instance, controlsVisibility])\n\n // 处理属性更新\n useDidUpdate(() => {\n const { canvas } = store.getState()\n if (!instance || !canvas) return\n\n instance.set(attributes)\n instance.setCoords()\n canvas.requestRenderAll()\n }, [attributes])\n\n return (\n <>\n {instance &&\n Children.map(children, child => {\n if (isValidElement(child)) {\n return cloneElement(child, {\n group: instance,\n })\n }\n return null\n })}\n </>\n )\n})\n\nexport default Group\n"],"names":["Group","memo","children","controlsVisibility","props","store","useStoreApi","instance","setInstance","useState","listeners","attributes","useSplitProps","useLayoutEffect","newInstance","BaseGroup","canvas","useEffect","bindEvents","useDidUpdate","jsx","Fragment","Children","child","isValidElement","cloneElement"],"mappings":"gdAwBMA,EAAQC,EAAK,CAAC,CAAE,SAAAC,EAAU,mBAAAC,EAAoB,GAAGC,CAAM,IAAoB,CAC/E,MAAMC,EAAQC,IACR,CAACC,EAAUC,CAAW,EAAIC,EAA2B,IAAI,EAEzD,CAACC,EAAWC,CAAU,EAAIC,EAAcR,CAAK,EAGnD,OAAAS,EAAgB,IAAM,CACpB,MAAMC,EAAc,IAAIC,EAAU,CAAA,EAAI,CACpC,GAAGJ,CACL,CAAC,EACD,OAAAH,EAAYM,CAAW,EAEhB,IAAM,CACX,KAAM,CAAE,OAAAE,CAAO,EAAIX,EAAM,SAAS,EAC9BS,GAAeE,GACjBA,EAAO,OAAOF,CAAW,EAE3BN,EAAY,IAAI,CAClB,CACF,EAAG,CAACH,CAAK,CAAC,EAGVY,EAAU,IAAM,CACd,KAAM,CAAE,OAAAD,CAAO,EAAIX,EAAM,SAAS,EAC9B,CAACE,GAAY,CAACS,GAElBA,EAAO,IAAIT,CAAQ,CACrB,EAAG,CAACF,EAAOE,CAAQ,CAAC,EAGpBU,EAAU,IACHV,EAEWW,EAAWX,EAAUG,CAAS,EAF/B,OAId,CAACH,EAAUG,CAAS,CAAC,EAGxBO,EAAU,IAAM,CACV,CAACV,GAAY,CAACJ,GAClBI,EAAS,sBAAsBJ,CAAkB,CACnD,EAAG,CAACI,EAAUJ,CAAkB,CAAC,EAGjCgB,EAAa,IAAM,CACjB,KAAM,CAAE,OAAAH,CAAO,EAAIX,EAAM,SAAS,EAC9B,CAACE,GAAY,CAACS,IAElBT,EAAS,IAAII,CAAU,EACvBJ,EAAS,UACTS,EAAAA,EAAO,iBAAiB,EAC1B,EAAG,CAACL,CAAU,CAAC,EAGbS,EAAAC,EAAA,CACG,SAAAd,GACCe,EAAS,IAAIpB,EAAUqB,GACjBC,EAAeD,CAAK,EACfE,EAAaF,EAAO,CACzB,MAAOhB,CACT,CAAC,EAEI,IACR,CACL,CAAA,CAEJ,CAAC"}
|
|
@@ -0,0 +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};
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import{FabricImage as l}from"fabric";import{forwardRef as v,useRef as t,useEffect as p,useImperativeHandle as I,memo as R}from"react";import{useStoreApi as h}from"../../hooks/useStore.mjs";import{useInstancePosition as x}from"../../hooks/useInstancePosition.mjs";const E=v(({group:n,src:o,onLoad:c,children:d,...u},g)=>{const e=t(),s=t(c),m=h(),i=t(u);return p(()=>{s.current=c,i.current=u}),p(()=>{const{canvas:a}=m.getState();if(!a?.getElement())return;const f=n??a;return l.fromURL(o,{crossOrigin:"anonymous"}).then(r=>{e.current=r,r.set(i.current),s.current?.(r),f.add(r)}),()=>{e.current&&f?.remove(e.current)}},[o,m,n]),I(g,()=>e.current),x(e.current,d)});var F=R(E);export{F as default};
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../../../src/components/Image/index.tsx"],"sourcesContent":["import type { ImageProps as FabricImageProps, ObjectEvents, SerializedImageProps } from 'fabric'\nimport { FabricImage } from 'fabric'\nimport type { Group as BaseGroup } from 'fabric'\nimport { forwardRef, memo, useEffect, useImperativeHandle, useRef, type ReactNode } from 'react'\nimport { useStoreApi } from '../../hooks/useStore'\nimport { useInstancePosition } from '../../hooks/useInstancePosition'\n\nexport type ImageProps = Partial<FabricImageProps> & {\n src: string\n group?: BaseGroup\n onLoad?: (imageSource: FabricImage<Partial<ImageProps>, SerializedImageProps, ObjectEvents>) => void\n children?: ReactNode\n}\n\nconst Image = forwardRef<FabricImage | undefined, ImageProps>(({ group, src, onLoad, children, ...options }, ref) => {\n const instanceRef = useRef<FabricImage>()\n const onLoadRef = useRef(onLoad)\n const store = useStoreApi()\n const optionsRef = useRef(options)\n\n // 更新 onLoadRef\n useEffect(() => {\n onLoadRef.current = onLoad\n optionsRef.current = options\n })\n\n // 只在 src 改变时初始化 image\n useEffect(() => {\n const { canvas } = store.getState()\n if (!canvas?.getElement()) return\n\n const parent = group ?? canvas\n\n FabricImage.fromURL(src, { crossOrigin: 'anonymous' }).then(imageSource => {\n instanceRef.current = imageSource\n imageSource.set(optionsRef.current)\n onLoadRef.current?.(imageSource)\n parent.add(imageSource)\n })\n\n return () => {\n if (instanceRef.current) {\n parent?.remove(instanceRef.current)\n }\n }\n }, [src, store, group]) // 只包含初始化需要的依赖\n\n useImperativeHandle(ref, () => instanceRef.current)\n\n return useInstancePosition(instanceRef.current, children)\n})\n\nexport default memo(Image)\n"],"names":["Image","forwardRef","group","src","onLoad","children","options","ref","instanceRef","useRef","onLoadRef","store","useStoreApi","optionsRef","useEffect","canvas","parent","FabricImage","imageSource","useImperativeHandle","useInstancePosition","memo"],"mappings":"oRAcA,MAAMA,EAAQC,EAAgD,CAAC,CAAE,MAAAC,EAAO,IAAAC,EAAK,OAAAC,EAAQ,SAAAC,EAAU,GAAGC,CAAQ,EAAGC,IAAQ,CACnH,MAAMC,EAAcC,EAAoB,EAClCC,EAAYD,EAAOL,CAAM,EACzBO,EAAQC,EAAY,EACpBC,EAAaJ,EAAOH,CAAO,EAGjC,OAAAQ,EAAU,IAAM,CACdJ,EAAU,QAAUN,EACpBS,EAAW,QAAUP,CACvB,CAAC,EAGDQ,EAAU,IAAM,CACd,KAAM,CAAE,OAAAC,CAAO,EAAIJ,EAAM,SAAS,EAClC,GAAI,CAACI,GAAQ,WAAW,EAAG,OAE3B,MAAMC,EAASd,GAASa,EAExB,OAAAE,EAAY,QAAQd,EAAK,CAAE,YAAa,WAAY,CAAC,EAAE,KAAKe,GAAe,CACzEV,EAAY,QAAUU,EACtBA,EAAY,IAAIL,EAAW,OAAO,EAClCH,EAAU,UAAUQ,CAAW,EAC/BF,EAAO,IAAIE,CAAW,CACxB,CAAC,EAEM,IAAM,CACPV,EAAY,SACdQ,GAAQ,OAAOR,EAAY,OAAO,CAEtC,CACF,EAAG,CAACL,EAAKQ,EAAOT,CAAK,CAAC,EAEtBiB,EAAoBZ,EAAK,IAAMC,EAAY,OAAO,EAE3CY,EAAoBZ,EAAY,QAASH,CAAQ,CAC1D,CAAC,EAED,IAAegB,EAAAA,EAAKrB,CAAK"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{Line as
|
|
1
|
+
"use client";import{Line as c}from"fabric";import{forwardRef as f,useImperativeHandle as l,memo as d}from"react";import{useCreateObject as x}from"../../hooks/useCreateObject.mjs";import{useSplitProps as P}from"../../hooks/useSplitProps.mjs";import{useInstancePosition as b}from"../../hooks/useInstancePosition.mjs";const g=f(({group:e,x1:t,y1:o,x2:m,y2:s,children:i,...n},p)=>{const[a,u]=P(n),r=x({Constructor:c,param:[t,o,m,s],attributes:u,group:e,listeners:a});return l(p,()=>r,[r]),b(r,i)});var v=d(g);export{v as default};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../../../../src/components/Line/index.tsx"],"sourcesContent":["import type { Group as BaseGroup } from 'fabric'\nimport { Line as BaseLine } from 'fabric'\nimport { forwardRef, memo, useImperativeHandle } from 'react'\nimport { useCreateObject } from '../../hooks/useCreateObject'\nimport { useSplitProps } from '../../hooks/useSplitProps'\nimport type { AllObjectEvents } from '../../types/object'\n\nexport type Handle = BaseLine | undefined\n\nexport type LineProps<T = unknown> = Partial<ConstructorParameters<typeof BaseLine>[1] & AllObjectEvents> & {\n group?: BaseGroup\n path?: string\n} & T\n\nconst Line = forwardRef<Handle, LineProps>(({ group, x1, y1, x2, y2, ...props }, ref) => {\n const [listeners, attributes] = useSplitProps(props)\n\n const instance = useCreateObject({\n Constructor: BaseLine,\n param: [x1, y1, x2, y2],\n attributes,\n group,\n listeners,\n })\n\n useImperativeHandle(ref, () => instance, [instance])\n\n return
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../../../src/components/Line/index.tsx"],"sourcesContent":["import type { Group as BaseGroup } from 'fabric'\nimport { Line as BaseLine } 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 Handle = BaseLine | undefined\n\nexport type LineProps<T = unknown> = Partial<ConstructorParameters<typeof BaseLine>[1] & AllObjectEvents> & {\n group?: BaseGroup\n path?: string\n children?: ReactNode\n} & T\n\nconst Line = forwardRef<Handle, LineProps>(({ group, x1, y1, x2, y2, children, ...props }, ref) => {\n const [listeners, attributes] = useSplitProps(props)\n\n const instance = useCreateObject({\n Constructor: BaseLine,\n param: [x1, y1, x2, y2],\n attributes,\n group,\n listeners,\n })\n\n useImperativeHandle(ref, () => instance, [instance])\n\n return useInstancePosition(instance, children)\n})\n\nexport default memo(Line)\n"],"names":["Line","forwardRef","group","x1","y1","x2","y2","children","props","ref","listeners","attributes","useSplitProps","instance","useCreateObject","BaseLine","useImperativeHandle","useInstancePosition","memo"],"mappings":"2TAgBA,MAAMA,EAAOC,EAA8B,CAAC,CAAE,MAAAC,EAAO,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,GAAAC,EAAI,SAAAC,EAAU,GAAGC,CAAM,EAAGC,IAAQ,CACjG,KAAM,CAACC,EAAWC,CAAU,EAAIC,EAAcJ,CAAK,EAE7CK,EAAWC,EAAgB,CAC/B,YAAaC,EACb,MAAO,CAACZ,EAAIC,EAAIC,EAAIC,CAAE,EACtB,WAAAK,EACA,MAAAT,EACA,UAAAQ,CACF,CAAC,EAED,OAAAM,EAAoBP,EAAK,IAAMI,EAAU,CAACA,CAAQ,CAAC,EAE5CI,EAAoBJ,EAAUN,CAAQ,CAC/C,CAAC,EAED,IAAeW,EAAAA,EAAKlB,CAAI"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use client";import{jsxs as o,jsx as t}from"react/jsx-runtime";import{useStore as r}from"../../hooks/useStore.mjs";const i=()=>r(e=>e.loading)?o("div",{style:{position:"absolute",bottom:0,left:0,right:0,top:0,zIndex:40,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",overflow:"hidden"},children:[t("span",{style:{width:"48px",height:"48px",border:"5px solid #04aa65",borderBottomColor:"transparent",borderRadius:"50%",display:"inline-block",boxSizing:"border-box",animation:"rotation 1s linear infinite"}}),t("style",{children:`
|
|
2
|
+
@keyframes rotation {
|
|
3
|
+
0% {
|
|
4
|
+
transform: rotate(0deg);
|
|
5
|
+
}
|
|
6
|
+
100% {
|
|
7
|
+
transform: rotate(360deg);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
`})]}):null;export{i as default};
|
|
11
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../../../src/components/Loading/index.tsx"],"sourcesContent":["import { useStore } from '../../hooks/useStore'\n\n// bg-[hsla(221,14%,4%,0.6)\nconst Loading = () => {\n const loading = useStore(state => state.loading)\n\n return loading ? (\n <div\n style={{\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n top: 0,\n zIndex: 40,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'hidden',\n }}\n >\n <span\n style={{\n width: '48px',\n height: '48px',\n border: '5px solid #04aa65',\n borderBottomColor: 'transparent',\n borderRadius: '50%',\n display: 'inline-block',\n boxSizing: 'border-box',\n animation: 'rotation 1s linear infinite',\n }}\n ></span>\n <style>\n {`\n @keyframes rotation {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n }\n `}\n </style>\n </div>\n ) : null\n}\n\nexport default Loading\n"],"names":["Loading","useStore","state","jsxs","jsx"],"mappings":"mHAGMA,MAAAA,EAAU,IACEC,EAASC,GAASA,EAAM,OAAO,EAG7CC,EAAC,MACC,CAAA,MAAO,CACL,SAAU,WACV,OAAQ,EACR,KAAM,EACN,MAAO,EACP,IAAK,EACL,OAAQ,GACR,QAAS,OACT,cAAe,SACf,WAAY,SACZ,eAAgB,SAChB,SAAU,QACZ,EAEA,SAAA,CAAAC,EAAC,OAAA,CACC,MAAO,CACL,MAAO,OACP,OAAQ,OACR,OAAQ,oBACR,kBAAmB,cACnB,aAAc,MACd,QAAS,eACT,UAAW,aACX,UAAW,6BACb,CACD,CAAA,EACDA,EAAC,QACE,CAAA,SAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAUH,CAAA,CAAA,CAAA,CACF,EACE"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{createPortal as u}from"react-dom";import{
|
|
1
|
+
"use client";import{createPortal as u}from"react-dom";import{forwardRef as l,useRef as f,useCallback as d,useEffect as m}from"react";import{useStore as p}from"../../hooks/useStore.mjs";const v=o=>o.domNode?.querySelector(".react-fabric__canvas"),b=l(({children:o,className:s,onClick:n},t)=>{const a=p(v),e=f(),i=d(r=>{r!==e.current&&(e.current=r||void 0,typeof t=="function"?t(r):t&&(t.current=r))},[t]);if(m(()=>()=>{e.current&&(e.current.remove(),e.current=void 0)},[]),!a||e.current)return e.current?u(o,e.current):null;const c=document.createElement("div");return c.className=`react-fabric__portal ${s}`,n&&c.addEventListener("click",r=>{r.stopPropagation(),n(r)}),a.appendChild(c),i(c),u(o,c)});export{b as default};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../../../../src/components/NodeToolbarPortal/index.tsx"],"sourcesContent":["import { createPortal } from 'react-dom'\nimport
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../../../src/components/NodeToolbarPortal/index.tsx"],"sourcesContent":["import { createPortal } from 'react-dom'\nimport type { ReactNode } from 'react'\nimport { forwardRef, useCallback, useEffect, useRef } from 'react'\nimport { useStore } from '../../hooks/useStore'\nimport type { ReactFabricState } from '../../types/store'\n\nconst selector = (state: ReactFabricState) => state.domNode?.querySelector('.react-fabric__canvas')\n\ninterface Props {\n children: ReactNode\n className?: string\n onClick?: (e: React.MouseEvent) => void\n}\n\nconst NodeToolbarPortal = forwardRef<HTMLDivElement, Props>(({ children, className, onClick }, forwardRef) => {\n const wrapperRef = useStore(selector)\n const containerRef = useRef<HTMLDivElement>()\n\n // 使用 useCallback 创建稳定的 ref 回调\n const refCallback = useCallback(\n (node: HTMLDivElement | null) => {\n if (node !== containerRef.current) {\n containerRef.current = node || undefined\n\n if (typeof forwardRef === 'function') {\n forwardRef(node)\n } else if (forwardRef) {\n forwardRef.current = node\n }\n }\n },\n [forwardRef],\n )\n\n // 组件卸载时清理\n useEffect(() => {\n return () => {\n if (containerRef.current) {\n containerRef.current.remove()\n containerRef.current = undefined\n }\n }\n }, [])\n\n // 如果已经有 container 或没有 wrapper,直接返回\n if (!wrapperRef || containerRef.current) {\n return containerRef.current ? createPortal(children, containerRef.current) : null\n }\n\n // 创建 DOM 元素\n const div = document.createElement('div')\n div.className = `react-fabric__portal ${className}`\n if (onClick) {\n div.addEventListener('click', e => {\n e.stopPropagation()\n onClick(e as any)\n })\n }\n wrapperRef.appendChild(div)\n refCallback(div)\n\n return createPortal(children, div)\n})\n\nexport default NodeToolbarPortal\n"],"names":["selector","state","NodeToolbarPortal","forwardRef","children","className","onClick","wrapperRef","useStore","containerRef","useRef","refCallback","useCallback","node","useEffect","createPortal","div","e"],"mappings":"yLAMA,MAAMA,EAAYC,GAA4BA,EAAM,SAAS,cAAc,uBAAuB,EAQ5FC,EAAoBC,EAAkC,CAAC,CAAE,SAAAC,EAAU,UAAAC,EAAW,QAAAC,CAAQ,EAAGH,IAAe,CAC5G,MAAMI,EAAaC,EAASR,CAAQ,EAC9BS,EAAeC,EAAAA,EAGfC,EAAcC,EACjBC,GAAgC,CAC3BA,IAASJ,EAAa,UACxBA,EAAa,QAAUI,GAAQ,OAE3B,OAAOV,GAAe,WACxBA,EAAWU,CAAI,EACNV,IACTA,EAAW,QAAUU,GAG3B,EACA,CAACV,CAAU,CACb,EAaA,GAVAW,EAAU,IACD,IAAM,CACPL,EAAa,UACfA,EAAa,QAAQ,SACrBA,EAAa,QAAU,OAE3B,EACC,CAAA,CAAE,EAGD,CAACF,GAAcE,EAAa,QAC9B,OAAOA,EAAa,QAAUM,EAAaX,EAAUK,EAAa,OAAO,EAAI,KAI/E,MAAMO,EAAM,SAAS,cAAc,KAAK,EACxC,OAAAA,EAAI,UAAY,wBAAwBX,CAAS,GAC7CC,GACFU,EAAI,iBAAiB,QAASC,GAAK,CACjCA,EAAE,gBACFX,EAAAA,EAAQW,CAAQ,CAClB,CAAC,EAEHV,EAAW,YAAYS,CAAG,EAC1BL,EAAYK,CAAG,EAERD,EAAaX,EAAUY,CAAG,CACnC,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{jsx as o,Fragment as p}from"react/jsx-runtime";import{memo as
|
|
1
|
+
"use client";import{jsx as o,Fragment as p}from"react/jsx-runtime";import{memo as f}from"react";import s from"../Path/index.mjs";import e from"../Text/index.mjs";import a from"../Rect/index.mjs";import c from"../Line/index.mjs";import l from"../IText/index.mjs";const x=({objects:t})=>{const m={rect:a,path:s,text:e,line:c,"i-text":e,itext:l};return t?o(p,{children:t?.map(({type:i,...n})=>{const r=m[i.toLowerCase()];return r?o(r,{...n}):null})}):null};var u=f(x);export{u as default};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -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'\n\nexport type ObjectsProps = {\n objects: { type: string;
|
|
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,2 +1,2 @@
|
|
|
1
|
-
"use client";import{Path as
|
|
1
|
+
"use client";import{Path as i}from"fabric";import{forwardRef as n,useImperativeHandle as u,memo as f}from"react";import{useCreateObject as c}from"../../hooks/useCreateObject.mjs";import{useSplitProps as l}from"../../hooks/useSplitProps.mjs";import{useInstancePosition as d}from"../../hooks/useInstancePosition.mjs";const h=n(({group:t,path:e="M 0 0",children:o,...s},m)=>{const[p,a]=l(s),r=c({Constructor:i,param:e,attributes:a,group:t,listeners:p});return u(m,()=>r,[r]),d(r,o)});var P=f(h);export{P as default};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../../../../src/components/Path/index.tsx"],"sourcesContent":["import type { Group as BaseGroup } from 'fabric'\nimport { Path as BasePath } from 'fabric'\nimport { forwardRef, memo, useImperativeHandle } from 'react'\nimport { useCreateObject } from '../../hooks/useCreateObject'\nimport { useSplitProps } from '../../hooks/useSplitProps'\nimport type { AllObjectEvents } from '../../types/object'\n\nexport type Handle = BasePath | undefined\n\nexport type PathProps<T = unknown> = Partial<ConstructorParameters<typeof BasePath>[1] & AllObjectEvents> & {\n group?: BaseGroup\n path?: string\n} & T\n\nconst Path = forwardRef<Handle, PathProps>(({ group, path = 'M 0 0', ...props }, ref) => {\n const [listeners, attributes] = useSplitProps(props)\n\n const instance = useCreateObject({\n Constructor: BasePath,\n param: path,\n attributes,\n group,\n listeners,\n })\n\n useImperativeHandle(ref, () => instance, [instance])\n\n return
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../../../src/components/Path/index.tsx"],"sourcesContent":["import type { Group as BaseGroup } from 'fabric'\nimport { Path as BasePath } 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 Handle = BasePath | undefined\n\nexport type PathProps<T = unknown> = Partial<ConstructorParameters<typeof BasePath>[1] & AllObjectEvents> & {\n group?: BaseGroup\n path?: string\n children?: ReactNode\n} & T\n\nconst Path = forwardRef<Handle, PathProps>(({ group, path = 'M 0 0', children, ...props }, ref) => {\n const [listeners, attributes] = useSplitProps(props)\n\n const instance = useCreateObject({\n Constructor: BasePath,\n param: path,\n attributes,\n group,\n listeners,\n })\n\n useImperativeHandle(ref, () => instance, [instance])\n\n return useInstancePosition(instance, children)\n})\n\nexport default memo(Path)\n"],"names":["Path","forwardRef","group","path","children","props","ref","listeners","attributes","useSplitProps","instance","useCreateObject","BasePath","useImperativeHandle","useInstancePosition","memo"],"mappings":"2TAgBA,MAAMA,EAAOC,EAA8B,CAAC,CAAE,MAAAC,EAAO,KAAAC,EAAO,QAAS,SAAAC,EAAU,GAAGC,CAAM,EAAGC,IAAQ,CACjG,KAAM,CAACC,EAAWC,CAAU,EAAIC,EAAcJ,CAAK,EAE7CK,EAAWC,EAAgB,CAC/B,YAAaC,EACb,MAAOT,EACP,WAAAK,EACA,MAAAN,EACA,UAAAK,CACF,CAAC,EAED,OAAAM,EAAoBP,EAAK,IAAMI,EAAU,CAACA,CAAQ,CAAC,EAE5CI,EAAoBJ,EAAUN,CAAQ,CAC/C,CAAC,EAED,MAAeW,EAAKf,CAAI"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{Rect as
|
|
1
|
+
"use client";import{Rect as a}from"fabric";import{forwardRef as n,useImperativeHandle as p,memo as f}from"react";import{useCreateObject as c}from"../../hooks/useCreateObject.mjs";import{useSplitProps as l}from"../../hooks/useSplitProps.mjs";import{useInstancePosition as d}from"../../hooks/useInstancePosition.mjs";const b=n(({group:r,children:t,...o},s)=>{const[i,m,u]=l(o),e=c({Constructor:a,defaultValues:u,attributes:m,group:r,listeners:i});return p(s,()=>e,[e]),d(e,t)});var g=f(b);export{g as default};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|