"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
