acud
Version:
acg react 组件库
340 lines • 14.4 kB
JavaScript
import _typeof from "@babel/runtime/helpers/esm/typeof";
import _extends from "@babel/runtime/helpers/esm/extends";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _regeneratorRuntime from "@babel/runtime/regenerator";
var __awaiter = this && this.__awaiter || function (thisArg, _arguments, P, generator) {
function adopt(value) {
return value instanceof P ? value : new P(function (resolve) {
resolve(value);
});
}
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
}
function rejected(value) {
try {
step(generator["throw"](value));
} catch (e) {
reject(e);
}
}
function step(result) {
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
}
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __rest = this && this.__rest || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
}
return t;
};
/**
* @file img crop
* @author wangpantuo
*/
import React, { forwardRef, useCallback, useMemo, useRef, useState } from 'react';
import LocaleReceiver from '../locale-provider/LocaleReceiver';
import Modal from '../modal';
import Upload from '../upload';
import EasyCrop from './EasyCrop';
import { ConfigContext } from '../config-provider';
import { INIT_ROTATE, INIT_ZOOM } from './constants';
var ImgCrop = /*#__PURE__*/forwardRef(function (props, cropperRef) {
var _props$aspect = props.aspect,
aspect = _props$aspect === void 0 ? 1 : _props$aspect,
_props$shape = props.shape,
shape = _props$shape === void 0 ? 'rect' : _props$shape,
_props$grid = props.grid,
grid = _props$grid === void 0 ? false : _props$grid,
_props$quality = props.quality,
quality = _props$quality === void 0 ? 0.4 : _props$quality,
_props$fillColor = props.fillColor,
fillColor = _props$fillColor === void 0 ? 'white' : _props$fillColor,
customPrefixCls = props.prefixCls,
_props$zoom = props.zoom,
zoom = _props$zoom === void 0 ? true : _props$zoom,
_props$rotate = props.rotate,
rotate = _props$rotate === void 0 ? false : _props$rotate,
_props$minZoom = props.minZoom,
minZoom = _props$minZoom === void 0 ? 1 : _props$minZoom,
_props$maxZoom = props.maxZoom,
maxZoom = _props$maxZoom === void 0 ? 3 : _props$maxZoom,
modalTitle = props.modalTitle,
modalWidth = props.modalWidth,
modalOk = props.modalOk,
modalCancel = props.modalCancel,
modalMaskTransitionName = props.modalMaskTransitionName,
modalTransitionName = props.modalTransitionName,
modalClassName = props.modalClassName,
onModalOk = props.onModalOk,
onModalCancel = props.onModalCancel,
beforeCrop = props.beforeCrop,
onUploadFail = props.onUploadFail,
cropperProps = props.cropperProps,
children = props.children;
var _React$useContext = React.useContext(ConfigContext),
getPrefixCls = _React$useContext.getPrefixCls;
var prefixCls = getPrefixCls('imgcrop', customPrefixCls);
var cb = useRef({});
cb.current.onModalOk = onModalOk;
cb.current.onModalCancel = onModalCancel;
cb.current.beforeCrop = beforeCrop;
cb.current.onUploadFail = onUploadFail;
/**
* Upload
*/
var _useState = useState(''),
_useState2 = _slicedToArray(_useState, 2),
image = _useState2[0],
setImage = _useState2[1];
var fileRef = useRef({});
var beforeUploadRef = useRef();
var resolveRef = useRef(function () {});
var rejectRef = useRef(function () {});
var uploadComponent = useMemo(function () {
var upload = Array.isArray(children) ? children[0] : children;
var _a = upload.props,
beforeUpload = _a.beforeUpload,
accept = _a.accept,
restUploadProps = __rest(_a, ["beforeUpload", "accept"]);
beforeUploadRef.current = beforeUpload;
return _extends(_extends({}, upload), {
props: _extends(_extends({}, restUploadProps), {
accept: accept || 'image/*',
beforeUpload: function beforeUpload(file, fileList) {
return new Promise(function (resolve, reject) {
return __awaiter(void 0, void 0, void 0, /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
var shouldCrop, reader;
return _regeneratorRuntime.wrap(function (_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
if (!cb.current.beforeCrop) {
_context.next = 2;
break;
}
_context.next = 1;
return cb.current.beforeCrop(file, fileList);
case 1:
shouldCrop = _context.sent;
if (shouldCrop) {
_context.next = 2;
break;
}
return _context.abrupt("return", reject());
case 2:
fileRef.current = file;
resolveRef.current = function (newFile) {
var _a, _b;
(_b = (_a = cb.current).onModalOk) === null || _b === void 0 ? void 0 : _b.call(_a, newFile);
resolve(newFile);
};
rejectRef.current = function (uploadErr) {
var _a, _b;
(_b = (_a = cb.current).onUploadFail) === null || _b === void 0 ? void 0 : _b.call(_a, uploadErr);
reject();
};
reader = new FileReader();
reader.addEventListener('load', function () {
if (typeof reader.result === 'string') {
setImage(reader.result);
}
});
reader.readAsDataURL(file);
case 3:
case "end":
return _context.stop();
}
}, _callee);
}));
});
}
})
});
}, [children]);
/**
* Crop
*/
var easyCropRef = useRef({});
/**
* Modal
*/
var modalProps = useMemo(function () {
var obj = {
width: modalWidth,
okText: modalOk,
cancelText: modalCancel,
maskTransitionName: modalMaskTransitionName,
transitionName: modalTransitionName
};
Object.keys(obj).forEach(function (prop) {
var key = prop;
if (obj[key] === undefined) {
delete obj[key];
}
});
return obj;
}, [modalCancel, modalMaskTransitionName, modalOk, modalTransitionName, modalWidth]);
var onClose = function onClose() {
setImage('');
easyCropRef.current.setZoomVal(INIT_ZOOM);
easyCropRef.current.setRotateVal(INIT_ROTATE);
};
var onCancel = useCallback(function () {
var _a, _b;
(_b = (_a = cb.current).onModalCancel) === null || _b === void 0 ? void 0 : _b.call(_a);
onClose();
}, []);
var onOk = useCallback(function (event) {
return __awaiter(void 0, void 0, void 0, /*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
var _a, canvas, ctx, target, context, imgSource, _easyCropRef$current$, cropWidth, cropHeight, cropX, cropY, imgWidth, imgHeight, angle, sine, cosine, squareWidth, squareHeight, squareHalfWidth, squareHalfHeight, imgX, imgY, imgData, _fileRef$current, type, name, uid;
return _regeneratorRuntime.wrap(function (_context3) {
while (1) switch (_context3.prev = _context3.next) {
case 0:
onClose();
canvas = document.createElement('canvas');
ctx = canvas.getContext('2d');
target = event.target;
context = ((_a = target === null || target === void 0 ? void 0 : target.getRootNode) === null || _a === void 0 ? void 0 : _a.call(target)) || document;
imgSource = context.querySelector(".".concat(prefixCls, "-media"));
_easyCropRef$current$ = easyCropRef.current.cropPixelsRef.current, cropWidth = _easyCropRef$current$.width, cropHeight = _easyCropRef$current$.height, cropX = _easyCropRef$current$.x, cropY = _easyCropRef$current$.y;
if (rotate && easyCropRef.current.rotateVal !== INIT_ROTATE) {
imgWidth = imgSource.naturalWidth, imgHeight = imgSource.naturalHeight;
angle = easyCropRef.current.rotateVal * (Math.PI / 180); // get container for rotated image
sine = Math.abs(Math.sin(angle));
cosine = Math.abs(Math.cos(angle));
squareWidth = imgWidth * cosine + imgHeight * sine;
squareHeight = imgHeight * cosine + imgWidth * sine;
canvas.width = squareWidth;
canvas.height = squareHeight;
ctx.fillStyle = fillColor;
ctx.fillRect(0, 0, squareWidth, squareHeight);
// rotate container
squareHalfWidth = squareWidth / 2;
squareHalfHeight = squareHeight / 2;
ctx.translate(squareHalfWidth, squareHalfHeight);
ctx.rotate(angle);
ctx.translate(-squareHalfWidth, -squareHalfHeight);
// draw rotated image
imgX = (squareWidth - imgWidth) / 2;
imgY = (squareHeight - imgHeight) / 2;
ctx.drawImage(imgSource, 0, 0, imgWidth, imgHeight, imgX, imgY, imgWidth, imgHeight);
// crop rotated image
imgData = ctx.getImageData(0, 0, squareWidth, squareHeight);
canvas.width = cropWidth;
canvas.height = cropHeight;
ctx.putImageData(imgData, -cropX, -cropY);
} else {
canvas.width = cropWidth;
canvas.height = cropHeight;
ctx.fillStyle = fillColor;
ctx.fillRect(0, 0, cropWidth, cropHeight);
ctx.drawImage(imgSource, cropX, cropY, cropWidth, cropHeight, 0, 0, cropWidth, cropHeight);
}
// get the new image
_fileRef$current = fileRef.current, type = _fileRef$current.type, name = _fileRef$current.name, uid = _fileRef$current.uid;
canvas.toBlob(function (blob) {
return __awaiter(void 0, void 0, void 0, /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
var newFile, rcFile, result;
return _regeneratorRuntime.wrap(function (_context2) {
while (1) switch (_context2.prev = _context2.next) {
case 0:
newFile = _extends(new File([blob], name, {
type: type
}), {
uid: uid
});
if (beforeUploadRef.current) {
_context2.next = 1;
break;
}
return _context2.abrupt("return", resolveRef.current(newFile));
case 1:
rcFile = newFile;
_context2.next = 2;
return beforeUploadRef.current(rcFile, [rcFile]);
case 2:
result = _context2.sent;
if (!(result === true)) {
_context2.next = 3;
break;
}
return _context2.abrupt("return", resolveRef.current(newFile));
case 3:
if (!(result === false)) {
_context2.next = 4;
break;
}
return _context2.abrupt("return", rejectRef.current(new Error('beforeUpload return false')));
case 4:
delete newFile[Upload.LIST_IGNORE];
if (!(result === Upload.LIST_IGNORE)) {
_context2.next = 5;
break;
}
Object.defineProperty(newFile, Upload.LIST_IGNORE, {
value: true,
configurable: true
});
return _context2.abrupt("return", rejectRef.current(new Error('beforeUpload return LIST_IGNORE')));
case 5:
if (!(_typeof(result) === 'object' && result !== null)) {
_context2.next = 6;
break;
}
return _context2.abrupt("return", resolveRef.current(result));
case 6:
case "end":
return _context2.stop();
}
}, _callee2);
}));
}, type, quality);
case 1:
case "end":
return _context3.stop();
}
}, _callee3);
}));
}, [fillColor, quality, rotate]);
var getComponent = function getComponent(titleOfModal) {
return /*#__PURE__*/React.createElement(React.Fragment, null, uploadComponent, image && /*#__PURE__*/React.createElement(Modal, _extends({
visible: true,
className: "".concat(prefixCls, "-modal ").concat(modalClassName || ''),
title: titleOfModal,
onOk: onOk,
onCancel: onCancel,
maskClosable: false,
destroyOnClose: true
}, modalProps), /*#__PURE__*/React.createElement(EasyCrop, {
ref: easyCropRef,
cropperRef: cropperRef,
image: image,
aspect: aspect,
shape: shape,
grid: grid,
zoom: zoom,
rotate: rotate,
minZoom: minZoom,
maxZoom: maxZoom,
cropperProps: cropperProps
})));
};
if (modalTitle) {
return getComponent(modalTitle);
}
return /*#__PURE__*/React.createElement(LocaleReceiver, {
componentName: "ImgCrop"
}, function (locale) {
return getComponent(locale.modalTitle);
});
});
export default ImgCrop;