antd-react-cropper
Version:
An image cropper for Ant Design Upload using React Cropper.
421 lines (363 loc) • 18.6 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var React = require('react');
var antd = require('antd');
var Cropper = require('react-cropper');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
var Cropper__default = /*#__PURE__*/_interopDefaultLegacy(Cropper);
function styleInject(css, ref) {
if ( ref === void 0 ) ref = {};
var insertAt = ref.insertAt;
if (!css || typeof document === 'undefined') { return; }
var head = document.head || document.getElementsByTagName('head')[0];
var style = document.createElement('style');
style.type = 'text/css';
if (insertAt === 'top') {
if (head.firstChild) {
head.insertBefore(style, head.firstChild);
} else {
head.appendChild(style);
}
} else {
head.appendChild(style);
}
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
}
var css_248z = "/*!\n * Cropper.js v1.5.12\n * https://fengyuanchen.github.io/cropperjs\n *\n * Copyright 2015-present Chen Fengyuan\n * Released under the MIT license\n *\n * Date: 2021-06-12T08:00:11.623Z\n */\n\n.cropper-container {\n direction: ltr;\n font-size: 0;\n line-height: 0;\n position: relative;\n -ms-touch-action: none;\n touch-action: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.cropper-container img {\n display: block;\n height: 100%;\n image-orientation: 0deg;\n max-height: none !important;\n max-width: none !important;\n min-height: 0 !important;\n min-width: 0 !important;\n width: 100%;\n}\n\n.cropper-wrap-box,\n.cropper-canvas,\n.cropper-drag-box,\n.cropper-crop-box,\n.cropper-modal {\n bottom: 0;\n left: 0;\n position: absolute;\n right: 0;\n top: 0;\n}\n\n.cropper-wrap-box,\n.cropper-canvas {\n overflow: hidden;\n}\n\n.cropper-drag-box {\n background-color: #fff;\n opacity: 0;\n}\n\n.cropper-modal {\n background-color: #000;\n opacity: 0.5;\n}\n\n.cropper-view-box {\n display: block;\n height: 100%;\n outline: 1px solid #39f;\n outline-color: rgba(51, 153, 255, 0.75);\n overflow: hidden;\n width: 100%;\n}\n\n.cropper-dashed {\n border: 0 dashed #eee;\n display: block;\n opacity: 0.5;\n position: absolute;\n}\n\n.cropper-dashed.dashed-h {\n border-bottom-width: 1px;\n border-top-width: 1px;\n height: calc(100% / 3);\n left: 0;\n top: calc(100% / 3);\n width: 100%;\n}\n\n.cropper-dashed.dashed-v {\n border-left-width: 1px;\n border-right-width: 1px;\n height: 100%;\n left: calc(100% / 3);\n top: 0;\n width: calc(100% / 3);\n}\n\n.cropper-center {\n display: block;\n height: 0;\n left: 50%;\n opacity: 0.75;\n position: absolute;\n top: 50%;\n width: 0;\n}\n\n.cropper-center::before,\n.cropper-center::after {\n background-color: #eee;\n content: ' ';\n display: block;\n position: absolute;\n}\n\n.cropper-center::before {\n height: 1px;\n left: -3px;\n top: 0;\n width: 7px;\n}\n\n.cropper-center::after {\n height: 7px;\n left: 0;\n top: -3px;\n width: 1px;\n}\n\n.cropper-face,\n.cropper-line,\n.cropper-point {\n display: block;\n height: 100%;\n opacity: 0.1;\n position: absolute;\n width: 100%;\n}\n\n.cropper-face {\n background-color: #fff;\n left: 0;\n top: 0;\n}\n\n.cropper-line {\n background-color: #39f;\n}\n\n.cropper-line.line-e {\n cursor: ew-resize;\n right: -3px;\n top: 0;\n width: 5px;\n}\n\n.cropper-line.line-n {\n cursor: ns-resize;\n height: 5px;\n left: 0;\n top: -3px;\n}\n\n.cropper-line.line-w {\n cursor: ew-resize;\n left: -3px;\n top: 0;\n width: 5px;\n}\n\n.cropper-line.line-s {\n bottom: -3px;\n cursor: ns-resize;\n height: 5px;\n left: 0;\n}\n\n.cropper-point {\n background-color: #39f;\n height: 5px;\n opacity: 0.75;\n width: 5px;\n}\n\n.cropper-point.point-e {\n cursor: ew-resize;\n margin-top: -3px;\n right: -3px;\n top: 50%;\n}\n\n.cropper-point.point-n {\n cursor: ns-resize;\n left: 50%;\n margin-left: -3px;\n top: -3px;\n}\n\n.cropper-point.point-w {\n cursor: ew-resize;\n left: -3px;\n margin-top: -3px;\n top: 50%;\n}\n\n.cropper-point.point-s {\n bottom: -3px;\n cursor: s-resize;\n left: 50%;\n margin-left: -3px;\n}\n\n.cropper-point.point-ne {\n cursor: nesw-resize;\n right: -3px;\n top: -3px;\n}\n\n.cropper-point.point-nw {\n cursor: nwse-resize;\n left: -3px;\n top: -3px;\n}\n\n.cropper-point.point-sw {\n bottom: -3px;\n cursor: nesw-resize;\n left: -3px;\n}\n\n.cropper-point.point-se {\n bottom: -3px;\n cursor: nwse-resize;\n height: 20px;\n opacity: 1;\n right: -3px;\n width: 20px;\n}\n\n@media (min-width: 768px) {\n .cropper-point.point-se {\n height: 15px;\n width: 15px;\n }\n}\n\n@media (min-width: 992px) {\n .cropper-point.point-se {\n height: 10px;\n width: 10px;\n }\n}\n\n@media (min-width: 1200px) {\n .cropper-point.point-se {\n height: 5px;\n opacity: 0.75;\n width: 5px;\n }\n}\n\n.cropper-point.point-se::before {\n background-color: #39f;\n bottom: -50%;\n content: ' ';\n display: block;\n height: 200%;\n opacity: 0;\n position: absolute;\n right: -50%;\n width: 200%;\n}\n\n.cropper-invisible {\n opacity: 0;\n}\n\n.cropper-bg {\n background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC');\n}\n\n.cropper-hide {\n display: block;\n height: 0;\n position: absolute;\n width: 0;\n}\n\n.cropper-hidden {\n display: none !important;\n}\n\n.cropper-move {\n cursor: move;\n}\n\n.cropper-crop {\n cursor: crosshair;\n}\n\n.cropper-disabled .cropper-drag-box,\n.cropper-disabled .cropper-face,\n.cropper-disabled .cropper-line,\n.cropper-disabled .cropper-point {\n cursor: not-allowed;\n}\n";
styleInject(css_248z);
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
enumerableOnly && (symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
})), keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread2(target) {
for (var i = 1; i < arguments.length; i++) {
var source = null != arguments[i] ? arguments[i] : {};
i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
_defineProperty(target, key, source[key]);
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
return target;
}
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _slicedToArray(arr, i) {
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
}
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterableToArrayLimit(arr, i) {
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
if (_i == null) return;
var _arr = [];
var _n = true;
var _d = false;
var _s, _e;
try {
for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var css_248z$1 = ".container {\n display: flex;\n width: 100%;\n height: 100%;\n}\n.img-cropper {\n width: 100%;\n height: 100%;\n border-radius: 6px;\n}\n.img-cropper .cropper-container,\n.img-cropper .cropper-crop-box,\n.img-cropper .cropper-drag-box,\n.img-cropper .cropper-wrap-box {\n border-radius: 6px !important;\n}\n.slider-container {\n display: flex;\n align-items: center;\n justify-self: center;\n width: 100%;\n margin: 4px 0px;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n.slider-container .slider {\n flex: 1;\n margin-right: 20px !important;\n margin-left: 20px !important;\n}\n.preview-container {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: '100%';\n overflow: hidden;\n border-radius: 6px;\n position: 'relative';\n}\n.preview-container .preview-content {\n float: left;\n width: '100%';\n overflow: hidden;\n}\n.divider {\n margin-top: 4px !important;\n margin-bottom: 16px !important;\n}\n.flex {\n display: flex;\n}\n.flex-center {\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n}\n.modal-footer {\n display: flex;\n}\n.action-btn {\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n width: 20px;\n padding: 0 !important;\n}\n";
styleInject(css_248z$1);
var maxZoom = 10;
var ImageCropper = function ImageCropper(props) {
var aspect = props.aspect,
file = props.file,
onCropped = props.onCropped,
previewMaxHeight = props.previewMaxHeight,
title = props.title;
var screens = antd.Grid.useBreakpoint();
var _useState = React.useState(),
_useState2 = _slicedToArray(_useState, 2),
src = _useState2[0],
setSrc = _useState2[1];
var _useState3 = React.useState(),
_useState4 = _slicedToArray(_useState3, 2),
cropper = _useState4[0],
setCropper = _useState4[1];
var _useState5 = React.useState(0),
_useState6 = _slicedToArray(_useState5, 2),
zoom = _useState6[0],
setZoom = _useState6[1];
var _useState7 = React.useState(0),
_useState8 = _slicedToArray(_useState7, 2),
rotate = _useState8[0],
setRotate = _useState8[1];
var _useState9 = React.useState(),
_useState10 = _slicedToArray(_useState9, 2),
canvasData = _useState10[0],
setCanvasData = _useState10[1];
React.useEffect(function () {
if (file && file.originFileObj) getFileUrl(file.originFileObj, setSrc);
}, [file]);
React.useEffect(function () {
if (!src) {
setZoom(0);
setRotate(0);
setCanvasData(undefined);
setCropper(undefined);
}
}, [src]);
React.useEffect(function () {
if (cropper) cropper.rotateTo(rotate);
}, [rotate]);
var onZoomIn = function onZoomIn() {
var to = zoom + 1;
if (to > maxZoom) to = maxZoom;
setZoom(to);
onZoom(to);
};
var onZoomOut = function onZoomOut() {
var to = zoom - 1;
if (to <= 0) to = 0;
setZoom(to);
onZoom(to);
};
var onZoomSlide = function onZoomSlide(value) {
setZoom(value);
onZoom(value);
};
var onRotateLeft = function onRotateLeft() {
var to = rotate - 15;
if (to <= -180) to = -180;
setRotate(to);
};
var onRotateRight = function onRotateRight() {
var to = rotate + 15;
if (to >= 180) to = 180;
setRotate(to);
};
var onCrop = function onCrop() {
if (typeof cropper !== 'undefined') {
var loader;
if (props.showLoader) loader = antd.message.loading('Processing image...', 0);
var cropped = cropper.getCroppedCanvas();
var thumbUrl = cropped.toDataURL('image/jpeg');
cropped.toBlob(function (blob) {
if (!blob) return;
var newFile = new File([blob], file.name);
var data = _objectSpread2(_objectSpread2({}, file), {}, {
thumbUrl: thumbUrl,
originFileObj: newFile
});
if (loader) loader();
onCropped === null || onCropped === void 0 ? void 0 : onCropped(data);
}, props.exportFileType);
}
setSrc(undefined);
};
var onCancel = function onCancel() {
setSrc(undefined);
if (props.onCancel) props.onCancel();
};
var onZoom = function onZoom(value) {
if (!cropper) return;
if (!canvasData) setCanvasData(cropper.getCanvasData());
if (value > maxZoom) return;
if (value <= 0) {
cropper.setCanvasData(canvasData);
} else if (value > zoom) {
var diff = value - zoom;
cropper.zoom(diff * 0.2);
} else {
var _diff = zoom - value;
cropper.zoom(_diff * -0.2);
}
};
return /*#__PURE__*/React__default['default'].createElement(antd.Modal, {
title: title,
zIndex: props.zIndex,
centered: props.centered,
width: props.width,
closable: props.closable || false,
bodyStyle: props.bodyStyle || {
paddingBottom: 0
},
maskClosable: props.maskClosable,
destroyOnClose: true,
visible: !!src,
onCancel: onCancel,
footer: props.customFooter ? props.customFooter({
onCrop: onCrop,
onCancel: onCancel
}) : /*#__PURE__*/React__default['default'].createElement("div", {
className: "modal-footer"
}, /*#__PURE__*/React__default['default'].createElement(antd.Button, {
onClick: onCancel
}, props.cancelText), /*#__PURE__*/React__default['default'].createElement(antd.Button, {
block: true,
type: "primary",
onClick: onCrop
}, props.cropText))
}, /*#__PURE__*/React__default['default'].createElement(antd.Row, {
gutter: 12
}, /*#__PURE__*/React__default['default'].createElement(antd.Col, {
xs: 24,
sm: 16
}, /*#__PURE__*/React__default['default'].createElement("div", null, src && /*#__PURE__*/React__default['default'].createElement(Cropper__default['default'], {
className: "img-cropper ".concat(props.cropperClassName || ''),
style: props.cropperStyle,
dragMode: "move",
aspectRatio: aspect,
preview: ".img-preview",
src: src,
viewMode: 0,
background: true,
center: true,
autoCropArea: 1,
scalable: false,
movable: true,
onInitialized: setCropper,
checkOrientation: false
}), /*#__PURE__*/React__default['default'].createElement("div", {
className: "slider-container"
}, props.zoomOutButton ? props.zoomOutButton(onZoomOut) : /*#__PURE__*/React__default['default'].createElement(antd.Button, {
className: "action-btn",
type: "link",
onClick: onZoomOut
}, /*#__PURE__*/React__default['default'].createElement("span", {
style: {
fontSize: 20
}
}, "-")), /*#__PURE__*/React__default['default'].createElement(antd.Slider, {
className: "slider",
value: zoom,
min: 0,
max: maxZoom,
onChange: onZoomSlide
}), props.zoomInButton ? props.zoomInButton(onZoomIn) : /*#__PURE__*/React__default['default'].createElement(antd.Button, {
className: "action-btn",
type: "link",
onClick: onZoomIn
}, /*#__PURE__*/React__default['default'].createElement("span", {
style: {
fontSize: 20
}
}, "+"))), /*#__PURE__*/React__default['default'].createElement("div", {
className: "slider-container"
}, props.rotateLeftButton ? props.rotateLeftButton(onRotateLeft) : /*#__PURE__*/React__default['default'].createElement(antd.Button, {
className: "action-btn",
type: "link",
onClick: onRotateLeft
}, /*#__PURE__*/React__default['default'].createElement("span", {
style: {
fontSize: 15
}
}, "\u21BA")), /*#__PURE__*/React__default['default'].createElement("div", {
style: {
flex: 1
},
onDoubleClick: function onDoubleClick() {
return setRotate(0);
}
}, /*#__PURE__*/React__default['default'].createElement(antd.Slider, {
className: "slider",
value: rotate,
min: -180,
max: 180,
onChange: setRotate
})), props.rotateRightButton ? props.rotateRightButton(onRotateRight) : /*#__PURE__*/React__default['default'].createElement(antd.Button, {
className: "action-btn",
type: "link",
onClick: onRotateRight
}, /*#__PURE__*/React__default['default'].createElement("span", {
style: {
fontSize: 15
}
}, "\u21BB"))))), /*#__PURE__*/React__default['default'].createElement(antd.Col, {
xs: 24,
sm: 8
}, screens.xs && /*#__PURE__*/React__default['default'].createElement(antd.Divider, {
className: "divider"
}), /*#__PURE__*/React__default['default'].createElement("div", {
className: "preview-container ".concat(props.previewClassName || ''),
style: _objectSpread2(_objectSpread2({}, props.previewStyle), {}, {
maxHeight: previewMaxHeight,
backgroundColor: props.previewBackground
})
}, /*#__PURE__*/React__default['default'].createElement("div", {
className: "img-preview",
style: {
width: '100%',
height: previewMaxHeight,
float: 'left',
overflow: 'hidden',
background: '#000'
}
})))));
};
var getFileUrl = function getFileUrl(file, callback) {
return new Promise(function (resolve) {
var reader = new FileReader();
reader.onload = function () {
resolve(reader.result);
callback === null || callback === void 0 ? void 0 : callback(reader.result);
};
reader.readAsDataURL(file);
});
};
ImageCropper.defaultProps = {
centered: true,
width: 500,
previewMaxHeight: 150,
previewBackground: 'rgba(212, 212, 216)',
cropText: 'Crop',
cancelText: 'Cancel',
showLoader: true,
exportFileType: 'image/jpeg'
};
exports.ImageCropper = ImageCropper;
exports.default = ImageCropper;