@nice2dev/ui-graphics 1.1.0 → 1.1.1
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/dist/cjs/animation/AnimatedPerson.js +69 -63
- package/dist/cjs/animation/AnimatedPerson.js.map +1 -1
- package/dist/cjs/animation/AnimationEditor.js +27 -20
- package/dist/cjs/animation/AnimationEditor.js.map +1 -1
- package/dist/cjs/animation/Audience.js +17 -11
- package/dist/cjs/animation/Audience.js.map +1 -1
- package/dist/cjs/animation/BodyRenderer.js +7 -7
- package/dist/cjs/animation/BodyRenderer.js.map +1 -1
- package/dist/cjs/animation/animationHelper.js +83 -52
- package/dist/cjs/animation/animationHelper.js.map +1 -1
- package/dist/cjs/animation/characterTypes.js +171 -30
- package/dist/cjs/animation/characterTypes.js.map +1 -1
- package/dist/cjs/animation/choreoDSL.js +114 -62
- package/dist/cjs/animation/choreoDSL.js.map +1 -1
- package/dist/cjs/animation/karaokeIntegration.js +10 -11
- package/dist/cjs/animation/karaokeIntegration.js.map +1 -1
- package/dist/cjs/animation/lottieExport.js +15 -9
- package/dist/cjs/animation/lottieExport.js.map +1 -1
- package/dist/cjs/animation/motionPath.js +125 -30
- package/dist/cjs/animation/motionPath.js.map +1 -1
- package/dist/cjs/animation/physics.js +157 -57
- package/dist/cjs/animation/physics.js.map +1 -1
- package/dist/cjs/animation/rig/RigPlayer.js +7 -6
- package/dist/cjs/animation/rig/RigPlayer.js.map +1 -1
- package/dist/cjs/animation/rig/RiggedBody.js +7 -7
- package/dist/cjs/animation/rig/RiggedBody.js.map +1 -1
- package/dist/cjs/animation/rig/choreoRigBridge.js +52 -29
- package/dist/cjs/animation/rig/choreoRigBridge.js.map +1 -1
- package/dist/cjs/animation/rig/poseOps.js +6 -3
- package/dist/cjs/animation/rig/poseOps.js.map +1 -1
- package/dist/cjs/animation/shapes/arms.js +7 -6
- package/dist/cjs/animation/shapes/arms.js.map +1 -1
- package/dist/cjs/animation/shapes/eyes.js +31 -18
- package/dist/cjs/animation/shapes/eyes.js.map +1 -1
- package/dist/cjs/animation/shapes/hair.js +39 -23
- package/dist/cjs/animation/shapes/hair.js.map +1 -1
- package/dist/cjs/animation/shapes/heads.js +47 -29
- package/dist/cjs/animation/shapes/heads.js.map +1 -1
- package/dist/cjs/animation/shapes/headwear.js +26 -14
- package/dist/cjs/animation/shapes/headwear.js.map +1 -1
- package/dist/cjs/animation/shapes/legs.js +7 -6
- package/dist/cjs/animation/shapes/legs.js.map +1 -1
- package/dist/cjs/animation/shapes/mouths.js +28 -18
- package/dist/cjs/animation/shapes/mouths.js.map +1 -1
- package/dist/cjs/animation/shapes/noses.js +18 -9
- package/dist/cjs/animation/shapes/noses.js.map +1 -1
- package/dist/cjs/animation/shapes/outfits.js +25 -14
- package/dist/cjs/animation/shapes/outfits.js.map +1 -1
- package/dist/cjs/animation/shapes/torsos.js +5 -4
- package/dist/cjs/animation/shapes/torsos.js.map +1 -1
- package/dist/cjs/animation/spineExport.js +33 -26
- package/dist/cjs/animation/spineExport.js.map +1 -1
- package/dist/cjs/core/LocalUI.js +16 -16
- package/dist/cjs/core/LocalUI.js.map +1 -1
- package/dist/cjs/core/NiceBrushEngine.js +205 -69
- package/dist/cjs/core/NiceBrushEngine.js.map +1 -1
- package/dist/cjs/core/collaboration.js +35 -21
- package/dist/cjs/core/collaboration.js.map +1 -1
- package/dist/cjs/core/colorBlindness.js +64 -24
- package/dist/cjs/core/colorBlindness.js.map +1 -1
- package/dist/cjs/core/dragDrop.js +34 -26
- package/dist/cjs/core/dragDrop.js.map +1 -1
- package/dist/cjs/core/fixes.js +26 -14
- package/dist/cjs/core/fixes.js.map +1 -1
- package/dist/cjs/core/gridGuides.js +24 -16
- package/dist/cjs/core/gridGuides.js.map +1 -1
- package/dist/cjs/core/historyVisual.js +42 -23
- package/dist/cjs/core/historyVisual.js.map +1 -1
- package/dist/cjs/core/integrations.js +65 -48
- package/dist/cjs/core/integrations.js.map +1 -1
- package/dist/cjs/core/minimap.js +40 -24
- package/dist/cjs/core/minimap.js.map +1 -1
- package/dist/cjs/core/plugins.js +10 -6
- package/dist/cjs/core/plugins.js.map +1 -1
- package/dist/cjs/core/rtl.js +32 -27
- package/dist/cjs/core/rtl.js.map +1 -1
- package/dist/cjs/core/shortcuts.js +77 -39
- package/dist/cjs/core/shortcuts.js.map +1 -1
- package/dist/cjs/core/theme.js +68 -61
- package/dist/cjs/core/theme.js.map +1 -1
- package/dist/cjs/core/yjsCollaboration.js +61 -28
- package/dist/cjs/core/yjsCollaboration.js.map +1 -1
- package/dist/cjs/font/NiceFontEditor.js +160 -57
- package/dist/cjs/font/NiceFontEditor.js.map +1 -1
- package/dist/cjs/font/fontFormatUtils.js +37 -24
- package/dist/cjs/font/fontFormatUtils.js.map +1 -1
- package/dist/cjs/game/GameAsset2dEditor.js +73 -60
- package/dist/cjs/game/GameAsset2dEditor.js.map +1 -1
- package/dist/cjs/game/gameAssetUtils.js +18 -13
- package/dist/cjs/game/gameAssetUtils.js.map +1 -1
- package/dist/cjs/game/useGameAssetEditor.js +160 -143
- package/dist/cjs/game/useGameAssetEditor.js.map +1 -1
- package/dist/cjs/icon/NiceIconEditor.js +329 -106
- package/dist/cjs/icon/NiceIconEditor.js.map +1 -1
- package/dist/cjs/packages/ui/dist/NiceErrorBoundary-D75yr_WE.js +572 -0
- package/dist/cjs/packages/ui/dist/NiceErrorBoundary-D75yr_WE.js.map +1 -0
- package/dist/cjs/packages/ui/dist/NiceForm-CKoJA6NG.js +4979 -0
- package/dist/cjs/packages/ui/dist/NiceForm-CKoJA6NG.js.map +1 -0
- package/dist/cjs/packages/ui/dist/NiceModal-1QX7NhyH.js +98 -0
- package/dist/cjs/packages/ui/dist/NiceModal-1QX7NhyH.js.map +1 -0
- package/dist/cjs/packages/ui/dist/NiceModuleLifecyclePanel-CMrPbSw9.js +5244 -0
- package/dist/cjs/packages/ui/dist/NiceModuleLifecyclePanel-CMrPbSw9.js.map +1 -0
- package/dist/cjs/packages/ui/dist/NicePagination-DbE-uOkl.js +174 -0
- package/dist/cjs/packages/ui/dist/NicePagination-DbE-uOkl.js.map +1 -0
- package/dist/cjs/packages/ui/dist/NicePinCodeInput-B8cI8zu8.js +10459 -0
- package/dist/cjs/packages/ui/dist/NicePinCodeInput-B8cI8zu8.js.map +1 -0
- package/dist/cjs/packages/ui/dist/NiceSavedQueryPanel-CZ5bYOe_.js +6313 -0
- package/dist/cjs/packages/ui/dist/NiceSavedQueryPanel-CZ5bYOe_.js.map +1 -0
- package/dist/cjs/packages/ui/dist/NiceTabs-DzLHzwuA.js +1639 -0
- package/dist/cjs/packages/ui/dist/NiceTabs-DzLHzwuA.js.map +1 -0
- package/dist/cjs/packages/ui/dist/NiceWindow-DeC83yfE.js +807 -0
- package/dist/cjs/packages/ui/dist/NiceWindow-DeC83yfE.js.map +1 -0
- package/dist/cjs/packages/ui/dist/charts-BAS21jkC.js +3833 -0
- package/dist/cjs/packages/ui/dist/charts-BAS21jkC.js.map +1 -0
- package/dist/cjs/packages/ui/dist/core-Da43q-pO.js +11683 -0
- package/dist/cjs/packages/ui/dist/core-Da43q-pO.js.map +1 -0
- package/dist/cjs/packages/ui/dist/index-pAuGTbuB.js +28876 -0
- package/dist/cjs/packages/ui/dist/index-pAuGTbuB.js.map +1 -0
- package/dist/cjs/photo/FilterThumb.js +7 -5
- package/dist/cjs/photo/FilterThumb.js.map +1 -1
- package/dist/cjs/photo/NiceAITools.js +78 -32
- package/dist/cjs/photo/NiceAITools.js.map +1 -1
- package/dist/cjs/photo/PhotoEditor.js +4 -4
- package/dist/cjs/photo/PhotoEditor.js.map +1 -1
- package/dist/cjs/photo/PhotoEditorCanvas.js +56 -22
- package/dist/cjs/photo/PhotoEditorCanvas.js.map +1 -1
- package/dist/cjs/photo/PhotoEditorLeftPanel.js +106 -48
- package/dist/cjs/photo/PhotoEditorLeftPanel.js.map +1 -1
- package/dist/cjs/photo/PhotoEditorToolbar.js +2 -2
- package/dist/cjs/photo/PhotoEditorToolbar.js.map +1 -1
- package/dist/cjs/photo/photoEditorActions.js +27 -18
- package/dist/cjs/photo/photoEditorActions.js.map +1 -1
- package/dist/cjs/photo/photoFilters.js +316 -81
- package/dist/cjs/photo/photoFilters.js.map +1 -1
- package/dist/cjs/photo/photoOverlays.js +521 -165
- package/dist/cjs/photo/photoOverlays.js.map +1 -1
- package/dist/cjs/photo/photoSelection.js +69 -35
- package/dist/cjs/photo/photoSelection.js.map +1 -1
- package/dist/cjs/photo/usePhotoEditor.js +203 -97
- package/dist/cjs/photo/usePhotoEditor.js.map +1 -1
- package/dist/cjs/pixel/HSVPicker.js +32 -19
- package/dist/cjs/pixel/HSVPicker.js.map +1 -1
- package/dist/cjs/pixel/PixelEditor.js +25 -14
- package/dist/cjs/pixel/PixelEditor.js.map +1 -1
- package/dist/cjs/pixel/PixelEditorCanvas.js +2 -2
- package/dist/cjs/pixel/PixelEditorCanvas.js.map +1 -1
- package/dist/cjs/pixel/PixelEditorMenuBar.js +3 -3
- package/dist/cjs/pixel/PixelEditorMenuBar.js.map +1 -1
- package/dist/cjs/pixel/PixelEditorRightPanel.js +28 -8
- package/dist/cjs/pixel/PixelEditorRightPanel.js.map +1 -1
- package/dist/cjs/pixel/PixelEditorStatusBar.js +2 -2
- package/dist/cjs/pixel/PixelEditorStatusBar.js.map +1 -1
- package/dist/cjs/pixel/PixelEditorTimeline.js +3 -4
- package/dist/cjs/pixel/PixelEditorTimeline.js.map +1 -1
- package/dist/cjs/pixel/PixelEditorToolbar.js +3 -3
- package/dist/cjs/pixel/PixelEditorToolbar.js.map +1 -1
- package/dist/cjs/pixel/SpriteGeneratorPanel.js +136 -54
- package/dist/cjs/pixel/SpriteGeneratorPanel.js.map +1 -1
- package/dist/cjs/pixel/asepriteFormat.js +122 -38
- package/dist/cjs/pixel/asepriteFormat.js.map +1 -1
- package/dist/cjs/pixel/characterGeneratorPresets.js +208 -54
- package/dist/cjs/pixel/characterGeneratorPresets.js.map +1 -1
- package/dist/cjs/pixel/pixelEditorExports.js +42 -35
- package/dist/cjs/pixel/pixelEditorExports.js.map +1 -1
- package/dist/cjs/pixel/pixelEditorTypes.js +67 -33
- package/dist/cjs/pixel/pixelEditorTypes.js.map +1 -1
- package/dist/cjs/pixel/pixelEditorUtils.js +62 -38
- package/dist/cjs/pixel/pixelEditorUtils.js.map +1 -1
- package/dist/cjs/pixel/spriteGeneratorCore.js +47 -24
- package/dist/cjs/pixel/spriteGeneratorCore.js.map +1 -1
- package/dist/cjs/pixel/usePixelEditor.js +475 -213
- package/dist/cjs/pixel/usePixelEditor.js.map +1 -1
- package/dist/cjs/texture/Nice3DTexturePainter.js +201 -71
- package/dist/cjs/texture/Nice3DTexturePainter.js.map +1 -1
- package/dist/cjs/ui/NiceUIDesigner.js +280 -91
- package/dist/cjs/ui/NiceUIDesigner.js.map +1 -1
- package/dist/cjs/vector/NiceSvgToCode.js +96 -34
- package/dist/cjs/vector/NiceSvgToCode.js.map +1 -1
- package/dist/cjs/vector/VectorEditor.js +14 -13
- package/dist/cjs/vector/VectorEditor.js.map +1 -1
- package/dist/cjs/vector/VectorEditorMenuBar.js +7 -6
- package/dist/cjs/vector/VectorEditorMenuBar.js.map +1 -1
- package/dist/cjs/vector/VectorEditorRightPanel.js +87 -32
- package/dist/cjs/vector/VectorEditorRightPanel.js.map +1 -1
- package/dist/cjs/vector/VectorEditorShapeRenderer.js +17 -15
- package/dist/cjs/vector/VectorEditorShapeRenderer.js.map +1 -1
- package/dist/cjs/vector/VectorEditorStatusBar.js.map +1 -1
- package/dist/cjs/vector/useVectorEditor.js +312 -122
- package/dist/cjs/vector/useVectorEditor.js.map +1 -1
- package/dist/cjs/vector/vectorBooleanOps.js +60 -42
- package/dist/cjs/vector/vectorBooleanOps.js.map +1 -1
- package/dist/cjs/vector/vectorEditorExport.js +40 -34
- package/dist/cjs/vector/vectorEditorExport.js.map +1 -1
- package/dist/cjs/vector/vectorGradients.js +41 -40
- package/dist/cjs/vector/vectorGradients.js.map +1 -1
- package/dist/esm/animation/AnimatedPerson.js +69 -63
- package/dist/esm/animation/AnimatedPerson.js.map +1 -1
- package/dist/esm/animation/AnimationEditor.js +27 -20
- package/dist/esm/animation/AnimationEditor.js.map +1 -1
- package/dist/esm/animation/Audience.js +17 -11
- package/dist/esm/animation/Audience.js.map +1 -1
- package/dist/esm/animation/BodyRenderer.js +7 -7
- package/dist/esm/animation/BodyRenderer.js.map +1 -1
- package/dist/esm/animation/animationHelper.js +83 -52
- package/dist/esm/animation/animationHelper.js.map +1 -1
- package/dist/esm/animation/characterTypes.js +171 -30
- package/dist/esm/animation/characterTypes.js.map +1 -1
- package/dist/esm/animation/choreoDSL.js +114 -62
- package/dist/esm/animation/choreoDSL.js.map +1 -1
- package/dist/esm/animation/karaokeIntegration.js +10 -11
- package/dist/esm/animation/karaokeIntegration.js.map +1 -1
- package/dist/esm/animation/lottieExport.js +15 -9
- package/dist/esm/animation/lottieExport.js.map +1 -1
- package/dist/esm/animation/motionPath.js +125 -30
- package/dist/esm/animation/motionPath.js.map +1 -1
- package/dist/esm/animation/physics.js +157 -57
- package/dist/esm/animation/physics.js.map +1 -1
- package/dist/esm/animation/rig/RigPlayer.js +7 -6
- package/dist/esm/animation/rig/RigPlayer.js.map +1 -1
- package/dist/esm/animation/rig/RiggedBody.js +7 -7
- package/dist/esm/animation/rig/RiggedBody.js.map +1 -1
- package/dist/esm/animation/rig/choreoRigBridge.js +52 -29
- package/dist/esm/animation/rig/choreoRigBridge.js.map +1 -1
- package/dist/esm/animation/rig/poseOps.js +6 -3
- package/dist/esm/animation/rig/poseOps.js.map +1 -1
- package/dist/esm/animation/shapes/arms.js +7 -6
- package/dist/esm/animation/shapes/arms.js.map +1 -1
- package/dist/esm/animation/shapes/eyes.js +31 -18
- package/dist/esm/animation/shapes/eyes.js.map +1 -1
- package/dist/esm/animation/shapes/hair.js +39 -23
- package/dist/esm/animation/shapes/hair.js.map +1 -1
- package/dist/esm/animation/shapes/heads.js +47 -29
- package/dist/esm/animation/shapes/heads.js.map +1 -1
- package/dist/esm/animation/shapes/headwear.js +26 -14
- package/dist/esm/animation/shapes/headwear.js.map +1 -1
- package/dist/esm/animation/shapes/legs.js +7 -6
- package/dist/esm/animation/shapes/legs.js.map +1 -1
- package/dist/esm/animation/shapes/mouths.js +28 -18
- package/dist/esm/animation/shapes/mouths.js.map +1 -1
- package/dist/esm/animation/shapes/noses.js +18 -9
- package/dist/esm/animation/shapes/noses.js.map +1 -1
- package/dist/esm/animation/shapes/outfits.js +25 -14
- package/dist/esm/animation/shapes/outfits.js.map +1 -1
- package/dist/esm/animation/shapes/torsos.js +5 -4
- package/dist/esm/animation/shapes/torsos.js.map +1 -1
- package/dist/esm/animation/spineExport.js +33 -26
- package/dist/esm/animation/spineExport.js.map +1 -1
- package/dist/esm/core/LocalUI.js +16 -16
- package/dist/esm/core/LocalUI.js.map +1 -1
- package/dist/esm/core/NiceBrushEngine.js +205 -69
- package/dist/esm/core/NiceBrushEngine.js.map +1 -1
- package/dist/esm/core/collaboration.js +35 -21
- package/dist/esm/core/collaboration.js.map +1 -1
- package/dist/esm/core/colorBlindness.js +64 -24
- package/dist/esm/core/colorBlindness.js.map +1 -1
- package/dist/esm/core/dragDrop.js +34 -26
- package/dist/esm/core/dragDrop.js.map +1 -1
- package/dist/esm/core/fixes.js +26 -14
- package/dist/esm/core/fixes.js.map +1 -1
- package/dist/esm/core/gridGuides.js +24 -16
- package/dist/esm/core/gridGuides.js.map +1 -1
- package/dist/esm/core/historyVisual.js +42 -23
- package/dist/esm/core/historyVisual.js.map +1 -1
- package/dist/esm/core/integrations.js +65 -48
- package/dist/esm/core/integrations.js.map +1 -1
- package/dist/esm/core/minimap.js +40 -24
- package/dist/esm/core/minimap.js.map +1 -1
- package/dist/esm/core/plugins.js +10 -6
- package/dist/esm/core/plugins.js.map +1 -1
- package/dist/esm/core/rtl.js +32 -27
- package/dist/esm/core/rtl.js.map +1 -1
- package/dist/esm/core/shortcuts.js +77 -39
- package/dist/esm/core/shortcuts.js.map +1 -1
- package/dist/esm/core/theme.js +68 -61
- package/dist/esm/core/theme.js.map +1 -1
- package/dist/esm/core/yjsCollaboration.js +61 -28
- package/dist/esm/core/yjsCollaboration.js.map +1 -1
- package/dist/esm/font/NiceFontEditor.js +160 -57
- package/dist/esm/font/NiceFontEditor.js.map +1 -1
- package/dist/esm/font/fontFormatUtils.js +37 -24
- package/dist/esm/font/fontFormatUtils.js.map +1 -1
- package/dist/esm/game/GameAsset2dEditor.js +73 -60
- package/dist/esm/game/GameAsset2dEditor.js.map +1 -1
- package/dist/esm/game/gameAssetUtils.js +18 -13
- package/dist/esm/game/gameAssetUtils.js.map +1 -1
- package/dist/esm/game/useGameAssetEditor.js +160 -143
- package/dist/esm/game/useGameAssetEditor.js.map +1 -1
- package/dist/esm/icon/NiceIconEditor.js +329 -106
- package/dist/esm/icon/NiceIconEditor.js.map +1 -1
- package/dist/esm/packages/ui/dist/NiceErrorBoundary-D75yr_WE.js +563 -0
- package/dist/esm/packages/ui/dist/NiceErrorBoundary-D75yr_WE.js.map +1 -0
- package/dist/esm/packages/ui/dist/NiceForm-CKoJA6NG.js +4960 -0
- package/dist/esm/packages/ui/dist/NiceForm-CKoJA6NG.js.map +1 -0
- package/dist/esm/packages/ui/dist/NiceModal-1QX7NhyH.js +96 -0
- package/dist/esm/packages/ui/dist/NiceModal-1QX7NhyH.js.map +1 -0
- package/dist/esm/packages/ui/dist/NiceModuleLifecyclePanel-CMrPbSw9.js +5201 -0
- package/dist/esm/packages/ui/dist/NiceModuleLifecyclePanel-CMrPbSw9.js.map +1 -0
- package/dist/esm/packages/ui/dist/NicePagination-DbE-uOkl.js +172 -0
- package/dist/esm/packages/ui/dist/NicePagination-DbE-uOkl.js.map +1 -0
- package/dist/esm/packages/ui/dist/NicePinCodeInput-B8cI8zu8.js +10408 -0
- package/dist/esm/packages/ui/dist/NicePinCodeInput-B8cI8zu8.js.map +1 -0
- package/dist/esm/packages/ui/dist/NiceSavedQueryPanel-CZ5bYOe_.js +6296 -0
- package/dist/esm/packages/ui/dist/NiceSavedQueryPanel-CZ5bYOe_.js.map +1 -0
- package/dist/esm/packages/ui/dist/NiceTabs-DzLHzwuA.js +1630 -0
- package/dist/esm/packages/ui/dist/NiceTabs-DzLHzwuA.js.map +1 -0
- package/dist/esm/packages/ui/dist/NiceWindow-DeC83yfE.js +796 -0
- package/dist/esm/packages/ui/dist/NiceWindow-DeC83yfE.js.map +1 -0
- package/dist/esm/packages/ui/dist/charts-BAS21jkC.js +3809 -0
- package/dist/esm/packages/ui/dist/charts-BAS21jkC.js.map +1 -0
- package/dist/esm/packages/ui/dist/core-Da43q-pO.js +11502 -0
- package/dist/esm/packages/ui/dist/core-Da43q-pO.js.map +1 -0
- package/dist/esm/packages/ui/dist/index-pAuGTbuB.js +28792 -0
- package/dist/esm/packages/ui/dist/index-pAuGTbuB.js.map +1 -0
- package/dist/esm/photo/FilterThumb.js +7 -5
- package/dist/esm/photo/FilterThumb.js.map +1 -1
- package/dist/esm/photo/NiceAITools.js +78 -32
- package/dist/esm/photo/NiceAITools.js.map +1 -1
- package/dist/esm/photo/PhotoEditor.js +4 -4
- package/dist/esm/photo/PhotoEditor.js.map +1 -1
- package/dist/esm/photo/PhotoEditorCanvas.js +56 -22
- package/dist/esm/photo/PhotoEditorCanvas.js.map +1 -1
- package/dist/esm/photo/PhotoEditorLeftPanel.js +106 -48
- package/dist/esm/photo/PhotoEditorLeftPanel.js.map +1 -1
- package/dist/esm/photo/PhotoEditorToolbar.js +2 -2
- package/dist/esm/photo/PhotoEditorToolbar.js.map +1 -1
- package/dist/esm/photo/photoEditorActions.js +27 -18
- package/dist/esm/photo/photoEditorActions.js.map +1 -1
- package/dist/esm/photo/photoFilters.js +316 -81
- package/dist/esm/photo/photoFilters.js.map +1 -1
- package/dist/esm/photo/photoOverlays.js +521 -165
- package/dist/esm/photo/photoOverlays.js.map +1 -1
- package/dist/esm/photo/photoSelection.js +69 -35
- package/dist/esm/photo/photoSelection.js.map +1 -1
- package/dist/esm/photo/usePhotoEditor.js +203 -97
- package/dist/esm/photo/usePhotoEditor.js.map +1 -1
- package/dist/esm/pixel/HSVPicker.js +32 -19
- package/dist/esm/pixel/HSVPicker.js.map +1 -1
- package/dist/esm/pixel/PixelEditor.js +25 -14
- package/dist/esm/pixel/PixelEditor.js.map +1 -1
- package/dist/esm/pixel/PixelEditorCanvas.js +2 -2
- package/dist/esm/pixel/PixelEditorCanvas.js.map +1 -1
- package/dist/esm/pixel/PixelEditorMenuBar.js +3 -3
- package/dist/esm/pixel/PixelEditorMenuBar.js.map +1 -1
- package/dist/esm/pixel/PixelEditorRightPanel.js +28 -8
- package/dist/esm/pixel/PixelEditorRightPanel.js.map +1 -1
- package/dist/esm/pixel/PixelEditorStatusBar.js +2 -2
- package/dist/esm/pixel/PixelEditorStatusBar.js.map +1 -1
- package/dist/esm/pixel/PixelEditorTimeline.js +3 -4
- package/dist/esm/pixel/PixelEditorTimeline.js.map +1 -1
- package/dist/esm/pixel/PixelEditorToolbar.js +3 -3
- package/dist/esm/pixel/PixelEditorToolbar.js.map +1 -1
- package/dist/esm/pixel/SpriteGeneratorPanel.js +136 -54
- package/dist/esm/pixel/SpriteGeneratorPanel.js.map +1 -1
- package/dist/esm/pixel/asepriteFormat.js +122 -38
- package/dist/esm/pixel/asepriteFormat.js.map +1 -1
- package/dist/esm/pixel/characterGeneratorPresets.js +208 -54
- package/dist/esm/pixel/characterGeneratorPresets.js.map +1 -1
- package/dist/esm/pixel/pixelEditorExports.js +42 -35
- package/dist/esm/pixel/pixelEditorExports.js.map +1 -1
- package/dist/esm/pixel/pixelEditorTypes.js +67 -33
- package/dist/esm/pixel/pixelEditorTypes.js.map +1 -1
- package/dist/esm/pixel/pixelEditorUtils.js +62 -38
- package/dist/esm/pixel/pixelEditorUtils.js.map +1 -1
- package/dist/esm/pixel/spriteGeneratorCore.js +47 -24
- package/dist/esm/pixel/spriteGeneratorCore.js.map +1 -1
- package/dist/esm/pixel/usePixelEditor.js +475 -213
- package/dist/esm/pixel/usePixelEditor.js.map +1 -1
- package/dist/esm/texture/Nice3DTexturePainter.js +201 -71
- package/dist/esm/texture/Nice3DTexturePainter.js.map +1 -1
- package/dist/esm/ui/NiceUIDesigner.js +280 -91
- package/dist/esm/ui/NiceUIDesigner.js.map +1 -1
- package/dist/esm/vector/NiceSvgToCode.js +96 -34
- package/dist/esm/vector/NiceSvgToCode.js.map +1 -1
- package/dist/esm/vector/VectorEditor.js +14 -13
- package/dist/esm/vector/VectorEditor.js.map +1 -1
- package/dist/esm/vector/VectorEditorMenuBar.js +7 -6
- package/dist/esm/vector/VectorEditorMenuBar.js.map +1 -1
- package/dist/esm/vector/VectorEditorRightPanel.js +87 -32
- package/dist/esm/vector/VectorEditorRightPanel.js.map +1 -1
- package/dist/esm/vector/VectorEditorShapeRenderer.js +17 -15
- package/dist/esm/vector/VectorEditorShapeRenderer.js.map +1 -1
- package/dist/esm/vector/VectorEditorStatusBar.js.map +1 -1
- package/dist/esm/vector/useVectorEditor.js +312 -122
- package/dist/esm/vector/useVectorEditor.js.map +1 -1
- package/dist/esm/vector/vectorBooleanOps.js +60 -42
- package/dist/esm/vector/vectorBooleanOps.js.map +1 -1
- package/dist/esm/vector/vectorEditorExport.js +40 -34
- package/dist/esm/vector/vectorEditorExport.js.map +1 -1
- package/dist/esm/vector/vectorGradients.js +41 -40
- package/dist/esm/vector/vectorGradients.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useState, useRef, useMemo, useCallback, useEffect } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { booleanOperation, flattenToOutline } from './vectorBooleanOps.js';
|
|
3
3
|
import { buildSVGString, exportSVGFile, exportPNGFile, exportJPGFile, exportWebPFile, exportBMPFile } from './vectorEditorExport.js';
|
|
4
4
|
import { parseSVGToShapes } from './vectorEditorImport.js';
|
|
5
|
-
import {
|
|
5
|
+
import { cloneShapes, snapToGrid, sid } from './vectorEditorTypes.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* useVectorEditor — extracted logic + state for VectorEditor.
|
|
@@ -13,12 +13,12 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
13
13
|
/* ── state ── */
|
|
14
14
|
const [shapes, setShapes] = useState([]);
|
|
15
15
|
const [selId, setSelId] = useState(null);
|
|
16
|
-
const [tool, setTool] = useState(
|
|
17
|
-
const [fillCol, setFillCol] = useState(
|
|
18
|
-
const [strokeCol, setStrokeCol] = useState(
|
|
16
|
+
const [tool, setTool] = useState('pointer');
|
|
17
|
+
const [fillCol, setFillCol] = useState('#5566cc');
|
|
18
|
+
const [strokeCol, setStrokeCol] = useState('#ffffff');
|
|
19
19
|
const [strokeW, setStrokeW] = useState(2);
|
|
20
20
|
const [fontSize, setFontSize] = useState(24);
|
|
21
|
-
const [fontFamily, setFontFamily] = useState(
|
|
21
|
+
const [fontFamily, setFontFamily] = useState('sans-serif');
|
|
22
22
|
const [shapeOpacity, setShapeOpacity] = useState(1);
|
|
23
23
|
const [cornerRadius, setCornerRadius] = useState(12);
|
|
24
24
|
const [polygonSides, setPolygonSides] = useState(6);
|
|
@@ -28,7 +28,7 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
28
28
|
const [px, setPx] = useState(0);
|
|
29
29
|
const [py, setPy] = useState(0);
|
|
30
30
|
const [dlgSvg, setDlgSvg] = useState(false);
|
|
31
|
-
const [svgText, setSvgText] = useState(
|
|
31
|
+
const [svgText, setSvgText] = useState('');
|
|
32
32
|
const [snapGrid, setSnapGrid] = useState(false);
|
|
33
33
|
const [gridSize, setGridSize] = useState(16);
|
|
34
34
|
const [hasClipboard, setHasClipboard] = useState(false);
|
|
@@ -59,18 +59,21 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
59
59
|
hIdx.current = hist.current.length - 1;
|
|
60
60
|
}, []);
|
|
61
61
|
useEffect(() => {
|
|
62
|
-
if (hist.current.length === 0)
|
|
62
|
+
if (hist.current.length === 0) {
|
|
63
63
|
snap([]);
|
|
64
|
+
}
|
|
64
65
|
}, [snap]);
|
|
65
66
|
const undo = useCallback(() => {
|
|
66
|
-
if (hIdx.current <= 0)
|
|
67
|
+
if (hIdx.current <= 0) {
|
|
67
68
|
return;
|
|
69
|
+
}
|
|
68
70
|
hIdx.current--;
|
|
69
71
|
setShapes(cloneShapes(hist.current[hIdx.current].shapes));
|
|
70
72
|
}, []);
|
|
71
73
|
const redo = useCallback(() => {
|
|
72
|
-
if (hIdx.current >= hist.current.length - 1)
|
|
74
|
+
if (hIdx.current >= hist.current.length - 1) {
|
|
73
75
|
return;
|
|
76
|
+
}
|
|
74
77
|
hIdx.current++;
|
|
75
78
|
setShapes(cloneShapes(hist.current[hIdx.current].shapes));
|
|
76
79
|
}, []);
|
|
@@ -78,8 +81,9 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
78
81
|
const scr2art = useCallback((cx, cy) => {
|
|
79
82
|
var _a;
|
|
80
83
|
const r = (_a = boxRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
|
|
81
|
-
if (!r)
|
|
84
|
+
if (!r) {
|
|
82
85
|
return { x: 0, y: 0 };
|
|
86
|
+
}
|
|
83
87
|
let x = (cx - r.left - r.width / 2 - px) / zoom + artW / 2;
|
|
84
88
|
let y = (cy - r.top - r.height / 2 - py) / zoom + artH / 2;
|
|
85
89
|
if (snapGrid) {
|
|
@@ -96,8 +100,9 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
96
100
|
panStart.current = { mx: e.clientX, my: e.clientY, px, py };
|
|
97
101
|
return;
|
|
98
102
|
}
|
|
99
|
-
if (e.button !== 0)
|
|
103
|
+
if (e.button !== 0) {
|
|
100
104
|
return;
|
|
105
|
+
}
|
|
101
106
|
const p = scr2art(e.clientX, e.clientY);
|
|
102
107
|
const defaultBase = {
|
|
103
108
|
fill: fillCol,
|
|
@@ -106,7 +111,7 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
106
111
|
opacity: shapeOpacity,
|
|
107
112
|
rotation: 0,
|
|
108
113
|
};
|
|
109
|
-
if (tool ===
|
|
114
|
+
if (tool === 'pointer') {
|
|
110
115
|
let hit = null;
|
|
111
116
|
for (let i = shapes.length - 1; i >= 0; i--) {
|
|
112
117
|
const s = shapes[i];
|
|
@@ -122,13 +127,22 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
122
127
|
}
|
|
123
128
|
return;
|
|
124
129
|
}
|
|
125
|
-
if (tool ===
|
|
130
|
+
if (tool === 'pen') {
|
|
126
131
|
penPts.current.push(p);
|
|
127
132
|
if (penPts.current.length === 1) {
|
|
128
133
|
const ns = {
|
|
129
|
-
id: sid(),
|
|
130
|
-
|
|
131
|
-
|
|
134
|
+
id: sid(),
|
|
135
|
+
type: 'polyline',
|
|
136
|
+
x: p.x,
|
|
137
|
+
y: p.y,
|
|
138
|
+
w: 0,
|
|
139
|
+
h: 0,
|
|
140
|
+
points: [{ x: p.x, y: p.y }],
|
|
141
|
+
fill: 'none',
|
|
142
|
+
stroke: strokeCol,
|
|
143
|
+
strokeWidth: strokeW,
|
|
144
|
+
opacity: shapeOpacity,
|
|
145
|
+
rotation: 0,
|
|
132
146
|
};
|
|
133
147
|
pendingShape.current = ns;
|
|
134
148
|
setShapes((prev) => [...prev, ns]);
|
|
@@ -140,21 +154,37 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
140
154
|
setShapes((prev) => prev.map((s) => {
|
|
141
155
|
var _a;
|
|
142
156
|
return s.id === ((_a = pendingShape.current) === null || _a === void 0 ? void 0 : _a.id)
|
|
143
|
-
? {
|
|
157
|
+
? {
|
|
158
|
+
...s,
|
|
159
|
+
points: pts,
|
|
160
|
+
x: Math.min(...xs),
|
|
161
|
+
y: Math.min(...ys),
|
|
162
|
+
w: Math.max(...xs) - Math.min(...xs),
|
|
163
|
+
h: Math.max(...ys) - Math.min(...ys),
|
|
164
|
+
}
|
|
144
165
|
: s;
|
|
145
166
|
}));
|
|
146
167
|
}
|
|
147
168
|
return;
|
|
148
169
|
}
|
|
149
|
-
if (tool ===
|
|
150
|
-
const txt = prompt(
|
|
151
|
-
if (!txt)
|
|
170
|
+
if (tool === 'text') {
|
|
171
|
+
const txt = prompt('Enter text:', 'Hello');
|
|
172
|
+
if (!txt) {
|
|
152
173
|
return;
|
|
174
|
+
}
|
|
153
175
|
const ns = {
|
|
154
|
-
id: sid(),
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
176
|
+
id: sid(),
|
|
177
|
+
type: 'text',
|
|
178
|
+
x: p.x,
|
|
179
|
+
y: p.y,
|
|
180
|
+
w: txt.length * fontSize * 0.6,
|
|
181
|
+
h: fontSize,
|
|
182
|
+
...defaultBase,
|
|
183
|
+
stroke: 'none',
|
|
184
|
+
strokeWidth: 0,
|
|
185
|
+
text: txt,
|
|
186
|
+
fontSize,
|
|
187
|
+
fontFamily,
|
|
158
188
|
};
|
|
159
189
|
const next = [...shapes, ns];
|
|
160
190
|
snap(next);
|
|
@@ -162,11 +192,17 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
162
192
|
setSelId(ns.id);
|
|
163
193
|
return;
|
|
164
194
|
}
|
|
165
|
-
if (tool ===
|
|
195
|
+
if (tool === 'polygon') {
|
|
166
196
|
const r2 = 40;
|
|
167
197
|
const ns = {
|
|
168
|
-
id: sid(),
|
|
169
|
-
|
|
198
|
+
id: sid(),
|
|
199
|
+
type: 'polygon',
|
|
200
|
+
x: p.x - r2,
|
|
201
|
+
y: p.y - r2,
|
|
202
|
+
w: r2 * 2,
|
|
203
|
+
h: r2 * 2,
|
|
204
|
+
...defaultBase,
|
|
205
|
+
sides: polygonSides,
|
|
170
206
|
};
|
|
171
207
|
drawing.current = true;
|
|
172
208
|
startPt.current = p;
|
|
@@ -174,11 +210,18 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
174
210
|
setShapes((prev) => [...prev, ns]);
|
|
175
211
|
return;
|
|
176
212
|
}
|
|
177
|
-
if (tool ===
|
|
213
|
+
if (tool === 'star') {
|
|
178
214
|
const r2 = 40;
|
|
179
215
|
const ns = {
|
|
180
|
-
id: sid(),
|
|
181
|
-
|
|
216
|
+
id: sid(),
|
|
217
|
+
type: 'star',
|
|
218
|
+
x: p.x - r2,
|
|
219
|
+
y: p.y - r2,
|
|
220
|
+
w: r2 * 2,
|
|
221
|
+
h: r2 * 2,
|
|
222
|
+
...defaultBase,
|
|
223
|
+
sides: starPoints2,
|
|
224
|
+
innerRadius: starInnerRatio,
|
|
182
225
|
};
|
|
183
226
|
drawing.current = true;
|
|
184
227
|
startPt.current = p;
|
|
@@ -189,29 +232,61 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
189
232
|
// rect / roundrect / ellipse / line / arrow — start drag
|
|
190
233
|
drawing.current = true;
|
|
191
234
|
startPt.current = p;
|
|
192
|
-
const typeMap = {
|
|
193
|
-
|
|
194
|
-
|
|
235
|
+
const typeMap = {
|
|
236
|
+
line: 'line',
|
|
237
|
+
arrow: 'arrow',
|
|
238
|
+
ellipse: 'ellipse',
|
|
239
|
+
roundrect: 'roundrect',
|
|
240
|
+
};
|
|
241
|
+
const shapeType = typeMap[tool] || 'rect';
|
|
242
|
+
const isLineLike = shapeType === 'line' || shapeType === 'arrow';
|
|
195
243
|
const ns = {
|
|
196
|
-
id: sid(),
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
244
|
+
id: sid(),
|
|
245
|
+
type: shapeType,
|
|
246
|
+
x: p.x,
|
|
247
|
+
y: p.y,
|
|
248
|
+
w: 0,
|
|
249
|
+
h: 0,
|
|
250
|
+
x2: p.x,
|
|
251
|
+
y2: p.y,
|
|
252
|
+
fill: isLineLike ? 'none' : fillCol,
|
|
253
|
+
stroke: strokeCol,
|
|
254
|
+
strokeWidth: strokeW,
|
|
255
|
+
opacity: shapeOpacity,
|
|
256
|
+
rotation: 0,
|
|
257
|
+
rx: shapeType === 'roundrect' ? cornerRadius : undefined,
|
|
201
258
|
};
|
|
202
259
|
pendingShape.current = ns;
|
|
203
260
|
setShapes((prev) => [...prev, ns]);
|
|
204
|
-
}, [
|
|
261
|
+
}, [
|
|
262
|
+
tool,
|
|
263
|
+
shapes,
|
|
264
|
+
scr2art,
|
|
265
|
+
px,
|
|
266
|
+
py,
|
|
267
|
+
fillCol,
|
|
268
|
+
strokeCol,
|
|
269
|
+
strokeW,
|
|
270
|
+
fontSize,
|
|
271
|
+
fontFamily,
|
|
272
|
+
snap,
|
|
273
|
+
shapeOpacity,
|
|
274
|
+
polygonSides,
|
|
275
|
+
starPoints2,
|
|
276
|
+
starInnerRatio,
|
|
277
|
+
cornerRadius,
|
|
278
|
+
]);
|
|
205
279
|
const onMove = useCallback((e) => {
|
|
206
280
|
if (panning.current) {
|
|
207
281
|
setPx(panStart.current.px + (e.clientX - panStart.current.mx));
|
|
208
282
|
setPy(panStart.current.py + (e.clientY - panStart.current.my));
|
|
209
283
|
return;
|
|
210
284
|
}
|
|
211
|
-
if (!drawing.current)
|
|
285
|
+
if (!drawing.current) {
|
|
212
286
|
return;
|
|
287
|
+
}
|
|
213
288
|
const p = scr2art(e.clientX, e.clientY);
|
|
214
|
-
if (tool ===
|
|
289
|
+
if (tool === 'pointer' && selId) {
|
|
215
290
|
const dx = p.x - startPt.current.x;
|
|
216
291
|
const dy = p.y - startPt.current.y;
|
|
217
292
|
startPt.current = p;
|
|
@@ -219,7 +294,9 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
219
294
|
var _a;
|
|
220
295
|
return s.id === selId
|
|
221
296
|
? {
|
|
222
|
-
...s,
|
|
297
|
+
...s,
|
|
298
|
+
x: s.x + dx,
|
|
299
|
+
y: s.y + dy,
|
|
223
300
|
x2: s.x2 != null ? s.x2 + dx : undefined,
|
|
224
301
|
y2: s.y2 != null ? s.y2 + dy : undefined,
|
|
225
302
|
points: (_a = s.points) === null || _a === void 0 ? void 0 : _a.map((pt) => ({ x: pt.x + dx, y: pt.y + dy })),
|
|
@@ -228,10 +305,11 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
228
305
|
}));
|
|
229
306
|
return;
|
|
230
307
|
}
|
|
231
|
-
if (!pendingShape.current)
|
|
308
|
+
if (!pendingShape.current) {
|
|
232
309
|
return;
|
|
310
|
+
}
|
|
233
311
|
const t = pendingShape.current.type;
|
|
234
|
-
if (t ===
|
|
312
|
+
if (t === 'polygon' || t === 'star') {
|
|
235
313
|
const cx = startPt.current.x;
|
|
236
314
|
const cy = startPt.current.y;
|
|
237
315
|
const dx = p.x - cx;
|
|
@@ -242,14 +320,14 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
242
320
|
: s));
|
|
243
321
|
return;
|
|
244
322
|
}
|
|
245
|
-
if (t ===
|
|
323
|
+
if (t === 'rect' || t === 'roundrect' || t === 'ellipse') {
|
|
246
324
|
const x1 = Math.min(startPt.current.x, p.x);
|
|
247
325
|
const y1 = Math.min(startPt.current.y, p.y);
|
|
248
326
|
const w2 = Math.abs(p.x - startPt.current.x);
|
|
249
327
|
const h2 = Math.abs(p.y - startPt.current.y);
|
|
250
328
|
setShapes((prev) => prev.map((s) => s.id === pendingShape.current.id ? { ...s, x: x1, y: y1, w: w2, h: h2 } : s));
|
|
251
329
|
}
|
|
252
|
-
else if (t ===
|
|
330
|
+
else if (t === 'line' || t === 'arrow') {
|
|
253
331
|
setShapes((prev) => prev.map((s) => s.id === pendingShape.current.id
|
|
254
332
|
? { ...s, w: Math.abs(p.x - s.x), h: Math.abs(p.y - s.y), x2: p.x, y2: p.y }
|
|
255
333
|
: s));
|
|
@@ -265,9 +343,9 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
265
343
|
drawing.current = false;
|
|
266
344
|
if (pendingShape.current) {
|
|
267
345
|
const ps = pendingShape.current;
|
|
268
|
-
if (ps.type !==
|
|
346
|
+
if (ps.type !== 'polyline' && ps.type !== 'text') {
|
|
269
347
|
const minD = 3;
|
|
270
|
-
const isTiny = ps.type ===
|
|
348
|
+
const isTiny = ps.type === 'line' || ps.type === 'arrow'
|
|
271
349
|
? Math.abs(((_a = ps.x2) !== null && _a !== void 0 ? _a : ps.x) - ps.x) < minD && Math.abs(((_b = ps.y2) !== null && _b !== void 0 ? _b : ps.y) - ps.y) < minD
|
|
272
350
|
: Math.abs(ps.w) < minD && Math.abs(ps.h) < minD;
|
|
273
351
|
if (isTiny) {
|
|
@@ -282,14 +360,22 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
282
360
|
}
|
|
283
361
|
}, [snap]);
|
|
284
362
|
const onWheel = useCallback((e) => {
|
|
285
|
-
e.preventDefault();
|
|
286
363
|
setZoom((z) => {
|
|
287
364
|
const n = e.deltaY < 0 ? z * 1.15 : z / 1.15;
|
|
288
365
|
return Math.max(0.1, Math.min(10, n));
|
|
289
366
|
});
|
|
290
367
|
}, []);
|
|
368
|
+
useEffect(() => {
|
|
369
|
+
const el = boxRef.current;
|
|
370
|
+
if (!el) {
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
const handler = (e) => e.preventDefault();
|
|
374
|
+
el.addEventListener('wheel', handler, { passive: false });
|
|
375
|
+
return () => el.removeEventListener('wheel', handler);
|
|
376
|
+
}, []);
|
|
291
377
|
const onDblClick = useCallback(() => {
|
|
292
|
-
if (tool ===
|
|
378
|
+
if (tool === 'pen' && pendingShape.current) {
|
|
293
379
|
snap(shapesRef.current);
|
|
294
380
|
setSelId(pendingShape.current.id);
|
|
295
381
|
pendingShape.current = null;
|
|
@@ -298,52 +384,69 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
298
384
|
}, [tool, snap]);
|
|
299
385
|
/* ── shape operations ── */
|
|
300
386
|
const deleteShape = useCallback(() => {
|
|
301
|
-
if (!selId)
|
|
387
|
+
if (!selId) {
|
|
302
388
|
return;
|
|
389
|
+
}
|
|
303
390
|
const next = shapes.filter((s) => s.id !== selId);
|
|
304
391
|
snap(next);
|
|
305
392
|
setShapes(next);
|
|
306
393
|
setSelId(null);
|
|
307
394
|
}, [selId, shapes, snap]);
|
|
308
395
|
const bringToFront = useCallback(() => {
|
|
309
|
-
if (!selId)
|
|
396
|
+
if (!selId) {
|
|
310
397
|
return;
|
|
398
|
+
}
|
|
311
399
|
const next = [...shapes.filter((s) => s.id !== selId), shapes.find((s) => s.id === selId)];
|
|
312
400
|
snap(next);
|
|
313
401
|
setShapes(next);
|
|
314
402
|
}, [selId, shapes, snap]);
|
|
315
403
|
const sendToBack = useCallback(() => {
|
|
316
|
-
if (!selId)
|
|
404
|
+
if (!selId) {
|
|
317
405
|
return;
|
|
406
|
+
}
|
|
318
407
|
const next = [shapes.find((s) => s.id === selId), ...shapes.filter((s) => s.id !== selId)];
|
|
319
408
|
snap(next);
|
|
320
409
|
setShapes(next);
|
|
321
410
|
}, [selId, shapes, snap]);
|
|
322
411
|
const updateSel = useCallback((patch) => {
|
|
323
|
-
if (!selId)
|
|
412
|
+
if (!selId) {
|
|
324
413
|
return;
|
|
414
|
+
}
|
|
325
415
|
setShapes((prev) => prev.map((s) => (s.id === selId ? { ...s, ...patch } : s)));
|
|
326
416
|
}, [selId]);
|
|
327
417
|
/* ── clipboard ── */
|
|
328
418
|
const copyShape = useCallback(() => {
|
|
329
|
-
if (!selShape)
|
|
419
|
+
if (!selShape) {
|
|
330
420
|
return;
|
|
421
|
+
}
|
|
331
422
|
clipboard.current = JSON.parse(JSON.stringify(selShape));
|
|
332
423
|
setHasClipboard(true);
|
|
333
424
|
}, [selShape]);
|
|
334
425
|
const pasteShape = useCallback(() => {
|
|
335
|
-
if (!clipboard.current)
|
|
426
|
+
if (!clipboard.current) {
|
|
336
427
|
return;
|
|
337
|
-
|
|
428
|
+
}
|
|
429
|
+
const ns = {
|
|
430
|
+
...JSON.parse(JSON.stringify(clipboard.current)),
|
|
431
|
+
id: sid(),
|
|
432
|
+
x: clipboard.current.x + 20,
|
|
433
|
+
y: clipboard.current.y + 20,
|
|
434
|
+
};
|
|
338
435
|
const next = [...shapes, ns];
|
|
339
436
|
snap(next);
|
|
340
437
|
setShapes(next);
|
|
341
438
|
setSelId(ns.id);
|
|
342
439
|
}, [shapes, snap]);
|
|
343
440
|
const duplicateShape = useCallback(() => {
|
|
344
|
-
if (!selShape)
|
|
441
|
+
if (!selShape) {
|
|
345
442
|
return;
|
|
346
|
-
|
|
443
|
+
}
|
|
444
|
+
const ns = {
|
|
445
|
+
...JSON.parse(JSON.stringify(selShape)),
|
|
446
|
+
id: sid(),
|
|
447
|
+
x: selShape.x + 20,
|
|
448
|
+
y: selShape.y + 20,
|
|
449
|
+
};
|
|
347
450
|
const next = [...shapes, ns];
|
|
348
451
|
snap(next);
|
|
349
452
|
setShapes(next);
|
|
@@ -351,69 +454,82 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
351
454
|
}, [selShape, shapes, snap]);
|
|
352
455
|
/* ── flip ── */
|
|
353
456
|
const flipH = useCallback(() => {
|
|
354
|
-
if (!selId || !selShape)
|
|
457
|
+
if (!selId || !selShape) {
|
|
355
458
|
return;
|
|
459
|
+
}
|
|
356
460
|
if (selShape.points) {
|
|
357
461
|
const cx = selShape.x + selShape.w / 2;
|
|
358
|
-
const next = shapes.map((s) => {
|
|
462
|
+
const next = shapes.map((s) => {
|
|
463
|
+
var _a;
|
|
464
|
+
return s.id === selId
|
|
465
|
+
? { ...s, points: (_a = s.points) === null || _a === void 0 ? void 0 : _a.map((pt) => ({ x: cx * 2 - pt.x, y: pt.y })) }
|
|
466
|
+
: s;
|
|
467
|
+
});
|
|
359
468
|
snap(next);
|
|
360
469
|
setShapes(next);
|
|
361
470
|
}
|
|
362
|
-
else if (selShape.type ===
|
|
363
|
-
const next = shapes.map((s) => { var _a; return s.id === selId ? { ...s, x: (_a = s.x2) !== null && _a !== void 0 ? _a : s.x, x2: s.x } : s; });
|
|
471
|
+
else if (selShape.type === 'line' || selShape.type === 'arrow') {
|
|
472
|
+
const next = shapes.map((s) => { var _a; return (s.id === selId ? { ...s, x: (_a = s.x2) !== null && _a !== void 0 ? _a : s.x, x2: s.x } : s); });
|
|
364
473
|
snap(next);
|
|
365
474
|
setShapes(next);
|
|
366
475
|
}
|
|
367
476
|
else {
|
|
368
477
|
const newRot = selShape.rotation ? -selShape.rotation : 0;
|
|
369
|
-
const next = shapes.map((s) => s.id === selId ? { ...s, rotation: newRot } : s);
|
|
478
|
+
const next = shapes.map((s) => (s.id === selId ? { ...s, rotation: newRot } : s));
|
|
370
479
|
snap(next);
|
|
371
480
|
setShapes(next);
|
|
372
481
|
}
|
|
373
482
|
}, [selId, selShape, shapes, snap]);
|
|
374
483
|
const flipV = useCallback(() => {
|
|
375
|
-
if (!selId || !selShape)
|
|
484
|
+
if (!selId || !selShape) {
|
|
376
485
|
return;
|
|
486
|
+
}
|
|
377
487
|
if (selShape.points) {
|
|
378
488
|
const cy = selShape.y + selShape.h / 2;
|
|
379
|
-
const next = shapes.map((s) => {
|
|
489
|
+
const next = shapes.map((s) => {
|
|
490
|
+
var _a;
|
|
491
|
+
return s.id === selId
|
|
492
|
+
? { ...s, points: (_a = s.points) === null || _a === void 0 ? void 0 : _a.map((pt) => ({ x: pt.x, y: cy * 2 - pt.y })) }
|
|
493
|
+
: s;
|
|
494
|
+
});
|
|
380
495
|
snap(next);
|
|
381
496
|
setShapes(next);
|
|
382
497
|
}
|
|
383
|
-
else if (selShape.type ===
|
|
384
|
-
const next = shapes.map((s) => { var _a; return s.id === selId ? { ...s, y: (_a = s.y2) !== null && _a !== void 0 ? _a : s.y, y2: s.y } : s; });
|
|
498
|
+
else if (selShape.type === 'line' || selShape.type === 'arrow') {
|
|
499
|
+
const next = shapes.map((s) => { var _a; return (s.id === selId ? { ...s, y: (_a = s.y2) !== null && _a !== void 0 ? _a : s.y, y2: s.y } : s); });
|
|
385
500
|
snap(next);
|
|
386
501
|
setShapes(next);
|
|
387
502
|
}
|
|
388
503
|
else {
|
|
389
504
|
const newRot = selShape.rotation ? (180 - selShape.rotation) % 360 : 180;
|
|
390
|
-
const next = shapes.map((s) => s.id === selId ? { ...s, rotation: newRot } : s);
|
|
505
|
+
const next = shapes.map((s) => (s.id === selId ? { ...s, rotation: newRot } : s));
|
|
391
506
|
snap(next);
|
|
392
507
|
setShapes(next);
|
|
393
508
|
}
|
|
394
509
|
}, [selId, selShape, shapes, snap]);
|
|
395
510
|
/* ── alignment ── */
|
|
396
511
|
const alignShapes = useCallback((mode) => {
|
|
397
|
-
if (!selId || !selShape)
|
|
512
|
+
if (!selId || !selShape) {
|
|
398
513
|
return;
|
|
514
|
+
}
|
|
399
515
|
let patch = {};
|
|
400
516
|
switch (mode) {
|
|
401
|
-
case
|
|
517
|
+
case 'left':
|
|
402
518
|
patch = { x: 0 };
|
|
403
519
|
break;
|
|
404
|
-
case
|
|
520
|
+
case 'right':
|
|
405
521
|
patch = { x: artW - selShape.w };
|
|
406
522
|
break;
|
|
407
|
-
case
|
|
523
|
+
case 'center':
|
|
408
524
|
patch = { x: (artW - selShape.w) / 2 };
|
|
409
525
|
break;
|
|
410
|
-
case
|
|
526
|
+
case 'top':
|
|
411
527
|
patch = { y: 0 };
|
|
412
528
|
break;
|
|
413
|
-
case
|
|
529
|
+
case 'bottom':
|
|
414
530
|
patch = { y: artH - selShape.h };
|
|
415
531
|
break;
|
|
416
|
-
case
|
|
532
|
+
case 'middle':
|
|
417
533
|
patch = { y: (artH - selShape.h) / 2 };
|
|
418
534
|
break;
|
|
419
535
|
}
|
|
@@ -425,15 +541,17 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
425
541
|
const [boolSecondShape, setBoolSecondShape] = useState(null);
|
|
426
542
|
const applyBoolean = useCallback((operation) => {
|
|
427
543
|
var _a;
|
|
428
|
-
if (!selId || !boolSecondShape)
|
|
544
|
+
if (!selId || !boolSecondShape) {
|
|
429
545
|
return;
|
|
546
|
+
}
|
|
430
547
|
const shapeA = shapes.find((s) => s.id === selId);
|
|
431
548
|
const shapeB = shapes.find((s) => s.id === boolSecondShape);
|
|
432
|
-
if (!shapeA || !shapeB)
|
|
549
|
+
if (!shapeA || !shapeB) {
|
|
433
550
|
return;
|
|
551
|
+
}
|
|
434
552
|
const result = booleanOperation(shapeA, shapeB, operation);
|
|
435
553
|
if (!result) {
|
|
436
|
-
|
|
554
|
+
console.warn('[VectorEditor] Boolean operation resulted in empty shape');
|
|
437
555
|
return;
|
|
438
556
|
}
|
|
439
557
|
// Remove original shapes, add result(s)
|
|
@@ -450,13 +568,14 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
450
568
|
setShapes(next);
|
|
451
569
|
setBoolSecondShape(null);
|
|
452
570
|
}, [selId, boolSecondShape, shapes, snap]);
|
|
453
|
-
const unionShapes = useCallback(() => applyBoolean(
|
|
454
|
-
const subtractShapes = useCallback(() => applyBoolean(
|
|
455
|
-
const intersectShapes = useCallback(() => applyBoolean(
|
|
456
|
-
const excludeShapes = useCallback(() => applyBoolean(
|
|
571
|
+
const unionShapes = useCallback(() => applyBoolean('union'), [applyBoolean]);
|
|
572
|
+
const subtractShapes = useCallback(() => applyBoolean('difference'), [applyBoolean]);
|
|
573
|
+
const intersectShapes = useCallback(() => applyBoolean('intersection'), [applyBoolean]);
|
|
574
|
+
const excludeShapes = useCallback(() => applyBoolean('exclusion'), [applyBoolean]);
|
|
457
575
|
const outlineStroke = useCallback(() => {
|
|
458
|
-
if (!selId || !selShape)
|
|
576
|
+
if (!selId || !selShape) {
|
|
459
577
|
return;
|
|
578
|
+
}
|
|
460
579
|
const result = flattenToOutline(selShape);
|
|
461
580
|
const next = shapes.map((s) => (s.id === selId ? result : s));
|
|
462
581
|
snap(next);
|
|
@@ -468,7 +587,7 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
468
587
|
try {
|
|
469
588
|
const imported = parseSVGToShapes(raw);
|
|
470
589
|
if (imported.length === 0) {
|
|
471
|
-
|
|
590
|
+
console.warn('[VectorEditor] No supported shapes found in SVG.');
|
|
472
591
|
return;
|
|
473
592
|
}
|
|
474
593
|
const next = [...shapes, ...imported];
|
|
@@ -477,10 +596,12 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
477
596
|
setDlgSvg(false);
|
|
478
597
|
}
|
|
479
598
|
catch (e) {
|
|
480
|
-
|
|
599
|
+
console.warn('[VectorEditor] SVG parse error:', e instanceof Error ? e.message : 'Failed to parse SVG.');
|
|
481
600
|
}
|
|
482
601
|
}, [shapes, snap]);
|
|
483
|
-
const openFile = useCallback(async (file) => {
|
|
602
|
+
const openFile = useCallback(async (file) => {
|
|
603
|
+
importSVGString(await file.text());
|
|
604
|
+
}, [importSVGString]);
|
|
484
605
|
/* ── new / reset ── */
|
|
485
606
|
const newCanvas = useCallback(() => {
|
|
486
607
|
snap([]);
|
|
@@ -492,17 +613,19 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
492
613
|
}, [snap]);
|
|
493
614
|
/* ── save to library ── */
|
|
494
615
|
const saveToLibrary = useCallback(() => {
|
|
495
|
-
if (!onSaveToLibrary)
|
|
616
|
+
if (!onSaveToLibrary) {
|
|
496
617
|
return;
|
|
618
|
+
}
|
|
497
619
|
const svg = buildSVGString(shapes, artW, artH);
|
|
498
|
-
const blob = new Blob([svg], { type:
|
|
620
|
+
const blob = new Blob([svg], { type: 'image/svg+xml' });
|
|
499
621
|
const reader = new FileReader();
|
|
500
622
|
reader.onload = () => {
|
|
501
|
-
const defaultName =
|
|
502
|
-
const name = window.prompt(
|
|
503
|
-
if (!name || !name.trim())
|
|
623
|
+
const defaultName = 'drawing.svg';
|
|
624
|
+
const name = window.prompt('Save to library as:', defaultName);
|
|
625
|
+
if (!name || !name.trim()) {
|
|
504
626
|
return;
|
|
505
|
-
|
|
627
|
+
}
|
|
628
|
+
onSaveToLibrary(reader.result, name.trim(), 'image/svg+xml');
|
|
506
629
|
};
|
|
507
630
|
reader.readAsDataURL(blob);
|
|
508
631
|
}, [shapes, artW, artH, onSaveToLibrary]);
|
|
@@ -514,7 +637,7 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
514
637
|
const exportBMP = useCallback(() => exportBMPFile(shapes, artW, artH), [shapes, artW, artH]);
|
|
515
638
|
/* ── tool switch helper (finishes pen) ── */
|
|
516
639
|
const switchTool = useCallback((newTool) => {
|
|
517
|
-
if (tool ===
|
|
640
|
+
if (tool === 'pen' && newTool !== 'pen' && pendingShape.current) {
|
|
518
641
|
snap(shapes);
|
|
519
642
|
pendingShape.current = null;
|
|
520
643
|
penPts.current = [];
|
|
@@ -525,34 +648,35 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
525
648
|
useEffect(() => {
|
|
526
649
|
const h = (e) => {
|
|
527
650
|
const t = e.target;
|
|
528
|
-
if (t.tagName ===
|
|
651
|
+
if (t.tagName === 'INPUT' || t.tagName === 'TEXTAREA') {
|
|
529
652
|
return;
|
|
530
|
-
|
|
653
|
+
}
|
|
654
|
+
if (e.ctrlKey && e.key === 'z') {
|
|
531
655
|
e.preventDefault();
|
|
532
656
|
undo();
|
|
533
657
|
return;
|
|
534
658
|
}
|
|
535
|
-
if (e.ctrlKey && (e.key ===
|
|
659
|
+
if (e.ctrlKey && (e.key === 'y' || (e.shiftKey && e.key === 'Z'))) {
|
|
536
660
|
e.preventDefault();
|
|
537
661
|
redo();
|
|
538
662
|
return;
|
|
539
663
|
}
|
|
540
|
-
if (e.ctrlKey && e.key ===
|
|
664
|
+
if (e.ctrlKey && e.key === 'c') {
|
|
541
665
|
e.preventDefault();
|
|
542
666
|
copyShape();
|
|
543
667
|
return;
|
|
544
668
|
}
|
|
545
|
-
if (e.ctrlKey && e.key ===
|
|
669
|
+
if (e.ctrlKey && e.key === 'v') {
|
|
546
670
|
e.preventDefault();
|
|
547
671
|
pasteShape();
|
|
548
672
|
return;
|
|
549
673
|
}
|
|
550
|
-
if (e.ctrlKey && e.key ===
|
|
674
|
+
if (e.ctrlKey && e.key === 'd') {
|
|
551
675
|
e.preventDefault();
|
|
552
676
|
duplicateShape();
|
|
553
677
|
return;
|
|
554
678
|
}
|
|
555
|
-
if (e.key ===
|
|
679
|
+
if (e.key === 'Escape') {
|
|
556
680
|
if (pendingShape.current) {
|
|
557
681
|
setShapes((prev) => prev.filter((s) => s.id !== pendingShape.current.id));
|
|
558
682
|
pendingShape.current = null;
|
|
@@ -565,45 +689,111 @@ function useVectorEditor({ artW, artH, onSaveToLibrary }) {
|
|
|
565
689
|
return;
|
|
566
690
|
}
|
|
567
691
|
const km = {
|
|
568
|
-
v:
|
|
569
|
-
|
|
692
|
+
v: 'pointer',
|
|
693
|
+
r: 'rect',
|
|
694
|
+
u: 'roundrect',
|
|
695
|
+
c: 'ellipse',
|
|
696
|
+
l: 'line',
|
|
697
|
+
a: 'arrow',
|
|
698
|
+
g: 'polygon',
|
|
699
|
+
s: 'star',
|
|
700
|
+
p: 'pen',
|
|
701
|
+
t: 'text',
|
|
570
702
|
};
|
|
571
703
|
if (km[e.key.toLowerCase()] && !e.ctrlKey && !e.altKey) {
|
|
572
704
|
setTool(km[e.key.toLowerCase()]);
|
|
573
705
|
return;
|
|
574
706
|
}
|
|
575
|
-
if (e.key ===
|
|
707
|
+
if (e.key === 'Delete' || e.key === 'Backspace') {
|
|
576
708
|
deleteShape();
|
|
709
|
+
}
|
|
577
710
|
};
|
|
578
|
-
window.addEventListener(
|
|
579
|
-
return () => window.removeEventListener(
|
|
711
|
+
window.addEventListener('keydown', h);
|
|
712
|
+
return () => window.removeEventListener('keydown', h);
|
|
580
713
|
}, [undo, redo, deleteShape, copyShape, pasteShape, duplicateShape]);
|
|
581
714
|
/* ── return ── */
|
|
582
715
|
return {
|
|
583
716
|
// state
|
|
584
|
-
shapes,
|
|
585
|
-
|
|
586
|
-
|
|
717
|
+
shapes,
|
|
718
|
+
selId,
|
|
719
|
+
tool,
|
|
720
|
+
fillCol,
|
|
721
|
+
strokeCol,
|
|
722
|
+
strokeW,
|
|
723
|
+
fontSize,
|
|
724
|
+
fontFamily,
|
|
725
|
+
shapeOpacity,
|
|
726
|
+
cornerRadius,
|
|
727
|
+
polygonSides,
|
|
728
|
+
starPoints2,
|
|
729
|
+
starInnerRatio,
|
|
730
|
+
zoom,
|
|
731
|
+
px,
|
|
732
|
+
py,
|
|
733
|
+
dlgSvg,
|
|
734
|
+
svgText,
|
|
735
|
+
snapGrid,
|
|
736
|
+
gridSize,
|
|
737
|
+
hasClipboard,
|
|
587
738
|
boolSecondShape,
|
|
588
739
|
// derived
|
|
589
740
|
selShape,
|
|
590
741
|
// setters
|
|
591
|
-
setTool,
|
|
592
|
-
|
|
593
|
-
|
|
742
|
+
setTool,
|
|
743
|
+
setFillCol,
|
|
744
|
+
setStrokeCol,
|
|
745
|
+
setStrokeW,
|
|
746
|
+
setFontSize,
|
|
747
|
+
setFontFamily,
|
|
748
|
+
setShapeOpacity,
|
|
749
|
+
setCornerRadius,
|
|
750
|
+
setPolygonSides,
|
|
751
|
+
setStarPoints2,
|
|
752
|
+
setStarInnerRatio,
|
|
753
|
+
setZoom,
|
|
754
|
+
setDlgSvg,
|
|
755
|
+
setSvgText,
|
|
756
|
+
setSnapGrid,
|
|
757
|
+
setGridSize,
|
|
758
|
+
setSelId,
|
|
594
759
|
setBoolSecondShape,
|
|
595
760
|
// refs
|
|
596
|
-
boxRef,
|
|
761
|
+
boxRef,
|
|
762
|
+
fInp,
|
|
597
763
|
// mouse handlers
|
|
598
|
-
onDown,
|
|
764
|
+
onDown,
|
|
765
|
+
onMove,
|
|
766
|
+
onUp,
|
|
767
|
+
onWheel,
|
|
768
|
+
onDblClick,
|
|
599
769
|
// actions
|
|
600
|
-
undo,
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
770
|
+
undo,
|
|
771
|
+
redo,
|
|
772
|
+
deleteShape,
|
|
773
|
+
bringToFront,
|
|
774
|
+
sendToBack,
|
|
775
|
+
updateSel,
|
|
776
|
+
copyShape,
|
|
777
|
+
pasteShape,
|
|
778
|
+
duplicateShape,
|
|
779
|
+
flipH,
|
|
780
|
+
flipV,
|
|
781
|
+
alignShapes,
|
|
782
|
+
unionShapes,
|
|
783
|
+
subtractShapes,
|
|
784
|
+
intersectShapes,
|
|
785
|
+
excludeShapes,
|
|
786
|
+
outlineStroke,
|
|
787
|
+
importSVGString,
|
|
788
|
+
openFile,
|
|
789
|
+
newCanvas,
|
|
790
|
+
exportSVG,
|
|
791
|
+
exportPNG,
|
|
792
|
+
exportJPG,
|
|
793
|
+
exportWebP,
|
|
794
|
+
exportBMP,
|
|
795
|
+
switchTool,
|
|
796
|
+
saveToLibrary,
|
|
607
797
|
};
|
|
608
798
|
}
|
|
609
799
|
|