UNPKG

choerodon-ui

Version:

An enterprise-class UI design language and React-based implementation

615 lines (514 loc) 21.1 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"]; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard")["default"]; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "ShapeCroper", { enumerable: true, get: function get() { return _enum.ShapeCroper; } }); exports["default"] = void 0; var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2")); var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _react = _interopRequireWildcard(require("react")); var _reactEasyCrop = _interopRequireDefault(require("react-easy-crop")); var _isFunction = _interopRequireDefault(require("lodash/isFunction")); var _LocaleReceiver = _interopRequireDefault(require("../locale-provider/LocaleReceiver")); var _modal = _interopRequireDefault(require("../modal")); var _default2 = _interopRequireDefault(require("../locale-provider/default")); var _button = _interopRequireDefault(require("../button")); var _ButtonGroup = _interopRequireDefault(require("../button/ButtonGroup")); var _upload = _interopRequireDefault(require("../upload")); var _avatarUpload = _interopRequireDefault(require("./avatarUpload")); var _enum = require("./enum"); var _ConfigContext = _interopRequireDefault(require("../config-provider/ConfigContext")); var _excluded = ["beforeUpload", "accept"]; // ssr if (typeof window !== 'undefined') { // 兼容ie11 remove 方法 (function (arr) { arr.forEach(function (item) { // eslint-disable-next-line no-prototype-builtins if (item.hasOwnProperty('remove')) { return; } Object.defineProperty(item, 'remove', { configurable: true, enumerable: true, writable: true, value: function remove() { if (this.parentNode === null) { return; } this.parentNode.removeChild(this); } }); }); // 兼容IE if (!HTMLCanvasElement.prototype.toBlob) { Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', { value: function value(callback, type, quality) { var _this = this; setTimeout(function () { var binStr = atob(_this.toDataURL(type, quality).split(',')[1]); var len = binStr.length; var arrArray = new Uint8Array(len); for (var i = 0; i < len; i++) { arrArray[i] = binStr.charCodeAt(i); } callback(new Blob([arrArray], { type: type || 'image/png' })); }); } }); } })([Element.prototype, CharacterData.prototype, DocumentType.prototype]); } var MIN_ZOOM = 1; var MAX_ZOOM = 3; var ZOOM_STEP = 0.1; var EasyCrop = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) { var src = props.src, aspect = props.aspect, shape = props.shape, grid = props.grid, hasZoom = props.hasZoom, zoomVal = props.zoomVal, rotateVal = props.rotateVal, setZoomVal = props.setZoomVal, setRotateVal = props.setRotateVal, onComplete = props.onComplete, prefixCls = props.prefixCls; var _useState = (0, _react.useState)({ x: 0, y: 0 }), _useState2 = (0, _slicedToArray2["default"])(_useState, 2), crop = _useState2[0], setCrop = _useState2[1]; var onCropComplete = (0, _react.useCallback)(function (_croppedArea, croppedAreaPixels) { croppedAreaPixels.zoom = zoomVal || 0; croppedAreaPixels.rotate = rotateVal || 0; onComplete(croppedAreaPixels); }, [onComplete, zoomVal, rotateVal]); return /*#__PURE__*/_react["default"].createElement(_reactEasyCrop["default"], { ref: ref, image: src, aspect: aspect, cropShape: shape, showGrid: grid, zoomWithScroll: hasZoom, crop: crop, zoom: zoomVal, rotation: rotateVal, onCropChange: setCrop, onZoomChange: setZoomVal, onRotationChange: setRotateVal, onCropComplete: onCropComplete, classes: { containerClassName: "".concat(prefixCls, "-container"), mediaClassName: "".concat(prefixCls, "-media") } }); }); // 图片转化为canvas var imageToCanvas = function imageToCanvas(image) { var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); canvas.width = image.naturalWidth; canvas.height = image.naturalHeight; if (ctx) { ctx.drawImage(image, 0, 0); return canvas; } return undefined; }; var ImgCrop = /*#__PURE__*/(0, _react.forwardRef)(function ImgCrop(props, ref) { var aspect = props.aspect, shape = props.shape, grid = props.grid, zoom = props.zoom, rotate = props.rotate, _props$rotateStep = props.rotateStep, rotateStep = _props$rotateStep === void 0 ? 90 : _props$rotateStep, beforeCrop = props.beforeCrop, modalTitle = props.modalTitle, modalWidth = props.modalWidth, modalOk = props.modalOk, modalCancel = props.modalCancel, modalVisible = props.modalVisible, children = props.children, onModalCancel = props.onCancel, onModalOk = props.onOk, imageSrc = props.src, serverCrop = props.serverCrop, modalProps = props.modalProps, cropContent = props.cropContent, onCropComplete = props.onCropComplete, customizePrefixCls = props.prefixCls; var _useContext = (0, _react.useContext)(_ConfigContext["default"]), getPrefixCls = _useContext.getPrefixCls; var prefixCls = getPrefixCls('image-crop', customizePrefixCls); var prefixClsMedia = "".concat(prefixCls, "-media"); var hasZoom = zoom === true; var hasRotate = rotate === true; var _useState3 = (0, _react.useState)(''), _useState4 = (0, _slicedToArray2["default"])(_useState3, 2), src = _useState4[0], setSrc = _useState4[1]; var _useState5 = (0, _react.useState)(1), _useState6 = (0, _slicedToArray2["default"])(_useState5, 2), zoomVal = _useState6[0], setZoomVal = _useState6[1]; var _useState7 = (0, _react.useState)(0), _useState8 = (0, _slicedToArray2["default"])(_useState7, 2), rotateVal = _useState8[0], setRotateVal = _useState8[1]; var beforeUploadRef = _react["default"].useRef(); // 返回上传组件的上传之前的钩子函数 var fileRef = _react["default"].useRef(); // 记录文件的参数 var resolveRef = (0, _react.useRef)(); // 返回文件上传的成功数据的方法 var rejectRef = (0, _react.useRef)(); // 返回失败数据的方法 var cropPixelsRef = _react["default"].useRef(); var imageCropCanvas = function imageCropCanvas(naturalModalImg) { var naturalWidth = naturalModalImg.naturalWidth, naturalHeight = naturalModalImg.naturalHeight; var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); if (ctx) { // create a max canvas to cover the source image after rotated var maxLen = Math.sqrt(Math.pow(naturalWidth, 2) + Math.pow(naturalHeight, 2)); canvas.width = maxLen; canvas.height = maxLen; // rotate the image if (hasRotate && rotateVal > 0 && rotateVal < 360) { var halfMax = maxLen / 2; ctx.translate(halfMax, halfMax); ctx.rotate(rotateVal * Math.PI / 180); ctx.translate(-halfMax, -halfMax); } // draw the source image in the center of the max canvas var left = (maxLen - naturalWidth) / 2; var top = (maxLen - naturalHeight) / 2; ctx.drawImage(naturalModalImg, left, top); // shrink the max canvas to the crop area size, then align two center points var maxImgData = ctx.getImageData(0, 0, maxLen, maxLen); if (cropPixelsRef && cropPixelsRef.current) { var _cropPixelsRef$curren = cropPixelsRef.current, width = _cropPixelsRef$curren.width, height = _cropPixelsRef$curren.height, x = _cropPixelsRef$curren.x, y = _cropPixelsRef$curren.y; canvas.width = width; canvas.height = height; // get the new image ctx.putImageData(maxImgData, -left - x, -top - y); return canvas; } } }; /** * Upload */ var renderUpload = (0, _react.useCallback)(function () { var upload = Array.isArray(children) ? children[0] : children; if (upload && upload.props && upload.type === _upload["default"]) { var _upload$props = upload.props, beforeUpload = _upload$props.beforeUpload, accept = _upload$props.accept, restUploadProps = (0, _objectWithoutProperties2["default"])(_upload$props, _excluded); beforeUploadRef.current = beforeUpload; return (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, upload), {}, { props: (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, restUploadProps), {}, { accept: accept || 'image/*', beforeUpload: function beforeUpload(file, fileList) { return new Promise(function (resolve, reject) { if (beforeCrop && !beforeCrop(file, fileList)) { reject(); return; } fileRef.current = file; resolveRef.current = resolve; rejectRef.current = reject; var reader = new FileReader(); if (reader) { reader.addEventListener('load', function () { if (reader.result && typeof reader.result === 'string') { setSrc(reader.result); } }); if (file instanceof Blob) { reader.readAsDataURL(file); } } }); } }) }); } if (imageSrc && typeof window !== 'undefined') { var newimage = new Image(); newimage.src = imageSrc; newimage.crossOrigin = 'anonymous'; newimage.onload = function () { var canvas = imageToCanvas(newimage); if (canvas) { if ((0, _isFunction["default"])(onModalOk) && canvas) { setSrc(canvas.toDataURL()); } } }; } }, [beforeCrop, children]); /** * EasyCrop */ var onComplete = (0, _react.useCallback)(function (croppedAreaPixels) { cropPixelsRef.current = croppedAreaPixels; if ((0, _isFunction["default"])(onCropComplete)) { var naturalModalImg = document.querySelector(".".concat(prefixClsMedia)); var canvas = serverCrop ? imageToCanvas(naturalModalImg) : imageCropCanvas(naturalModalImg); if (canvas) { canvas.toBlob(function (blob) { var area = {}; if (cropPixelsRef.current) { area = cropPixelsRef.current; } onCropComplete({ url: canvas.toDataURL(), blob: blob, area: area }); }); } } }, [rotateVal, hasRotate]); /** * Controls */ var MIN_ROTATE = 0; var MAX_ROTATE = 360; var isMinZoom = zoomVal <= MIN_ZOOM; var isMaxZoom = zoomVal >= MAX_ZOOM; var isMinRotate = rotateVal === MIN_ROTATE; var isMaxRotate = rotateVal >= MAX_ROTATE; var subZoomVal = (0, _react.useCallback)(function () { if (!isMinZoom) setZoomVal(zoomVal - ZOOM_STEP); }, [isMinZoom, zoomVal]); var addZoomVal = (0, _react.useCallback)(function () { if (!isMaxZoom) setZoomVal(zoomVal + ZOOM_STEP); }, [isMaxZoom, zoomVal]); var addRotateVal = (0, _react.useCallback)(function () { if (!isMaxRotate) { setRotateVal(rotateVal + rotateStep); } else { setRotateVal(MIN_ROTATE + rotateStep); } }, [isMaxRotate, rotateVal]); var initVal = (0, _react.useCallback)(function () { if (!isMinZoom || !isMinRotate) { setZoomVal(MIN_ZOOM); setRotateVal(MIN_ROTATE); } }, [zoomVal, rotateVal]); /** * Modal */ var closeModal = (0, _react.useCallback)(function () { setSrc(''); setZoomVal(1); setRotateVal(0); }, []); var onClose = (0, _react.useCallback)(function () { closeModal(); if ((0, _isFunction["default"])(onModalCancel)) { onModalCancel(); } }, []); var onOk = (0, _react.useCallback)( /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2() { var naturalModalImg, canvas, _fileRef$current, type, name, uid; return _regenerator["default"].wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: onClose(); naturalModalImg = document.querySelector(".".concat(prefixClsMedia)); if (naturalModalImg) { if (naturalModalImg && naturalModalImg instanceof HTMLImageElement) { canvas = serverCrop ? imageToCanvas(naturalModalImg) : imageCropCanvas(naturalModalImg); if (fileRef.current && canvas) { _fileRef$current = fileRef.current, type = _fileRef$current.type, name = _fileRef$current.name, uid = _fileRef$current.uid; canvas.toBlob( /*#__PURE__*/function () { var _ref2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(blob) { var newFile, res, passedFile, passedFileType; return _regenerator["default"].wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: newFile = blob; if (!newFile) { _context.next = 30; break; } newFile.lastModifiedDate = Date.now(); newFile.name = name; newFile.uid = uid; newFile.imageCropArea = cropPixelsRef.current; if (!(resolveRef && rejectRef && resolveRef.current && rejectRef.current)) { _context.next = 30; break; } if (!(typeof beforeUploadRef.current !== 'function')) { _context.next = 9; break; } return _context.abrupt("return", resolveRef.current(newFile)); case 9: res = beforeUploadRef.current(newFile, [newFile]); if (!(typeof res !== 'boolean' && !res)) { _context.next = 13; break; } console.error('beforeUpload must return a boolean or Promise'); return _context.abrupt("return"); case 13: if (!(res === true)) { _context.next = 15; break; } return _context.abrupt("return", resolveRef.current(newFile)); case 15: if (!(res === false)) { _context.next = 17; break; } return _context.abrupt("return", rejectRef.current('not upload')); case 17: if (!(res && typeof res.then === 'function')) { _context.next = 30; break; } _context.prev = 18; _context.next = 21; return res; case 21: passedFile = _context.sent; passedFileType = Object.prototype.toString.call(passedFile); if (passedFileType === '[object File]' || passedFileType === '[object Blob]') newFile = passedFile; resolveRef.current(newFile); _context.next = 30; break; case 27: _context.prev = 27; _context.t0 = _context["catch"](18); rejectRef.current(_context.t0); case 30: case "end": return _context.stop(); } } }, _callee, null, [[18, 27]]); })); return function (_x) { return _ref2.apply(this, arguments); }; }(), type, 0.4); } if ((0, _isFunction["default"])(onModalOk) && canvas) { canvas.toBlob(function (blob) { var area = {}; if (cropPixelsRef.current) { area = cropPixelsRef.current; } onModalOk({ url: canvas.toDataURL(), blob: blob, area: area }); }); } } } case 3: case "end": return _context2.stop(); } } }, _callee2); })), [hasRotate, onClose, rotateVal]); var RenderCrop = /*#__PURE__*/_react["default"].createElement(EasyCrop, { ref: ref, src: src, aspect: aspect, shape: shape, grid: grid, hasZoom: hasZoom, zoomVal: zoomVal, rotateVal: rotateVal, setZoomVal: setZoomVal, setRotateVal: setRotateVal, onComplete: onComplete, prefixCls: prefixCls }); var title = modalProps && modalProps.title || modalTitle; var cancelButtonProps = { funcType: 'raised' }; var okButtonProps = { funcType: 'raised', type: 'primary' }; return /*#__PURE__*/_react["default"].createElement(_LocaleReceiver["default"], { componentName: "imageCrop", defaultLocale: _default2["default"].imageCrop }, function (locale) { return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, renderUpload(), src && modalVisible && /*#__PURE__*/_react["default"].createElement(_modal["default"], (0, _extends2["default"])({ visible: modalVisible, wrapClassName: "".concat(prefixCls, "-modal"), title: title || (locale && locale.editImage ? locale.editImage : 'Edit image'), width: modalWidth, destroyOnClose: true, maskClosable: false, onCancel: onClose, onOk: onOk, cancelButtonProps: cancelButtonProps, okButtonProps: okButtonProps, okText: modalOk, cancelText: modalCancel }, modalProps), cropContent ? cropContent(RenderCrop) : RenderCrop, /*#__PURE__*/_react["default"].createElement("div", { className: "".concat(prefixCls, "-control") }, hasZoom && /*#__PURE__*/_react["default"].createElement(_ButtonGroup["default"], null, /*#__PURE__*/_react["default"].createElement(_button["default"], { funcType: "raised", icon: "zoom_in", onClick: addZoomVal, disabled: isMaxZoom }), /*#__PURE__*/_react["default"].createElement(_button["default"], { funcType: "raised", icon: "zoom_out", onClick: subZoomVal, disabled: isMinZoom })), hasRotate && /*#__PURE__*/_react["default"].createElement(_button["default"], { funcType: "raised", icon: rotateStep === 90 ? 'play_90' : 'rotate_right', onClick: addRotateVal }), hasZoom && /*#__PURE__*/_react["default"].createElement(_button["default"], { funcType: "raised", onClick: initVal }, "1:1")))); }); }); ImgCrop.displayName = 'ImgCrop'; ImgCrop.defaultProps = { shape: _enum.ShapeCroper.rect, grid: false, zoom: true, rotate: false, modalWidth: 600, modalVisible: true, serverCrop: false }; ImgCrop.AvatarUploader = _avatarUpload["default"]; var _default = ImgCrop; exports["default"] = _default; //# sourceMappingURL=index.js.map