Preview.js 8.83 KB
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
import * as React from 'react';
import Dialog from 'rc-dialog';
import RotateLeftOutlined from '@ant-design/icons/RotateLeftOutlined';
import RotateRightOutlined from '@ant-design/icons/RotateRightOutlined';
import ZoomInOutlined from '@ant-design/icons/ZoomInOutlined';
import ZoomOutOutlined from '@ant-design/icons/ZoomOutOutlined';
import CloseOutlined from '@ant-design/icons/CloseOutlined';
import LeftOutlined from '@ant-design/icons/LeftOutlined';
import RightOutlined from '@ant-design/icons/RightOutlined';
import classnames from 'classnames';
import addEventListener from "rc-util/es/Dom/addEventListener";
import { getOffset } from "rc-util/es/Dom/css";
import { warning } from "rc-util/es/warning";
import useFrameSetState from './hooks/useFrameSetState';
import usePreviewIndex from './hooks/usePreviewIndex';
import getFixScaleEleTransPosition from './getFixScaleEleTransPosition';
import { context } from './PreviewGroup';
var useState = React.useState;
var initialPosition = {
  x: 0,
  y: 0
};

var Preview = function Preview(props) {
  var prefixCls = props.prefixCls,
      src = props.src,
      alt = props.alt,
      onClose = props.onClose,
      afterClose = props.afterClose,
      visible = props.visible,
      restProps = _objectWithoutProperties(props, ["prefixCls", "src", "alt", "onClose", "afterClose", "visible"]);

  var _useState = useState(1),
      _useState2 = _slicedToArray(_useState, 2),
      scale = _useState2[0],
      setScale = _useState2[1];

  var _useState3 = useState(0),
      _useState4 = _slicedToArray(_useState3, 2),
      rotate = _useState4[0],
      setRotate = _useState4[1];

  var _useFrameSetState = useFrameSetState(initialPosition),
      _useFrameSetState2 = _slicedToArray(_useFrameSetState, 2),
      position = _useFrameSetState2[0],
      setPosition = _useFrameSetState2[1];

  var imgRef = React.useRef();
  var originPositionRef = React.useRef({
    originX: 0,
    originY: 0,
    deltaX: 0,
    deltaY: 0
  });

  var _React$useState = React.useState(false),
      _React$useState2 = _slicedToArray(_React$useState, 2),
      isMoving = _React$useState2[0],
      setMoving = _React$useState2[1];

  var _React$useContext = React.useContext(context),
      previewUrls = _React$useContext.previewUrls;

  var urls = previewUrls && previewUrls.length ? previewUrls : [src];

  var _usePreviewIndex = usePreviewIndex(src, urls),
      _usePreviewIndex2 = _slicedToArray(_usePreviewIndex, 2),
      index = _usePreviewIndex2[0],
      setIndex = _usePreviewIndex2[1];

  var onAfterClose = function onAfterClose() {
    setScale(1);
    setRotate(0);
    setPosition(initialPosition);
  };

  var onZoomIn = function onZoomIn() {
    setScale(function (value) {
      return value + 1;
    });
    setPosition(initialPosition);
  };

  var onZoomOut = function onZoomOut() {
    if (scale > 1) {
      setScale(function (value) {
        return value - 1;
      });
    }

    setPosition(initialPosition);
  };

  var onRotateRight = function onRotateRight() {
    setRotate(function (value) {
      return value + 90;
    });
  };

  var onRotateLeft = function onRotateLeft() {
    setRotate(function (value) {
      return value - 90;
    });
  };

  var onSwitchLeft = function onSwitchLeft(event) {
    event.preventDefault(); // Without this mask close will abnormal

    event.stopPropagation();

    if (index > 0) {
      onAfterClose();
      setIndex(index - 1);
    }
  };

  var onSwitchRight = function onSwitchRight(event) {
    event.preventDefault(); // Without this mask close will abnormal

    event.stopPropagation();

    if (index < urls.length - 1) {
      onAfterClose();
      setIndex(index + 1);
    }
  };

  var wrapClassName = classnames(_defineProperty({}, "".concat(prefixCls, "-moving"), isMoving));
  var toolClassName = "".concat(prefixCls, "-operations-operation");
  var iconClassName = "".concat(prefixCls, "-operations-icon");
  var tools = [{
    Icon: CloseOutlined,
    onClick: onClose,
    type: 'close'
  }, {
    Icon: ZoomInOutlined,
    onClick: onZoomIn,
    type: 'zoomIn'
  }, {
    Icon: ZoomOutOutlined,
    onClick: onZoomOut,
    type: 'zoomOut',
    disabled: scale === 1
  }, {
    Icon: RotateRightOutlined,
    onClick: onRotateRight,
    type: 'rotateRight'
  }, {
    Icon: RotateLeftOutlined,
    onClick: onRotateLeft,
    type: 'rotateLeft'
  }];

  var onMouseUp = function onMouseUp() {
    if (visible && isMoving) {
      var width = imgRef.current.offsetWidth * scale;
      var height = imgRef.current.offsetHeight * scale;

      var _getOffset = getOffset(imgRef.current),
          left = _getOffset.left,
          top = _getOffset.top;

      var isRotate = rotate % 180 !== 0;
      setMoving(false);
      var fixState = getFixScaleEleTransPosition(isRotate ? height : width, isRotate ? width : height, left, top);

      if (fixState) {
        setPosition(_objectSpread({}, fixState));
      }
    }
  };

  var onMouseDown = function onMouseDown(event) {
    event.preventDefault(); // Without this mask close will abnormal

    event.stopPropagation();
    originPositionRef.current.deltaX = event.pageX - position.x;
    originPositionRef.current.deltaY = event.pageY - position.y;
    originPositionRef.current.originX = position.x;
    originPositionRef.current.originY = position.y;
    setMoving(true);
  };

  var onMouseMove = function onMouseMove(event) {
    if (visible && isMoving) {
      setPosition({
        x: event.pageX - originPositionRef.current.deltaX,
        y: event.pageY - originPositionRef.current.deltaY
      });
    }
  };

  React.useEffect(function () {
    var onTopMouseUpListener;
    var onTopMouseMoveListener;
    var onMouseUpListener = addEventListener(window, 'mouseup', onMouseUp, false);
    var onMouseMoveListener = addEventListener(window, 'mousemove', onMouseMove, false);

    try {
      // Resolve if in iframe lost event

      /* istanbul ignore next */
      if (window.top !== window.self) {
        onTopMouseUpListener = addEventListener(window.top, 'mouseup', onMouseUp, false);
        onTopMouseMoveListener = addEventListener(window.top, 'mousemove', onMouseMove, false);
      }
    } catch (error) {
      /* istanbul ignore next */
      warning(false, "[rc-image] ".concat(error));
    }

    return function () {
      onMouseUpListener.remove();
      onMouseMoveListener.remove();
      /* istanbul ignore next */

      if (onTopMouseUpListener) onTopMouseUpListener.remove();
      /* istanbul ignore next */

      if (onTopMouseMoveListener) onTopMouseMoveListener.remove();

      if (!visible) {
        setIndex(urls.indexOf(src));
      }
    };
  }, [visible, isMoving]);
  return /*#__PURE__*/React.createElement(Dialog, Object.assign({}, restProps, {
    transitionName: "zoom",
    maskTransitionName: "fade",
    closable: false,
    keyboard: true,
    prefixCls: prefixCls,
    onClose: onClose,
    afterClose: onAfterClose,
    visible: visible,
    wrapClassName: wrapClassName
  }), /*#__PURE__*/React.createElement("ul", {
    className: "".concat(prefixCls, "-operations")
  }, tools.map(function (_ref) {
    var Icon = _ref.Icon,
        onClick = _ref.onClick,
        type = _ref.type,
        disabled = _ref.disabled;
    return /*#__PURE__*/React.createElement("li", {
      className: classnames(toolClassName, _defineProperty({}, "".concat(prefixCls, "-operations-operation-disabled"), !!disabled)),
      onClick: onClick,
      key: type
    }, /*#__PURE__*/React.createElement(Icon, {
      className: iconClassName
    }));
  })), /*#__PURE__*/React.createElement("div", {
    className: "".concat(prefixCls, "-img-wrapper"),
    style: {
      transform: "translate3d(".concat(position.x, "px, ").concat(position.y, "px, 0)")
    }
  }, /*#__PURE__*/React.createElement("img", {
    onMouseDown: onMouseDown,
    ref: imgRef,
    className: "".concat(prefixCls, "-img"),
    src: urls[index],
    alt: alt,
    style: {
      transform: "scale3d(".concat(scale, ", ").concat(scale, ", 1) rotate(").concat(rotate, "deg)")
    }
  })), urls.length > 1 ? /*#__PURE__*/React.createElement("div", {
    className: classnames("".concat(prefixCls, "-switch-left"), _defineProperty({}, "".concat(prefixCls, "-switch-left-disabled"), index <= 0)),
    onClick: onSwitchLeft
  }, /*#__PURE__*/React.createElement(LeftOutlined, null)) : null, urls.length > 1 ? /*#__PURE__*/React.createElement("div", {
    className: classnames("".concat(prefixCls, "-switch-right"), _defineProperty({}, "".concat(prefixCls, "-switch-right-disabled"), index >= urls.length - 1)),
    onClick: onSwitchRight
  }, /*#__PURE__*/React.createElement(RightOutlined, null)) : null);
};

export default Preview;