UNPKG

choerodon-ui

Version:

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

637 lines (579 loc) 19.5 kB
import _objectSpread from "@babel/runtime/helpers/objectSpread2"; import _extends from "@babel/runtime/helpers/extends"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _inherits from "@babel/runtime/helpers/inherits"; import _createSuper from "@babel/runtime/helpers/createSuper"; /** * 裁剪头像上传 */ import React, { Component } from 'react'; import axios from 'axios'; import isString from 'lodash/isString'; import Cropper from 'react-easy-crop'; import Button from '../button'; import Icon from '../icon'; import Modal from '../modal'; import message from '../message'; import Upload from '../upload'; import LocaleReceiver from '../locale-provider/LocaleReceiver'; import defaultLocale from '../locale-provider/default'; import ConfigContext from '../config-provider/ConfigContext'; var Dragger = Upload.Dragger; var round = Math.round; var ButtonGroup = Button.Group; var maxZoomVal = 3; var zoomStep = 0.5; function rotateFlag(rotate) { return rotate / 90 % 2 !== 0; } var Avatarlocale = defaultLocale.imageCrop; var AvatarUploader = /*#__PURE__*/function (_Component) { _inherits(AvatarUploader, _Component); var _super = _createSuper(AvatarUploader); function AvatarUploader(props, context) { var _this; _classCallCheck(this, AvatarUploader); _this = _super.call(this, props, context); _this.zoomImage = function (type) { var zoom = _this.state.zoom; var _this$state = _this.state, _this$state$imageStyl = _this$state.imageStyle, width = _this$state$imageStyl.width, height = _this$state$imageStyl.height, cropSize = _this$state.cropSize; var minZoomVal = cropSize / Math.min(width, height); switch (type) { case 'add': { zoom = zoom + zoomStep >= maxZoomVal ? maxZoomVal : zoom + zoomStep; _this.setState({ zoom: zoom }); break; } case 'sub': { zoom = zoom - zoomStep <= minZoomVal ? minZoomVal : zoom - zoomStep; _this.setState({ zoom: zoom }); break; } case 'init': { var x = (width - cropSize) / 2 / width; var y = (height - cropSize) / 2 / width; _this.setState({ zoom: 1, rotate: 0, crop: { x: x, y: y } }); } break; default: break; } }; _this.handleOk = function () { var _this$state2 = _this.state, x = _this$state2.x, y = _this$state2.y, size = _this$state2.size, rotate = _this$state2.rotate, file = _this$state2.file, _this$state2$imageSty = _this$state2.imageStyle, width = _this$state2$imageSty.width, height = _this$state2$imageSty.height, naturalWidth = _this$state2.img.naturalWidth; var _this$props = _this.props, uploadUrl = _this$props.uploadUrl, uploadFaild = _this$props.uploadFaild, uploadError = _this$props.uploadError, handleUpload = _this$props.handleUpload, axiosConfig = _this$props.axiosConfig; var flag = rotateFlag(rotate); var scale = naturalWidth / width; var startX = flag ? x - (width - height) / 2 : x; var startY = flag ? y + (width - height) / 2 : y; var QsData = { rotate: rotate, startX: round(startX * scale), startY: round(startY * scale), endX: round(size * scale), endY: round(size * scale) }; var qs = JSON.stringify(QsData); var data = new FormData(); data.append('file', file); _this.setState({ submitting: true }); if (uploadUrl) { var config; if (axiosConfig) { config = axiosConfig; } axios.post("".concat(uploadUrl, "?").concat(qs), data, config).then(function (res) { if (res.success) { _this.uploadOk(res); } else { message.error(Avatarlocale.avatarUploadError); _this.setState({ submitting: false }); if (uploadFaild) { uploadFaild(); } } })["catch"](function (error) { message.error("".concat(Avatarlocale.avatarServerError).concat(error)); _this.setState({ submitting: false }); if (uploadError) { uploadError(error); } }); } if (handleUpload) { QsData.file = file; handleUpload(QsData); } }; _this.handleCancel = function () { _this.close(); }; var rectSize = props.rectSize; _this.state = { submitting: false, img: null, file: '', imageStyle: { width: 0, height: 0 }, crop: { x: 0, y: 0 }, rotate: 0, zoom: 1, cropSize: rectSize }; return _this; } _createClass(AvatarUploader, [{ key: "close", value: function close() { var onClose = this.props.onClose; this.setState({ img: null }); if (onClose) { onClose(false); } } }, { key: "uploadOk", value: function uploadOk(res) { var onUploadOk = this.props.onUploadOk; this.setState({ img: null, submitting: false }, function () { if (onUploadOk) { onUploadOk(res); } }); } }, { key: "initImageSize", value: function initImageSize(img) { var rotate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var _this$props2 = this.props, editorWidth = _this$props2.editorWidth, editorHeight = _this$props2.editorHeight, rectSize = _this$props2.rectSize; var naturalWidth = img.naturalWidth, naturalHeight = img.naturalHeight; var flag = rotateFlag(rotate); var width = flag ? naturalHeight : naturalWidth; var height = flag ? naturalWidth : naturalHeight; if (width < rectSize || height < rectSize) { if (width > height) { width = width / height * rectSize; height = rectSize; } else { height = height / width * rectSize; width = rectSize; } } else if (width > editorWidth || height > editorHeight) { if (width / editorWidth > height / editorHeight) { height = height / width * editorWidth; width = editorWidth; } else { width = width / height * editorHeight; height = editorHeight; } } if (flag) { var tmp = width; width = height; height = tmp; } var size = Math.min(rectSize, width, height); this.setState({ img: img, imageStyle: { width: width, height: height, top: (editorHeight - height) / 2, left: (editorWidth - width) / 2, transform: "rotate(".concat(rotate, "deg)") }, size: size, cropSize: size, x: (width - size) / 2, y: (height - size) / 2, rotate: rotate }); } }, { key: "onComplete", value: function onComplete(imgState) { var _this$state3 = this.state, zoom = _this$state3.zoom, _this$state3$imageSty = _this$state3.imageStyle, width = _this$state3$imageSty.width, height = _this$state3$imageSty.height, cropSize = _this$state3.cropSize; var x = imgState.x, y = imgState.y; x = Math.ceil(x * width / 100); y = Math.ceil(y * height / 100); var imageState = { x: x, y: y, size: cropSize / zoom }; var cropComplete = this.props.cropComplete; this.setState(imageState); if (cropComplete) { cropComplete(imageState); } } }, { key: "loadImage", value: function loadImage(src) { var _this2 = this; if (typeof window !== 'undefined') { var img = new Image(); img.src = src; img.onload = function () { _this2.initImageSize(img); }; } } }, { key: "getPreviewProps", value: function getPreviewProps(previewSize) { var _this$state4 = this.state, size = _this$state4.size, x = _this$state4.x, y = _this$state4.y, src = _this$state4.img.src, rotate = _this$state4.rotate, _this$state4$imageSty = _this$state4.imageStyle, width = _this$state4$imageSty.width, height = _this$state4$imageSty.height; var previewScale = previewSize / size; var radius = rotate % 360 / 90; var px = -x; var py = -y; if (radius < 0) radius += 4; if (radius === 1) { py = x + (height - width) / 2 - height + size; px = (height - width) / 2 - y; } else if (radius === 2) { px = x - width + size; py = y - height + size; } else if (radius === 3) { px = y + (width - height) / 2 - width + size; py = (width - height) / 2 - x; } return { style: { width: previewSize, height: previewSize, backgroundImage: "url('".concat(src, "')"), backgroundSize: "".concat(width * previewScale, "px ").concat(height * previewScale, "px"), backgroundPosition: "".concat(px * previewScale, "px ").concat(py * previewScale, "px"), transform: "rotate(".concat(rotate, "deg)") } }; } }, { key: "renderPreviewItem", value: function renderPreviewItem(previewSizeList) { var _this3 = this; var customizePrefixCls = this.props.prefixCls; var getPrefixCls = this.context.getPrefixCls; var prefixCls = getPrefixCls('avatar-crop-edit', customizePrefixCls); return previewSizeList.map(function (itemSize) { return /*#__PURE__*/React.createElement("div", { key: itemSize, className: "".concat(prefixCls, "-preview-item") }, /*#__PURE__*/React.createElement("i", _extends({}, _this3.getPreviewProps(itemSize))), /*#__PURE__*/React.createElement("p", null, "".concat(itemSize, "\uFF0A").concat(itemSize))); }); } }, { key: "renderEditor", value: function renderEditor(props) { var _this4 = this; var _this$state5 = this.state, img = _this$state5.img, rotate = _this$state5.rotate, zoom = _this$state5.zoom, crop = _this$state5.crop, _this$state5$imageSty = _this$state5.imageStyle, width = _this$state5$imageSty.width, height = _this$state5$imageSty.height, cropSize = _this$state5.cropSize; var _this$props3 = this.props, customizePrefixCls = _this$props3.prefixCls, previewList = _this$props3.previewList, editorWidth = _this$props3.editorWidth, editorHeight = _this$props3.editorHeight, previewTitle = _this$props3.previewTitle, reloadTitle = _this$props3.reloadTitle; var getPrefixCls = this.context.getPrefixCls; var src = img.src; var style = { width: editorWidth, height: editorHeight, position: 'relative' }; var minZoomVal = cropSize / Math.min(width, height); var isMinZoom = zoom === minZoomVal; var isMaxZoom = zoom === maxZoomVal; var prefixCls = getPrefixCls('avatar-crop-edit', customizePrefixCls); var previewTitleFlag = isString(previewTitle) || /*#__PURE__*/React.isValidElement(previewTitle); var renderPreviewTitle = function renderPreviewTitle() { if (!previewTitleFlag || !previewTitle) return null; if (isString(previewTitle)) { return /*#__PURE__*/React.createElement("h5", { className: "".concat(prefixCls, "-preview-title") }, /*#__PURE__*/React.createElement("span", null, previewTitle)); } return previewTitle; }; return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-wraper") }, /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-edit"), style: style }, /*#__PURE__*/React.createElement(Cropper, { image: src, crop: crop, showGrid: false, cropSize: { width: cropSize, height: cropSize }, zoom: zoom, minZoom: minZoomVal, rotation: rotate, aspect: 1 / 1, onCropChange: function onCropChange(crop) { return _this4.setState({ crop: crop }); }, onCropComplete: function onCropComplete(_ref) { var x = _ref.x, y = _ref.y; return _this4.onComplete({ x: x, y: y, cropSize: cropSize }); }, onZoomChange: function onZoomChange(zoom) { _this4.setState({ zoom: zoom }); } })), /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-preview") }, renderPreviewTitle(), this.renderPreviewItem(previewList))), /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-button"), style: { width: editorWidth } }, /*#__PURE__*/React.createElement(ButtonGroup, null, /*#__PURE__*/React.createElement(Button, { funcType: "raised", icon: "zoom_in", disabled: isMaxZoom, onClick: function onClick() { return _this4.zoomImage('add'); } }), /*#__PURE__*/React.createElement(Button, { funcType: "raised", icon: "zoom_out", disabled: isMinZoom, onClick: function onClick() { return _this4.zoomImage('sub'); } })), /*#__PURE__*/React.createElement(Button, { funcType: "raised", icon: "play_90", onClick: function onClick() { return _this4.setState({ rotate: rotate + 90 >= 360 ? 0 : rotate + 90 }); } }), /*#__PURE__*/React.createElement(Button, { funcType: "raised", onClick: function onClick() { return _this4.zoomImage('init'); } }, "1:1"), /*#__PURE__*/React.createElement(Upload, _extends({}, props), /*#__PURE__*/React.createElement(Button, { funcType: "raised", icon: "file_upload" }, /*#__PURE__*/React.createElement("span", null, reloadTitle || Avatarlocale.reUpload))))); } }, { key: "getUploadProps", value: function getUploadProps() { var _this5 = this; var _this$props4 = this.props, _this$props4$limit = _this$props4.limit, limitSize = _this$props4$limit.size, type = _this$props4$limit.type, uploadProps = _this$props4.uploadProps; var typeLimit = type.split(',').map(function (item) { return "image/".concat(item); }).join(','); return _objectSpread(_objectSpread({ multiple: false, name: 'file', accept: typeLimit, headers: { Authorization: "bearer" }, showUploadList: false }, uploadProps), {}, { beforeUpload: function beforeUpload(file) { var size = file.size; if (size > limitSize * 1024) { message.warning(Avatarlocale.imageTooLarge); return false; } _this5.setState({ file: file }); var windowURL = window.URL || window.webkitURL; if (windowURL && windowURL.createObjectURL) { _this5.loadImage(windowURL.createObjectURL(file)); return false; } return false; }, onChange: function onChange(_ref2) { var file = _ref2.file; var status = file.status, response = file.response; if (status === 'done') { _this5.loadImage(response); } else if (status === 'error') { message.error(Avatarlocale.imageUploadError); } } }); } }, { key: "renderContainer", value: function renderContainer() { var _this$props5 = this.props, customizePrefixCls = _this$props5.prefixCls, _this$props5$limit = _this$props5.limit, limitSize = _this$props5$limit.size, type = _this$props5$limit.type; var img = this.state.img; var getPrefixCls = this.context.getPrefixCls; var prefixCls = getPrefixCls('avatar-crop', customizePrefixCls); var props = this.getUploadProps(); return img ? this.renderEditor(props) : /*#__PURE__*/React.createElement(Dragger, _extends({ className: "".concat(prefixCls, "-dragger") }, props), /*#__PURE__*/React.createElement(Icon, { type: "inbox" }), /*#__PURE__*/React.createElement("h3", { className: "".concat(prefixCls, "-dragger-text") }, /*#__PURE__*/React.createElement("span", null, Avatarlocale.imageDragHere)), /*#__PURE__*/React.createElement("h4", { className: "".concat(prefixCls, "-dragger-hint") }, /*#__PURE__*/React.createElement("span", null, "".concat(Avatarlocale.pleaseUpload).concat(limitSize / 1024, "M,").concat(Avatarlocale.uploadType).concat(type).concat(Avatarlocale.picture)))); } }, { key: "render", value: function render() { var _this6 = this; var _this$props6 = this.props, visible = _this$props6.visible, modalProps = _this$props6.modalProps, title = _this$props6.title; var _this$state6 = this.state, img = _this$state6.img, submitting = _this$state6.submitting; var cancelButtonProps = { disabled: submitting, funcType: 'raised' }; var okButtonProps = { funcType: 'raised', type: 'primary', disabled: !img, loading: submitting }; return /*#__PURE__*/React.createElement(LocaleReceiver, { componentName: "imageCrop", defaultLocale: defaultLocale.imageCrop }, function (locale) { Avatarlocale = locale || defaultLocale.imageCrop; return /*#__PURE__*/React.createElement(Modal, _extends({ title: title || /*#__PURE__*/React.createElement("span", null, Avatarlocale.changeAvatar), className: "avatar-modal", visible: visible, width: 600, closable: true, maskClosable: false, onOk: _this6.handleOk, onCancel: _this6.handleCancel, okButtonProps: okButtonProps, cancelButtonProps: cancelButtonProps }, modalProps), _this6.renderContainer()); }); } }], [{ key: "contextType", get: function get() { return ConfigContext; } }]); return AvatarUploader; }(Component); export { AvatarUploader as default }; AvatarUploader.defaultProps = { limit: { type: 'jpeg,png,jpg', size: 1024 }, previewList: [80, 48, 34], editorWidth: 380, editorHeight: 380, rectSize: 280 }; //# sourceMappingURL=avatarUpload.js.map