ding-image-editor 3.15.3
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 +193 -0
- package/dist/svg/icon-a.svg +376 -0
- package/dist/svg/icon-b.svg +369 -0
- package/dist/svg/icon-c.svg +369 -0
- package/dist/svg/icon-d.svg +369 -0
- package/dist/tui-image-editor.css +6 -0
- package/dist/tui-image-editor.js +62329 -0
- package/dist/tui-image-editor.min.css +5 -0
- package/dist/tui-image-editor.min.js +15 -0
- package/index.d.ts +334 -0
- package/package.json +52 -0
- package/src/css/buttons.styl +102 -0
- package/src/css/checkbox.styl +86 -0
- package/src/css/colorpicker.styl +98 -0
- package/src/css/gridtable.styl +45 -0
- package/src/css/icon.styl +44 -0
- package/src/css/index.styl +17 -0
- package/src/css/main.styl +163 -0
- package/src/css/position.styl +309 -0
- package/src/css/range.styl +91 -0
- package/src/css/submenu.styl +168 -0
- package/src/index.js +29 -0
- package/src/js/action.js +686 -0
- package/src/js/command/addIcon.js +42 -0
- package/src/js/command/addImageObject.js +34 -0
- package/src/js/command/addObject.js +43 -0
- package/src/js/command/addShape.js +51 -0
- package/src/js/command/addText.js +73 -0
- package/src/js/command/applyFilter.js +95 -0
- package/src/js/command/changeIconColor.js +48 -0
- package/src/js/command/changeSelection.js +31 -0
- package/src/js/command/changeShape.js +84 -0
- package/src/js/command/changeText.js +44 -0
- package/src/js/command/changeTextStyle.js +80 -0
- package/src/js/command/clearObjects.js +33 -0
- package/src/js/command/flip.js +36 -0
- package/src/js/command/loadImage.js +58 -0
- package/src/js/command/removeFilter.js +38 -0
- package/src/js/command/removeObject.js +37 -0
- package/src/js/command/resize.js +41 -0
- package/src/js/command/resizeCanvasDimension.js +40 -0
- package/src/js/command/rotate.js +64 -0
- package/src/js/command/setObjectPosition.js +50 -0
- package/src/js/command/setObjectProperties.js +55 -0
- package/src/js/component/cropper.js +407 -0
- package/src/js/component/filter.js +229 -0
- package/src/js/component/flip.js +146 -0
- package/src/js/component/freeDrawing.js +144 -0
- package/src/js/component/icon.js +246 -0
- package/src/js/component/imageLoader.js +84 -0
- package/src/js/component/line.js +205 -0
- package/src/js/component/resize.js +103 -0
- package/src/js/component/rotation.js +91 -0
- package/src/js/component/shape.js +601 -0
- package/src/js/component/text.js +572 -0
- package/src/js/component/zoom.js +708 -0
- package/src/js/consts.js +404 -0
- package/src/js/drawingMode/cropper.js +35 -0
- package/src/js/drawingMode/freeDrawing.js +36 -0
- package/src/js/drawingMode/icon.js +35 -0
- package/src/js/drawingMode/lineDrawing.js +36 -0
- package/src/js/drawingMode/resize.js +35 -0
- package/src/js/drawingMode/shape.js +35 -0
- package/src/js/drawingMode/text.js +35 -0
- package/src/js/drawingMode/zoom.js +37 -0
- package/src/js/extension/arrowLine.js +172 -0
- package/src/js/extension/blur.js +29 -0
- package/src/js/extension/colorFilter.js +104 -0
- package/src/js/extension/cropzone.js +568 -0
- package/src/js/extension/emboss.js +29 -0
- package/src/js/extension/mask.js +90 -0
- package/src/js/extension/sharpen.js +29 -0
- package/src/js/factory/command.js +36 -0
- package/src/js/factory/errorMessage.js +27 -0
- package/src/js/graphics.js +1539 -0
- package/src/js/helper/imagetracer.js +1396 -0
- package/src/js/helper/selectionModifyHelper.js +86 -0
- package/src/js/helper/shapeFilterFillHelper.js +564 -0
- package/src/js/helper/shapeResizeHelper.js +237 -0
- package/src/js/imageEditor.js +1795 -0
- package/src/js/interface/command.js +131 -0
- package/src/js/interface/component.js +127 -0
- package/src/js/interface/drawingMode.js +47 -0
- package/src/js/invoker.js +292 -0
- package/src/js/polyfill.js +498 -0
- package/src/js/ui/crop.js +139 -0
- package/src/js/ui/draw.js +187 -0
- package/src/js/ui/filter.js +510 -0
- package/src/js/ui/flip.js +87 -0
- package/src/js/ui/history.js +171 -0
- package/src/js/ui/icon.js +191 -0
- package/src/js/ui/locale/locale.js +19 -0
- package/src/js/ui/mask.js +96 -0
- package/src/js/ui/panelMenu.js +130 -0
- package/src/js/ui/resize.js +241 -0
- package/src/js/ui/rotate.js +123 -0
- package/src/js/ui/shape.js +265 -0
- package/src/js/ui/submenuBase.js +122 -0
- package/src/js/ui/template/controls.js +21 -0
- package/src/js/ui/template/mainContainer.js +38 -0
- package/src/js/ui/template/style.js +146 -0
- package/src/js/ui/template/submenu/crop.js +73 -0
- package/src/js/ui/template/submenu/draw.js +42 -0
- package/src/js/ui/template/submenu/filter.js +157 -0
- package/src/js/ui/template/submenu/flip.js +41 -0
- package/src/js/ui/template/submenu/history.js +22 -0
- package/src/js/ui/template/submenu/icon.js +108 -0
- package/src/js/ui/template/submenu/mask.js +30 -0
- package/src/js/ui/template/submenu/resize.js +54 -0
- package/src/js/ui/template/submenu/rotate.js +32 -0
- package/src/js/ui/template/submenu/shape.js +45 -0
- package/src/js/ui/template/submenu/text.js +67 -0
- package/src/js/ui/template/submenu/zoom.js +41 -0
- package/src/js/ui/text.js +279 -0
- package/src/js/ui/theme/standard.js +220 -0
- package/src/js/ui/theme/theme.js +249 -0
- package/src/js/ui/tools/colorpicker.js +250 -0
- package/src/js/ui/tools/range.js +390 -0
- package/src/js/ui.js +858 -0
- package/src/js/util.js +551 -0
- package/src/svg/default.svg +335 -0
- package/src/svg/icon-a/ic-apply.svg +6 -0
- package/src/svg/icon-a/ic-cancel.svg +6 -0
- package/src/svg/icon-a/ic-color-transparent-w.svg +12 -0
- package/src/svg/icon-a/ic-crop.svg +7 -0
- package/src/svg/icon-a/ic-delete-all.svg +6 -0
- package/src/svg/icon-a/ic-delete.svg +6 -0
- package/src/svg/icon-a/ic-draw-free.svg +5 -0
- package/src/svg/icon-a/ic-draw-line.svg +5 -0
- package/src/svg/icon-a/ic-draw.svg +6 -0
- package/src/svg/icon-a/ic-filter.svg +7 -0
- package/src/svg/icon-a/ic-flip-reset.svg +7 -0
- package/src/svg/icon-a/ic-flip-x.svg +6 -0
- package/src/svg/icon-a/ic-flip-y.svg +6 -0
- package/src/svg/icon-a/ic-flip.svg +6 -0
- package/src/svg/icon-a/ic-history-check.svg +5 -0
- package/src/svg/icon-a/ic-history-crop.svg +7 -0
- package/src/svg/icon-a/ic-history-delete.svg +9 -0
- package/src/svg/icon-a/ic-history-draw.svg +7 -0
- package/src/svg/icon-a/ic-history-filter.svg +8 -0
- package/src/svg/icon-a/ic-history-flip.svg +6 -0
- package/src/svg/icon-a/ic-history-group.svg +9 -0
- package/src/svg/icon-a/ic-history-icon.svg +6 -0
- package/src/svg/icon-a/ic-history-load.svg +7 -0
- package/src/svg/icon-a/ic-history-mask.svg +9 -0
- package/src/svg/icon-a/ic-history-resize.svg +12 -0
- package/src/svg/icon-a/ic-history-rotate.svg +16 -0
- package/src/svg/icon-a/ic-history-shape.svg +7 -0
- package/src/svg/icon-a/ic-history-text.svg +8 -0
- package/src/svg/icon-a/ic-history.svg +6 -0
- package/src/svg/icon-a/ic-icon-arrow-2.svg +5 -0
- package/src/svg/icon-a/ic-icon-arrow-3.svg +5 -0
- package/src/svg/icon-a/ic-icon-arrow.svg +5 -0
- package/src/svg/icon-a/ic-icon-bubble.svg +5 -0
- package/src/svg/icon-a/ic-icon-heart.svg +5 -0
- package/src/svg/icon-a/ic-icon-load.svg +8 -0
- package/src/svg/icon-a/ic-icon-location.svg +8 -0
- package/src/svg/icon-a/ic-icon-polygon.svg +5 -0
- package/src/svg/icon-a/ic-icon-star-2.svg +5 -0
- package/src/svg/icon-a/ic-icon-star.svg +5 -0
- package/src/svg/icon-a/ic-icon.svg +5 -0
- package/src/svg/icon-a/ic-mask-load.svg +8 -0
- package/src/svg/icon-a/ic-mask.svg +6 -0
- package/src/svg/icon-a/ic-redo.svg +7 -0
- package/src/svg/icon-a/ic-reset.svg +7 -0
- package/src/svg/icon-a/ic-resize.svg +13 -0
- package/src/svg/icon-a/ic-rotate-clockwise.svg +7 -0
- package/src/svg/icon-a/ic-rotate-counterclockwise.svg +7 -0
- package/src/svg/icon-a/ic-rotate.svg +7 -0
- package/src/svg/icon-a/ic-shape-circle.svg +5 -0
- package/src/svg/icon-a/ic-shape-rectangle.svg +5 -0
- package/src/svg/icon-a/ic-shape-triangle.svg +5 -0
- package/src/svg/icon-a/ic-shape.svg +6 -0
- package/src/svg/icon-a/ic-text-align-center.svg +6 -0
- package/src/svg/icon-a/ic-text-align-left.svg +6 -0
- package/src/svg/icon-a/ic-text-align-right.svg +6 -0
- package/src/svg/icon-a/ic-text-bold.svg +7 -0
- package/src/svg/icon-a/ic-text-italic.svg +6 -0
- package/src/svg/icon-a/ic-text-underline.svg +7 -0
- package/src/svg/icon-a/ic-text.svg +7 -0
- package/src/svg/icon-a/ic-undo.svg +7 -0
- package/src/svg/icon-a/ic-zoom-hand.svg +8 -0
- package/src/svg/icon-a/ic-zoom-zoom-in.svg +10 -0
- package/src/svg/icon-a/ic-zoom-zoom-out.svg +9 -0
- package/src/svg/icon-a/img-bi.svg +5 -0
- package/src/svg/icon-b/ic-apply.svg +6 -0
- package/src/svg/icon-b/ic-cancel.svg +6 -0
- package/src/svg/icon-b/ic-crop.svg +7 -0
- package/src/svg/icon-b/ic-delete-all.svg +6 -0
- package/src/svg/icon-b/ic-delete.svg +6 -0
- package/src/svg/icon-b/ic-draw-free.svg +5 -0
- package/src/svg/icon-b/ic-draw-line.svg +5 -0
- package/src/svg/icon-b/ic-draw.svg +6 -0
- package/src/svg/icon-b/ic-filter.svg +7 -0
- package/src/svg/icon-b/ic-flip-reset.svg +7 -0
- package/src/svg/icon-b/ic-flip-x.svg +6 -0
- package/src/svg/icon-b/ic-flip-y.svg +6 -0
- package/src/svg/icon-b/ic-flip.svg +6 -0
- package/src/svg/icon-b/ic-history-check.svg +5 -0
- package/src/svg/icon-b/ic-history-crop.svg +7 -0
- package/src/svg/icon-b/ic-history-delete.svg +9 -0
- package/src/svg/icon-b/ic-history-draw.svg +7 -0
- package/src/svg/icon-b/ic-history-filter.svg +8 -0
- package/src/svg/icon-b/ic-history-flip.svg +6 -0
- package/src/svg/icon-b/ic-history-group.svg +9 -0
- package/src/svg/icon-b/ic-history-icon.svg +6 -0
- package/src/svg/icon-b/ic-history-load.svg +7 -0
- package/src/svg/icon-b/ic-history-mask.svg +9 -0
- package/src/svg/icon-b/ic-history-resize.svg +12 -0
- package/src/svg/icon-b/ic-history-rotate.svg +16 -0
- package/src/svg/icon-b/ic-history-shape.svg +7 -0
- package/src/svg/icon-b/ic-history-text.svg +8 -0
- package/src/svg/icon-b/ic-history.svg +6 -0
- package/src/svg/icon-b/ic-icon-arrow-2.svg +5 -0
- package/src/svg/icon-b/ic-icon-arrow-3.svg +5 -0
- package/src/svg/icon-b/ic-icon-arrow.svg +5 -0
- package/src/svg/icon-b/ic-icon-bubble.svg +5 -0
- package/src/svg/icon-b/ic-icon-heart.svg +5 -0
- package/src/svg/icon-b/ic-icon-load.svg +8 -0
- package/src/svg/icon-b/ic-icon-location.svg +8 -0
- package/src/svg/icon-b/ic-icon-polygon.svg +5 -0
- package/src/svg/icon-b/ic-icon-star-2.svg +5 -0
- package/src/svg/icon-b/ic-icon-star.svg +5 -0
- package/src/svg/icon-b/ic-icon.svg +5 -0
- package/src/svg/icon-b/ic-mask-load.svg +8 -0
- package/src/svg/icon-b/ic-mask.svg +6 -0
- package/src/svg/icon-b/ic-redo.svg +7 -0
- package/src/svg/icon-b/ic-reset.svg +7 -0
- package/src/svg/icon-b/ic-resize.svg +13 -0
- package/src/svg/icon-b/ic-rotate-clockwise.svg +7 -0
- package/src/svg/icon-b/ic-rotate-counterclockwise.svg +7 -0
- package/src/svg/icon-b/ic-rotate.svg +7 -0
- package/src/svg/icon-b/ic-shape-circle.svg +5 -0
- package/src/svg/icon-b/ic-shape-rectangle.svg +5 -0
- package/src/svg/icon-b/ic-shape-triangle.svg +5 -0
- package/src/svg/icon-b/ic-shape.svg +6 -0
- package/src/svg/icon-b/ic-text-align-center.svg +6 -0
- package/src/svg/icon-b/ic-text-align-left.svg +6 -0
- package/src/svg/icon-b/ic-text-align-right.svg +6 -0
- package/src/svg/icon-b/ic-text-bold.svg +7 -0
- package/src/svg/icon-b/ic-text-italic.svg +6 -0
- package/src/svg/icon-b/ic-text-underline.svg +7 -0
- package/src/svg/icon-b/ic-text.svg +7 -0
- package/src/svg/icon-b/ic-undo.svg +7 -0
- package/src/svg/icon-b/ic-zoom-hand.svg +8 -0
- package/src/svg/icon-b/ic-zoom-zoom-in.svg +12 -0
- package/src/svg/icon-b/ic-zoom-zoom-out.svg +11 -0
- package/src/svg/icon-b/img-bi.svg +5 -0
- package/src/svg/icon-c/ic-apply.svg +6 -0
- package/src/svg/icon-c/ic-cancel.svg +6 -0
- package/src/svg/icon-c/ic-crop.svg +7 -0
- package/src/svg/icon-c/ic-delete-all.svg +6 -0
- package/src/svg/icon-c/ic-delete.svg +6 -0
- package/src/svg/icon-c/ic-draw-free.svg +5 -0
- package/src/svg/icon-c/ic-draw-line.svg +5 -0
- package/src/svg/icon-c/ic-draw.svg +6 -0
- package/src/svg/icon-c/ic-filter.svg +7 -0
- package/src/svg/icon-c/ic-flip-reset.svg +7 -0
- package/src/svg/icon-c/ic-flip-x.svg +6 -0
- package/src/svg/icon-c/ic-flip-y.svg +6 -0
- package/src/svg/icon-c/ic-flip.svg +6 -0
- package/src/svg/icon-c/ic-history-check.svg +5 -0
- package/src/svg/icon-c/ic-history-crop.svg +7 -0
- package/src/svg/icon-c/ic-history-delete.svg +9 -0
- package/src/svg/icon-c/ic-history-draw.svg +7 -0
- package/src/svg/icon-c/ic-history-filter.svg +8 -0
- package/src/svg/icon-c/ic-history-flip.svg +6 -0
- package/src/svg/icon-c/ic-history-group.svg +9 -0
- package/src/svg/icon-c/ic-history-icon.svg +6 -0
- package/src/svg/icon-c/ic-history-load.svg +7 -0
- package/src/svg/icon-c/ic-history-mask.svg +9 -0
- package/src/svg/icon-c/ic-history-resize.svg +12 -0
- package/src/svg/icon-c/ic-history-rotate.svg +16 -0
- package/src/svg/icon-c/ic-history-shape.svg +7 -0
- package/src/svg/icon-c/ic-history-text.svg +8 -0
- package/src/svg/icon-c/ic-history.svg +6 -0
- package/src/svg/icon-c/ic-icon-arrow-2.svg +5 -0
- package/src/svg/icon-c/ic-icon-arrow-3.svg +5 -0
- package/src/svg/icon-c/ic-icon-arrow.svg +5 -0
- package/src/svg/icon-c/ic-icon-bubble.svg +5 -0
- package/src/svg/icon-c/ic-icon-heart.svg +5 -0
- package/src/svg/icon-c/ic-icon-load.svg +8 -0
- package/src/svg/icon-c/ic-icon-location.svg +8 -0
- package/src/svg/icon-c/ic-icon-polygon.svg +5 -0
- package/src/svg/icon-c/ic-icon-star-2.svg +5 -0
- package/src/svg/icon-c/ic-icon-star.svg +5 -0
- package/src/svg/icon-c/ic-icon.svg +5 -0
- package/src/svg/icon-c/ic-mask-load.svg +8 -0
- package/src/svg/icon-c/ic-mask.svg +6 -0
- package/src/svg/icon-c/ic-redo.svg +7 -0
- package/src/svg/icon-c/ic-reset.svg +7 -0
- package/src/svg/icon-c/ic-resize.svg +13 -0
- package/src/svg/icon-c/ic-rotate-clockwise.svg +7 -0
- package/src/svg/icon-c/ic-rotate-counterclockwise.svg +7 -0
- package/src/svg/icon-c/ic-rotate.svg +7 -0
- package/src/svg/icon-c/ic-shape-circle.svg +5 -0
- package/src/svg/icon-c/ic-shape-rectangle.svg +5 -0
- package/src/svg/icon-c/ic-shape-triangle.svg +5 -0
- package/src/svg/icon-c/ic-shape.svg +6 -0
- package/src/svg/icon-c/ic-text-align-center.svg +6 -0
- package/src/svg/icon-c/ic-text-align-left.svg +6 -0
- package/src/svg/icon-c/ic-text-align-right.svg +6 -0
- package/src/svg/icon-c/ic-text-bold.svg +7 -0
- package/src/svg/icon-c/ic-text-italic.svg +6 -0
- package/src/svg/icon-c/ic-text-underline.svg +7 -0
- package/src/svg/icon-c/ic-text.svg +7 -0
- package/src/svg/icon-c/ic-undo.svg +7 -0
- package/src/svg/icon-c/ic-zoom-hand.svg +8 -0
- package/src/svg/icon-c/ic-zoom-zoom-in.svg +12 -0
- package/src/svg/icon-c/ic-zoom-zoom-out.svg +11 -0
- package/src/svg/icon-c/img-bi.svg +5 -0
- package/src/svg/icon-d/ic-apply.svg +6 -0
- package/src/svg/icon-d/ic-cancel.svg +6 -0
- package/src/svg/icon-d/ic-crop.svg +7 -0
- package/src/svg/icon-d/ic-delete-all.svg +6 -0
- package/src/svg/icon-d/ic-delete.svg +6 -0
- package/src/svg/icon-d/ic-draw-free.svg +5 -0
- package/src/svg/icon-d/ic-draw-line.svg +5 -0
- package/src/svg/icon-d/ic-draw.svg +6 -0
- package/src/svg/icon-d/ic-filter.svg +7 -0
- package/src/svg/icon-d/ic-flip-reset.svg +7 -0
- package/src/svg/icon-d/ic-flip-x.svg +6 -0
- package/src/svg/icon-d/ic-flip-y.svg +6 -0
- package/src/svg/icon-d/ic-flip.svg +6 -0
- package/src/svg/icon-d/ic-history-check.svg +5 -0
- package/src/svg/icon-d/ic-history-crop.svg +7 -0
- package/src/svg/icon-d/ic-history-delete.svg +9 -0
- package/src/svg/icon-d/ic-history-draw.svg +7 -0
- package/src/svg/icon-d/ic-history-filter.svg +8 -0
- package/src/svg/icon-d/ic-history-flip.svg +6 -0
- package/src/svg/icon-d/ic-history-group.svg +9 -0
- package/src/svg/icon-d/ic-history-icon.svg +6 -0
- package/src/svg/icon-d/ic-history-load.svg +7 -0
- package/src/svg/icon-d/ic-history-mask.svg +9 -0
- package/src/svg/icon-d/ic-history-resize.svg +12 -0
- package/src/svg/icon-d/ic-history-rotate.svg +16 -0
- package/src/svg/icon-d/ic-history-shape.svg +7 -0
- package/src/svg/icon-d/ic-history-text.svg +8 -0
- package/src/svg/icon-d/ic-history.svg +6 -0
- package/src/svg/icon-d/ic-icon-arrow-2.svg +5 -0
- package/src/svg/icon-d/ic-icon-arrow-3.svg +5 -0
- package/src/svg/icon-d/ic-icon-arrow.svg +5 -0
- package/src/svg/icon-d/ic-icon-bubble.svg +5 -0
- package/src/svg/icon-d/ic-icon-heart.svg +5 -0
- package/src/svg/icon-d/ic-icon-load.svg +8 -0
- package/src/svg/icon-d/ic-icon-location.svg +8 -0
- package/src/svg/icon-d/ic-icon-polygon.svg +5 -0
- package/src/svg/icon-d/ic-icon-star-2.svg +5 -0
- package/src/svg/icon-d/ic-icon-star.svg +5 -0
- package/src/svg/icon-d/ic-icon.svg +5 -0
- package/src/svg/icon-d/ic-mask-load.svg +8 -0
- package/src/svg/icon-d/ic-mask.svg +6 -0
- package/src/svg/icon-d/ic-redo.svg +7 -0
- package/src/svg/icon-d/ic-reset.svg +7 -0
- package/src/svg/icon-d/ic-resize.svg +13 -0
- package/src/svg/icon-d/ic-rotate-clockwise.svg +7 -0
- package/src/svg/icon-d/ic-rotate-counterclockwise.svg +7 -0
- package/src/svg/icon-d/ic-rotate.svg +7 -0
- package/src/svg/icon-d/ic-shape-circle.svg +5 -0
- package/src/svg/icon-d/ic-shape-rectangle.svg +5 -0
- package/src/svg/icon-d/ic-shape-triangle.svg +5 -0
- package/src/svg/icon-d/ic-shape.svg +6 -0
- package/src/svg/icon-d/ic-text-align-center.svg +6 -0
- package/src/svg/icon-d/ic-text-align-left.svg +6 -0
- package/src/svg/icon-d/ic-text-align-right.svg +6 -0
- package/src/svg/icon-d/ic-text-bold.svg +7 -0
- package/src/svg/icon-d/ic-text-italic.svg +6 -0
- package/src/svg/icon-d/ic-text-underline.svg +7 -0
- package/src/svg/icon-d/ic-text.svg +7 -0
- package/src/svg/icon-d/ic-undo.svg +7 -0
- package/src/svg/icon-d/ic-zoom-hand.svg +8 -0
- package/src/svg/icon-d/ic-zoom-zoom-in.svg +12 -0
- package/src/svg/icon-d/ic-zoom-zoom-out.svg +11 -0
- package/src/svg/icon-d/img-bi.svg +5 -0
@@ -0,0 +1,407 @@
|
|
1
|
+
import { fabric } from 'fabric';
|
2
|
+
import extend from 'tui-code-snippet/object/extend';
|
3
|
+
import Component from '@/interface/component';
|
4
|
+
import Cropzone from '@/extension/cropzone';
|
5
|
+
import { keyCodes, componentNames, CROPZONE_DEFAULT_OPTIONS } from '@/consts';
|
6
|
+
import { clamp, fixFloatingPoint } from '@/util';
|
7
|
+
|
8
|
+
const MOUSE_MOVE_THRESHOLD = 10;
|
9
|
+
const DEFAULT_OPTION = {
|
10
|
+
presetRatio: null,
|
11
|
+
top: -10,
|
12
|
+
left: -10,
|
13
|
+
height: 1,
|
14
|
+
width: 1,
|
15
|
+
};
|
16
|
+
|
17
|
+
/**
|
18
|
+
* Cropper components
|
19
|
+
* @param {Graphics} graphics - Graphics instance
|
20
|
+
* @extends {Component}
|
21
|
+
* @class Cropper
|
22
|
+
* @ignore
|
23
|
+
*/
|
24
|
+
class Cropper extends Component {
|
25
|
+
constructor(graphics) {
|
26
|
+
super(componentNames.CROPPER, graphics);
|
27
|
+
|
28
|
+
/**
|
29
|
+
* Cropzone
|
30
|
+
* @type {Cropzone}
|
31
|
+
* @private
|
32
|
+
*/
|
33
|
+
this._cropzone = null;
|
34
|
+
|
35
|
+
/**
|
36
|
+
* StartX of Cropzone
|
37
|
+
* @type {number}
|
38
|
+
* @private
|
39
|
+
*/
|
40
|
+
this._startX = null;
|
41
|
+
|
42
|
+
/**
|
43
|
+
* StartY of Cropzone
|
44
|
+
* @type {number}
|
45
|
+
* @private
|
46
|
+
*/
|
47
|
+
this._startY = null;
|
48
|
+
|
49
|
+
/**
|
50
|
+
* State whether shortcut key is pressed or not
|
51
|
+
* @type {boolean}
|
52
|
+
* @private
|
53
|
+
*/
|
54
|
+
this._withShiftKey = false;
|
55
|
+
|
56
|
+
/**
|
57
|
+
* Listeners
|
58
|
+
* @type {object.<string, function>}
|
59
|
+
* @private
|
60
|
+
*/
|
61
|
+
this._listeners = {
|
62
|
+
keydown: this._onKeyDown.bind(this),
|
63
|
+
keyup: this._onKeyUp.bind(this),
|
64
|
+
mousedown: this._onFabricMouseDown.bind(this),
|
65
|
+
mousemove: this._onFabricMouseMove.bind(this),
|
66
|
+
mouseup: this._onFabricMouseUp.bind(this),
|
67
|
+
};
|
68
|
+
}
|
69
|
+
|
70
|
+
/**
|
71
|
+
* Start cropping
|
72
|
+
*/
|
73
|
+
start() {
|
74
|
+
if (this._cropzone) {
|
75
|
+
return;
|
76
|
+
}
|
77
|
+
const canvas = this.getCanvas();
|
78
|
+
|
79
|
+
canvas.forEachObject((obj) => {
|
80
|
+
// {@link http://fabricjs.com/docs/fabric.Object.html#evented}
|
81
|
+
obj.evented = false;
|
82
|
+
});
|
83
|
+
|
84
|
+
this._cropzone = new Cropzone(
|
85
|
+
canvas,
|
86
|
+
extend(
|
87
|
+
{
|
88
|
+
left: 0,
|
89
|
+
top: 0,
|
90
|
+
width: 0.5,
|
91
|
+
height: 0.5,
|
92
|
+
strokeWidth: 0, // {@link https://github.com/kangax/fabric.js/issues/2860}
|
93
|
+
cornerSize: 10,
|
94
|
+
cornerColor: 'black',
|
95
|
+
fill: 'transparent',
|
96
|
+
},
|
97
|
+
CROPZONE_DEFAULT_OPTIONS,
|
98
|
+
this.graphics.cropSelectionStyle
|
99
|
+
)
|
100
|
+
);
|
101
|
+
|
102
|
+
canvas.discardActiveObject();
|
103
|
+
canvas.add(this._cropzone);
|
104
|
+
canvas.on('mouse:down', this._listeners.mousedown);
|
105
|
+
canvas.selection = false;
|
106
|
+
canvas.defaultCursor = 'crosshair';
|
107
|
+
|
108
|
+
fabric.util.addListener(document, 'keydown', this._listeners.keydown);
|
109
|
+
fabric.util.addListener(document, 'keyup', this._listeners.keyup);
|
110
|
+
}
|
111
|
+
|
112
|
+
/**
|
113
|
+
* End cropping
|
114
|
+
*/
|
115
|
+
end() {
|
116
|
+
const canvas = this.getCanvas();
|
117
|
+
const cropzone = this._cropzone;
|
118
|
+
|
119
|
+
if (!cropzone) {
|
120
|
+
return;
|
121
|
+
}
|
122
|
+
canvas.remove(cropzone);
|
123
|
+
canvas.selection = true;
|
124
|
+
canvas.defaultCursor = 'default';
|
125
|
+
canvas.off('mouse:down', this._listeners.mousedown);
|
126
|
+
canvas.forEachObject((obj) => {
|
127
|
+
obj.evented = true;
|
128
|
+
});
|
129
|
+
|
130
|
+
this._cropzone = null;
|
131
|
+
|
132
|
+
fabric.util.removeListener(document, 'keydown', this._listeners.keydown);
|
133
|
+
fabric.util.removeListener(document, 'keyup', this._listeners.keyup);
|
134
|
+
}
|
135
|
+
|
136
|
+
/**
|
137
|
+
* Change cropzone visible
|
138
|
+
* @param {boolean} visible - cropzone visible state
|
139
|
+
*/
|
140
|
+
changeVisibility(visible) {
|
141
|
+
if (this._cropzone) {
|
142
|
+
this._cropzone.set({ visible });
|
143
|
+
}
|
144
|
+
}
|
145
|
+
|
146
|
+
/**
|
147
|
+
* onMousedown handler in fabric canvas
|
148
|
+
* @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event
|
149
|
+
* @private
|
150
|
+
*/
|
151
|
+
_onFabricMouseDown(fEvent) {
|
152
|
+
const canvas = this.getCanvas();
|
153
|
+
|
154
|
+
if (fEvent.target) {
|
155
|
+
return;
|
156
|
+
}
|
157
|
+
|
158
|
+
canvas.selection = false;
|
159
|
+
const coord = canvas.getPointer(fEvent.e);
|
160
|
+
|
161
|
+
this._startX = coord.x;
|
162
|
+
this._startY = coord.y;
|
163
|
+
|
164
|
+
canvas.on({
|
165
|
+
'mouse:move': this._listeners.mousemove,
|
166
|
+
'mouse:up': this._listeners.mouseup,
|
167
|
+
});
|
168
|
+
}
|
169
|
+
|
170
|
+
/**
|
171
|
+
* onMousemove handler in fabric canvas
|
172
|
+
* @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event
|
173
|
+
* @private
|
174
|
+
*/
|
175
|
+
_onFabricMouseMove(fEvent) {
|
176
|
+
const canvas = this.getCanvas();
|
177
|
+
const pointer = canvas.getPointer(fEvent.e);
|
178
|
+
const { x, y } = pointer;
|
179
|
+
const cropzone = this._cropzone;
|
180
|
+
|
181
|
+
if (Math.abs(x - this._startX) + Math.abs(y - this._startY) > MOUSE_MOVE_THRESHOLD) {
|
182
|
+
canvas.remove(cropzone);
|
183
|
+
cropzone.set(this._calcRectDimensionFromPoint(x, y, cropzone.presetRatio));
|
184
|
+
|
185
|
+
canvas.add(cropzone);
|
186
|
+
canvas.setActiveObject(cropzone);
|
187
|
+
}
|
188
|
+
}
|
189
|
+
|
190
|
+
/**
|
191
|
+
* Get rect dimension setting from Canvas-Mouse-Position(x, y)
|
192
|
+
* @param {number} x - Canvas-Mouse-Position x
|
193
|
+
* @param {number} y - Canvas-Mouse-Position Y
|
194
|
+
* @param {number|null} presetRatio - fixed aspect ratio (width/height) of the cropzone (null if not set)
|
195
|
+
* @returns {{left: number, top: number, width: number, height: number}}
|
196
|
+
* @private
|
197
|
+
*/
|
198
|
+
_calcRectDimensionFromPoint(x, y, presetRatio = null) {
|
199
|
+
const canvas = this.getCanvas();
|
200
|
+
const canvasWidth = canvas.getWidth();
|
201
|
+
const canvasHeight = canvas.getHeight();
|
202
|
+
const startX = this._startX;
|
203
|
+
const startY = this._startY;
|
204
|
+
let left = clamp(x, 0, startX);
|
205
|
+
let top = clamp(y, 0, startY);
|
206
|
+
let width = clamp(x, startX, canvasWidth) - left; // (startX <= x(mouse) <= canvasWidth) - left
|
207
|
+
let height = clamp(y, startY, canvasHeight) - top; // (startY <= y(mouse) <= canvasHeight) - top
|
208
|
+
|
209
|
+
if (this._withShiftKey && !presetRatio) {
|
210
|
+
// make fixed ratio cropzone
|
211
|
+
if (width > height) {
|
212
|
+
height = width;
|
213
|
+
} else if (height > width) {
|
214
|
+
width = height;
|
215
|
+
}
|
216
|
+
|
217
|
+
if (startX >= x) {
|
218
|
+
left = startX - width;
|
219
|
+
}
|
220
|
+
|
221
|
+
if (startY >= y) {
|
222
|
+
top = startY - height;
|
223
|
+
}
|
224
|
+
} else if (presetRatio) {
|
225
|
+
// Restrict cropzone to given presetRatio
|
226
|
+
height = width / presetRatio;
|
227
|
+
|
228
|
+
// If moving in a direction where the top left corner moves (ie. top-left, bottom-left, top-right)
|
229
|
+
// the left and/or top values has to be changed based on the new height/width
|
230
|
+
if (startX >= x) {
|
231
|
+
left = clamp(startX - width, 0, canvasWidth);
|
232
|
+
}
|
233
|
+
|
234
|
+
if (startY >= y) {
|
235
|
+
top = clamp(startY - height, 0, canvasHeight);
|
236
|
+
}
|
237
|
+
|
238
|
+
// Check if the new height is too large
|
239
|
+
if (top + height > canvasHeight) {
|
240
|
+
height = canvasHeight - top; // Set height to max available height
|
241
|
+
width = height * presetRatio; // Restrict cropzone to given presetRatio based on the new height
|
242
|
+
|
243
|
+
// If moving in a direction where the top left corner moves (ie. top-left, bottom-left, top-right)
|
244
|
+
// the left and/or top values has to be changed based on the new height/width
|
245
|
+
if (startX >= x) {
|
246
|
+
left = clamp(startX - width, 0, canvasWidth);
|
247
|
+
}
|
248
|
+
|
249
|
+
if (startY >= y) {
|
250
|
+
top = clamp(startY - height, 0, canvasHeight);
|
251
|
+
}
|
252
|
+
}
|
253
|
+
}
|
254
|
+
|
255
|
+
return {
|
256
|
+
left,
|
257
|
+
top,
|
258
|
+
width,
|
259
|
+
height,
|
260
|
+
};
|
261
|
+
}
|
262
|
+
|
263
|
+
/**
|
264
|
+
* onMouseup handler in fabric canvas
|
265
|
+
* @private
|
266
|
+
*/
|
267
|
+
_onFabricMouseUp() {
|
268
|
+
const cropzone = this._cropzone;
|
269
|
+
const listeners = this._listeners;
|
270
|
+
const canvas = this.getCanvas();
|
271
|
+
|
272
|
+
canvas.setActiveObject(cropzone);
|
273
|
+
canvas.off({
|
274
|
+
'mouse:move': listeners.mousemove,
|
275
|
+
'mouse:up': listeners.mouseup,
|
276
|
+
});
|
277
|
+
}
|
278
|
+
|
279
|
+
/**
|
280
|
+
* Get cropped image data
|
281
|
+
* @param {Object} cropRect cropzone rect
|
282
|
+
* @param {Number} cropRect.left left position
|
283
|
+
* @param {Number} cropRect.top top position
|
284
|
+
* @param {Number} cropRect.width width
|
285
|
+
* @param {Number} cropRect.height height
|
286
|
+
* @returns {?{imageName: string, url: string}} cropped Image data
|
287
|
+
*/
|
288
|
+
getCroppedImageData(cropRect) {
|
289
|
+
const canvas = this.getCanvas();
|
290
|
+
const containsCropzone = canvas.contains(this._cropzone);
|
291
|
+
if (!cropRect) {
|
292
|
+
return null;
|
293
|
+
}
|
294
|
+
|
295
|
+
if (containsCropzone) {
|
296
|
+
canvas.remove(this._cropzone);
|
297
|
+
}
|
298
|
+
|
299
|
+
const imageData = {
|
300
|
+
imageName: this.getImageName(),
|
301
|
+
url: canvas.toDataURL(cropRect),
|
302
|
+
};
|
303
|
+
|
304
|
+
if (containsCropzone) {
|
305
|
+
canvas.add(this._cropzone);
|
306
|
+
}
|
307
|
+
|
308
|
+
return imageData;
|
309
|
+
}
|
310
|
+
|
311
|
+
/**
|
312
|
+
* Get cropped rect
|
313
|
+
* @returns {Object} rect
|
314
|
+
*/
|
315
|
+
getCropzoneRect() {
|
316
|
+
const cropzone = this._cropzone;
|
317
|
+
|
318
|
+
if (!cropzone.isValid()) {
|
319
|
+
return null;
|
320
|
+
}
|
321
|
+
|
322
|
+
return {
|
323
|
+
left: cropzone.left,
|
324
|
+
top: cropzone.top,
|
325
|
+
width: cropzone.width,
|
326
|
+
height: cropzone.height,
|
327
|
+
};
|
328
|
+
}
|
329
|
+
|
330
|
+
/**
|
331
|
+
* Set a cropzone square
|
332
|
+
* @param {number} [presetRatio] - preset ratio
|
333
|
+
*/
|
334
|
+
setCropzoneRect(presetRatio) {
|
335
|
+
const canvas = this.getCanvas();
|
336
|
+
const cropzone = this._cropzone;
|
337
|
+
|
338
|
+
canvas.discardActiveObject();
|
339
|
+
canvas.selection = false;
|
340
|
+
canvas.remove(cropzone);
|
341
|
+
|
342
|
+
cropzone.set(presetRatio ? this._getPresetPropertiesForCropSize(presetRatio) : DEFAULT_OPTION);
|
343
|
+
|
344
|
+
canvas.add(cropzone);
|
345
|
+
canvas.selection = true;
|
346
|
+
|
347
|
+
if (presetRatio) {
|
348
|
+
canvas.setActiveObject(cropzone);
|
349
|
+
}
|
350
|
+
}
|
351
|
+
|
352
|
+
/**
|
353
|
+
* get a cropzone square info
|
354
|
+
* @param {number} presetRatio - preset ratio
|
355
|
+
* @returns {{presetRatio: number, left: number, top: number, width: number, height: number}}
|
356
|
+
* @private
|
357
|
+
*/
|
358
|
+
_getPresetPropertiesForCropSize(presetRatio) {
|
359
|
+
const canvas = this.getCanvas();
|
360
|
+
const originalWidth = canvas.getWidth();
|
361
|
+
const originalHeight = canvas.getHeight();
|
362
|
+
|
363
|
+
const standardSize = originalWidth >= originalHeight ? originalWidth : originalHeight;
|
364
|
+
const getScale = (value, orignalValue) => (value > orignalValue ? orignalValue / value : 1);
|
365
|
+
|
366
|
+
let width = standardSize * presetRatio;
|
367
|
+
let height = standardSize;
|
368
|
+
|
369
|
+
const scaleWidth = getScale(width, originalWidth);
|
370
|
+
[width, height] = [width, height].map((sizeValue) => sizeValue * scaleWidth);
|
371
|
+
|
372
|
+
const scaleHeight = getScale(height, originalHeight);
|
373
|
+
[width, height] = [width, height].map((sizeValue) => fixFloatingPoint(sizeValue * scaleHeight));
|
374
|
+
|
375
|
+
return {
|
376
|
+
presetRatio,
|
377
|
+
top: (originalHeight - height) / 2,
|
378
|
+
left: (originalWidth - width) / 2,
|
379
|
+
width,
|
380
|
+
height,
|
381
|
+
};
|
382
|
+
}
|
383
|
+
|
384
|
+
/**
|
385
|
+
* Keydown event handler
|
386
|
+
* @param {KeyboardEvent} e - Event object
|
387
|
+
* @private
|
388
|
+
*/
|
389
|
+
_onKeyDown(e) {
|
390
|
+
if (e.keyCode === keyCodes.SHIFT) {
|
391
|
+
this._withShiftKey = true;
|
392
|
+
}
|
393
|
+
}
|
394
|
+
|
395
|
+
/**
|
396
|
+
* Keyup event handler
|
397
|
+
* @param {KeyboardEvent} e - Event object
|
398
|
+
* @private
|
399
|
+
*/
|
400
|
+
_onKeyUp(e) {
|
401
|
+
if (e.keyCode === keyCodes.SHIFT) {
|
402
|
+
this._withShiftKey = false;
|
403
|
+
}
|
404
|
+
}
|
405
|
+
}
|
406
|
+
|
407
|
+
export default Cropper;
|
@@ -0,0 +1,229 @@
|
|
1
|
+
import isUndefined from 'tui-code-snippet/type/isUndefined';
|
2
|
+
import extend from 'tui-code-snippet/object/extend';
|
3
|
+
import forEach from 'tui-code-snippet/collection/forEach';
|
4
|
+
import { fabric } from 'fabric';
|
5
|
+
import Component from '@/interface/component';
|
6
|
+
import { rejectMessages, componentNames } from '@/consts';
|
7
|
+
import Mask from '@/extension/mask';
|
8
|
+
import Sharpen from '@/extension/sharpen';
|
9
|
+
import Emboss from '@/extension/emboss';
|
10
|
+
import ColorFilter from '@/extension/colorFilter';
|
11
|
+
|
12
|
+
const { filters } = fabric.Image;
|
13
|
+
|
14
|
+
filters.Mask = Mask;
|
15
|
+
filters.Sharpen = Sharpen;
|
16
|
+
filters.Emboss = Emboss;
|
17
|
+
filters.ColorFilter = ColorFilter;
|
18
|
+
|
19
|
+
/**
|
20
|
+
* Filter
|
21
|
+
* @class Filter
|
22
|
+
* @param {Graphics} graphics - Graphics instance
|
23
|
+
* @extends {Component}
|
24
|
+
* @ignore
|
25
|
+
*/
|
26
|
+
class Filter extends Component {
|
27
|
+
constructor(graphics) {
|
28
|
+
super(componentNames.FILTER, graphics);
|
29
|
+
}
|
30
|
+
|
31
|
+
/**
|
32
|
+
* Add filter to source image (a specific filter is added on fabric.js)
|
33
|
+
* @param {string} type - Filter type
|
34
|
+
* @param {Object} [options] - Options of filter
|
35
|
+
* @returns {Promise}
|
36
|
+
*/
|
37
|
+
add(type, options) {
|
38
|
+
return new Promise((resolve, reject) => {
|
39
|
+
const sourceImg = this._getSourceImage();
|
40
|
+
const canvas = this.getCanvas();
|
41
|
+
let imgFilter = this._getFilter(sourceImg, type);
|
42
|
+
if (!imgFilter) {
|
43
|
+
imgFilter = this._createFilter(sourceImg, type, options);
|
44
|
+
}
|
45
|
+
|
46
|
+
if (!imgFilter) {
|
47
|
+
reject(rejectMessages.invalidParameters);
|
48
|
+
}
|
49
|
+
|
50
|
+
this._changeFilterValues(imgFilter, options);
|
51
|
+
|
52
|
+
this._apply(sourceImg, () => {
|
53
|
+
canvas.renderAll();
|
54
|
+
resolve({
|
55
|
+
type,
|
56
|
+
action: 'add',
|
57
|
+
options,
|
58
|
+
});
|
59
|
+
});
|
60
|
+
});
|
61
|
+
}
|
62
|
+
|
63
|
+
/**
|
64
|
+
* Remove filter to source image
|
65
|
+
* @param {string} type - Filter type
|
66
|
+
* @returns {Promise}
|
67
|
+
*/
|
68
|
+
remove(type) {
|
69
|
+
return new Promise((resolve, reject) => {
|
70
|
+
const sourceImg = this._getSourceImage();
|
71
|
+
const canvas = this.getCanvas();
|
72
|
+
const options = this.getOptions(type);
|
73
|
+
|
74
|
+
if (!sourceImg.filters.length) {
|
75
|
+
reject(rejectMessages.unsupportedOperation);
|
76
|
+
}
|
77
|
+
|
78
|
+
this._removeFilter(sourceImg, type);
|
79
|
+
|
80
|
+
this._apply(sourceImg, () => {
|
81
|
+
canvas.renderAll();
|
82
|
+
resolve({
|
83
|
+
type,
|
84
|
+
action: 'remove',
|
85
|
+
options,
|
86
|
+
});
|
87
|
+
});
|
88
|
+
});
|
89
|
+
}
|
90
|
+
|
91
|
+
/**
|
92
|
+
* Whether this has the filter or not
|
93
|
+
* @param {string} type - Filter type
|
94
|
+
* @returns {boolean} true if it has the filter
|
95
|
+
*/
|
96
|
+
hasFilter(type) {
|
97
|
+
return !!this._getFilter(this._getSourceImage(), type);
|
98
|
+
}
|
99
|
+
|
100
|
+
/**
|
101
|
+
* Get a filter options
|
102
|
+
* @param {string} type - Filter type
|
103
|
+
* @returns {Object} filter options or null if there is no that filter
|
104
|
+
*/
|
105
|
+
getOptions(type) {
|
106
|
+
const sourceImg = this._getSourceImage();
|
107
|
+
const imgFilter = this._getFilter(sourceImg, type);
|
108
|
+
if (!imgFilter) {
|
109
|
+
return null;
|
110
|
+
}
|
111
|
+
|
112
|
+
return extend({}, imgFilter.options);
|
113
|
+
}
|
114
|
+
|
115
|
+
/**
|
116
|
+
* Change filter values
|
117
|
+
* @param {Object} imgFilter object of filter
|
118
|
+
* @param {Object} options object
|
119
|
+
* @private
|
120
|
+
*/
|
121
|
+
_changeFilterValues(imgFilter, options) {
|
122
|
+
forEach(options, (value, key) => {
|
123
|
+
if (!isUndefined(imgFilter[key])) {
|
124
|
+
imgFilter[key] = value;
|
125
|
+
}
|
126
|
+
});
|
127
|
+
forEach(imgFilter.options, (value, key) => {
|
128
|
+
if (!isUndefined(options[key])) {
|
129
|
+
imgFilter.options[key] = options[key];
|
130
|
+
}
|
131
|
+
});
|
132
|
+
}
|
133
|
+
|
134
|
+
/**
|
135
|
+
* Apply filter
|
136
|
+
* @param {fabric.Image} sourceImg - Source image to apply filter
|
137
|
+
* @param {function} callback - Executed function after applying filter
|
138
|
+
* @private
|
139
|
+
*/
|
140
|
+
_apply(sourceImg, callback) {
|
141
|
+
sourceImg.filters.push();
|
142
|
+
const result = sourceImg.applyFilters();
|
143
|
+
if (result) {
|
144
|
+
callback();
|
145
|
+
}
|
146
|
+
}
|
147
|
+
|
148
|
+
/**
|
149
|
+
* Get source image on canvas
|
150
|
+
* @returns {fabric.Image} Current source image on canvas
|
151
|
+
* @private
|
152
|
+
*/
|
153
|
+
_getSourceImage() {
|
154
|
+
return this.getCanvasImage();
|
155
|
+
}
|
156
|
+
|
157
|
+
/**
|
158
|
+
* Create filter instance
|
159
|
+
* @param {fabric.Image} sourceImg - Source image to apply filter
|
160
|
+
* @param {string} type - Filter type
|
161
|
+
* @param {Object} [options] - Options of filter
|
162
|
+
* @returns {Object} Fabric object of filter
|
163
|
+
* @private
|
164
|
+
*/
|
165
|
+
_createFilter(sourceImg, type, options) {
|
166
|
+
let filterObj;
|
167
|
+
// capitalize first letter for matching with fabric image filter name
|
168
|
+
const fabricType = this._getFabricFilterType(type);
|
169
|
+
const ImageFilter = fabric.Image.filters[fabricType];
|
170
|
+
if (ImageFilter) {
|
171
|
+
filterObj = new ImageFilter(options);
|
172
|
+
filterObj.options = options;
|
173
|
+
sourceImg.filters.push(filterObj);
|
174
|
+
}
|
175
|
+
|
176
|
+
return filterObj;
|
177
|
+
}
|
178
|
+
|
179
|
+
/**
|
180
|
+
* Get applied filter instance
|
181
|
+
* @param {fabric.Image} sourceImg - Source image to apply filter
|
182
|
+
* @param {string} type - Filter type
|
183
|
+
* @returns {Object} Fabric object of filter
|
184
|
+
* @private
|
185
|
+
*/
|
186
|
+
_getFilter(sourceImg, type) {
|
187
|
+
let imgFilter = null;
|
188
|
+
|
189
|
+
if (sourceImg) {
|
190
|
+
const fabricType = this._getFabricFilterType(type);
|
191
|
+
const { length } = sourceImg.filters;
|
192
|
+
let item, i;
|
193
|
+
|
194
|
+
for (i = 0; i < length; i += 1) {
|
195
|
+
item = sourceImg.filters[i];
|
196
|
+
if (item.type === fabricType) {
|
197
|
+
imgFilter = item;
|
198
|
+
break;
|
199
|
+
}
|
200
|
+
}
|
201
|
+
}
|
202
|
+
|
203
|
+
return imgFilter;
|
204
|
+
}
|
205
|
+
|
206
|
+
/**
|
207
|
+
* Remove applied filter instance
|
208
|
+
* @param {fabric.Image} sourceImg - Source image to apply filter
|
209
|
+
* @param {string} type - Filter type
|
210
|
+
* @private
|
211
|
+
*/
|
212
|
+
_removeFilter(sourceImg, type) {
|
213
|
+
const fabricType = this._getFabricFilterType(type);
|
214
|
+
sourceImg.filters = sourceImg.filters.filter((value) => value.type !== fabricType);
|
215
|
+
}
|
216
|
+
|
217
|
+
/**
|
218
|
+
* Change filter class name to fabric's, especially capitalizing first letter
|
219
|
+
* @param {string} type - Filter type
|
220
|
+
* @example
|
221
|
+
* 'grayscale' -> 'Grayscale'
|
222
|
+
* @returns {string} Fabric filter class name
|
223
|
+
*/
|
224
|
+
_getFabricFilterType(type) {
|
225
|
+
return type.charAt(0).toUpperCase() + type.slice(1);
|
226
|
+
}
|
227
|
+
}
|
228
|
+
|
229
|
+
export default Filter;
|