@aplus-frontend/antdv
Version:
Vue basic component library maintained based on ant-design-vue
412 lines (411 loc) • 14.4 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.previewProps = exports.default = void 0;
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
var _vue = require("vue");
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _classNames = _interopRequireDefault(require("../../_util/classNames"));
var _vcDialog = _interopRequireDefault(require("../../vc-dialog"));
var _IDialogPropTypes = require("../../vc-dialog/IDialogPropTypes");
var _addEventListener = _interopRequireDefault(require("../../vc-util/Dom/addEventListener"));
var _KeyCode = _interopRequireDefault(require("../../_util/KeyCode"));
var _warning = require("../../vc-util/warning");
var _useFrameSetState = _interopRequireDefault(require("./hooks/useFrameSetState"));
var _getFixScaleEleTransPosition = _interopRequireDefault(require("./getFixScaleEleTransPosition"));
var _PreviewGroup = require("./PreviewGroup");
const initialPosition = {
x: 0,
y: 0
};
const previewProps = exports.previewProps = (0, _extends2.default)((0, _extends2.default)({}, (0, _IDialogPropTypes.dialogPropTypes)()), {
src: String,
alt: String,
rootClassName: String,
icons: {
type: Object,
default: () => ({})
},
minScale: Number,
maxScale: Number,
imageInfo: Object
});
const Preview = (0, _vue.defineComponent)({
compatConfig: {
MODE: 3
},
name: 'Preview',
inheritAttrs: false,
props: previewProps,
emits: ['close', 'afterClose'],
slots: Object,
setup(props, _ref) {
let {
emit,
attrs,
slots
} = _ref;
const {
rotateLeft,
rotateRight,
zoomIn,
zoomOut,
close,
left,
right,
flipX,
flipY
} = (0, _vue.reactive)(props.icons);
const {
minScale = 1,
maxScale = 50,
imageInfo = {}
} = (0, _vue.reactive)(props);
const scale = (0, _vue.shallowRef)(1);
const rotate = (0, _vue.shallowRef)(0);
const flip = (0, _vue.reactive)({
x: 1,
y: 1
});
const [position, setPosition] = (0, _useFrameSetState.default)(initialPosition);
const onClose = () => emit('close');
const imgRef = (0, _vue.shallowRef)();
const originPositionRef = (0, _vue.reactive)({
originX: 0,
originY: 0,
deltaX: 0,
deltaY: 0
});
const isMoving = (0, _vue.shallowRef)(false);
const groupContext = _PreviewGroup.context.inject();
const {
previewUrls,
current,
isPreviewGroup,
setCurrent
} = groupContext;
const previewGroupCount = (0, _vue.computed)(() => previewUrls.value.size);
const previewUrlsKeys = (0, _vue.computed)(() => Array.from(previewUrls.value.keys()));
const currentPreviewIndex = (0, _vue.computed)(() => previewUrlsKeys.value.indexOf(current.value));
const combinationSrc = (0, _vue.computed)(() => {
return isPreviewGroup.value ? previewUrls.value.get(current.value) : props.src;
});
const showLeftOrRightSwitches = (0, _vue.computed)(() => isPreviewGroup.value && previewGroupCount.value > 1);
const showOperationsProgress = (0, _vue.computed)(() => isPreviewGroup.value && previewGroupCount.value >= 1);
const lastWheelZoomDirection = (0, _vue.shallowRef)({
wheelDirection: 0
});
const image = (0, _vue.computed)(() => (0, _extends2.default)({
url: combinationSrc.value,
alt: props.alt
}, imageInfo));
const onAfterClose = () => {
scale.value = 1;
rotate.value = 0;
flip.x = 1;
flip.y = 1;
setPosition(initialPosition);
emit('afterClose');
};
const onZoomIn = isWheel => {
if (!isWheel) {
scale.value++;
} else {
scale.value += 0.5;
}
setPosition(initialPosition);
};
const onZoomOut = isWheel => {
if (scale.value > 1) {
if (!isWheel) {
scale.value--;
} else {
scale.value -= 0.5;
}
}
setPosition(initialPosition);
};
const onRotateRight = () => {
rotate.value += 90;
};
const onRotateLeft = () => {
rotate.value -= 90;
};
const onFlipX = () => {
flip.x = -flip.x;
};
const onFlipY = () => {
flip.y = -flip.y;
};
const onSwitchLeft = event => {
event.preventDefault();
// Without this mask close will abnormal
event.stopPropagation();
if (currentPreviewIndex.value > 0) {
setCurrent(previewUrlsKeys.value[currentPreviewIndex.value - 1]);
}
};
const onSwitchRight = event => {
event.preventDefault();
// Without this mask close will abnormal
event.stopPropagation();
if (currentPreviewIndex.value < previewGroupCount.value - 1) {
setCurrent(previewUrlsKeys.value[currentPreviewIndex.value + 1]);
}
};
const wrapClassName = (0, _classNames.default)({
[`${props.prefixCls}-moving`]: isMoving.value
});
const toolClassName = `${props.prefixCls}-operations-operation`;
const iconClassName = `${props.prefixCls}-operations-icon`;
const tools = [{
icon: flipY,
onClick: onFlipY,
type: 'flipY'
}, {
icon: flipX,
onClick: onFlipX,
type: 'flipX'
}, {
icon: rotateLeft,
onClick: onRotateLeft,
type: 'rotateLeft'
}, {
icon: rotateRight,
onClick: onRotateRight,
type: 'rotateRight'
}, {
icon: zoomOut,
onClick: onZoomOut,
type: 'zoomOut',
disabled: (0, _vue.computed)(() => scale.value === minScale)
}, {
icon: zoomIn,
onClick: onZoomIn,
type: 'zoomIn',
disabled: (0, _vue.computed)(() => scale.value === maxScale)
}];
const onMouseUp = () => {
if (props.visible && isMoving.value) {
const width = imgRef.value.offsetWidth * scale.value;
const height = imgRef.value.offsetHeight * scale.value;
const {
left,
top
} = imgRef.value.getBoundingClientRect();
const isRotate = rotate.value % 180 !== 0;
isMoving.value = false;
const fixState = (0, _getFixScaleEleTransPosition.default)(isRotate ? height : width, isRotate ? width : height, left, top);
if (fixState) {
setPosition((0, _extends2.default)({}, fixState));
}
}
};
const onMouseDown = event => {
// Only allow main button
if (event.button !== 0) return;
event.preventDefault();
// Without this mask close will abnormal
event.stopPropagation();
originPositionRef.deltaX = event.pageX - position.x;
originPositionRef.deltaY = event.pageY - position.y;
originPositionRef.originX = position.x;
originPositionRef.originY = position.y;
isMoving.value = true;
};
const onMouseMove = event => {
if (props.visible && isMoving.value) {
setPosition({
x: event.pageX - originPositionRef.deltaX,
y: event.pageY - originPositionRef.deltaY
});
}
};
const onWheelMove = event => {
if (!props.visible) return;
event.preventDefault();
const wheelDirection = event.deltaY;
lastWheelZoomDirection.value = {
wheelDirection
};
};
const onKeyDown = event => {
if (!props.visible || !showLeftOrRightSwitches.value) return;
event.preventDefault();
if (event.keyCode === _KeyCode.default.LEFT) {
if (currentPreviewIndex.value > 0) {
setCurrent(previewUrlsKeys.value[currentPreviewIndex.value - 1]);
}
} else if (event.keyCode === _KeyCode.default.RIGHT) {
if (currentPreviewIndex.value < previewGroupCount.value - 1) {
setCurrent(previewUrlsKeys.value[currentPreviewIndex.value + 1]);
}
}
};
const onDoubleClick = () => {
if (props.visible) {
if (scale.value !== 1) {
scale.value = 1;
}
if (position.x !== initialPosition.x || position.y !== initialPosition.y) {
setPosition(initialPosition);
}
}
};
let removeListeners = () => {};
(0, _vue.onMounted)(() => {
(0, _vue.watch)([() => props.visible, isMoving, imgRef], () => {
removeListeners();
let onTopMouseUpListener;
let onTopMouseMoveListener;
const onMouseUpListener = (0, _addEventListener.default)(imgRef.value, 'mouseup', onMouseUp, false);
const onMouseMoveListener = (0, _addEventListener.default)(imgRef.value, 'mousemove', onMouseMove, false);
const onScrollWheelListener = (0, _addEventListener.default)(imgRef.value, 'wheel', onWheelMove, {
passive: false
});
const onKeyDownListener = (0, _addEventListener.default)(window, 'keydown', onKeyDown, false);
try {
// Resolve if in iframe lost event
/* istanbul ignore next */
if (window.top !== window.self) {
onTopMouseUpListener = (0, _addEventListener.default)(window.top, 'mouseup', onMouseUp, false);
onTopMouseMoveListener = (0, _addEventListener.default)(window.top, 'mousemove', onMouseMove, false);
}
} catch (error) {
/* istanbul ignore next */
(0, _warning.warning)(false, `[vc-image] ${error}`);
}
removeListeners = () => {
onMouseUpListener.remove();
onMouseMoveListener.remove();
onScrollWheelListener.remove();
onKeyDownListener.remove();
/* istanbul ignore next */
if (onTopMouseUpListener) onTopMouseUpListener.remove();
/* istanbul ignore next */
if (onTopMouseMoveListener) onTopMouseMoveListener.remove();
};
}, {
flush: 'post',
immediate: true
});
(0, _vue.watch)([lastWheelZoomDirection], () => {
const {
wheelDirection
} = lastWheelZoomDirection.value;
if (wheelDirection > 0) {
onZoomOut(true);
} else if (wheelDirection < 0) {
onZoomIn(true);
}
});
});
(0, _vue.onUnmounted)(() => {
removeListeners();
});
return () => {
var _a, _b;
const {
visible,
prefixCls,
rootClassName
} = props;
const toolsNode = tools.map(_ref2 => {
let {
icon: IconType,
onClick,
type,
disabled
} = _ref2;
return (0, _vue.createVNode)("div", {
"class": (0, _classNames.default)(toolClassName, {
[`${props.prefixCls}-operations-operation-${type}`]: true,
[`${props.prefixCls}-operations-operation-disabled`]: disabled && (disabled === null || disabled === void 0 ? void 0 : disabled.value)
}),
"onClick": onClick,
"key": type
}, [(0, _vue.cloneVNode)(IconType, {
class: iconClassName
})]);
});
const toolbarNode = (0, _vue.createVNode)("div", {
"class": `${props.prefixCls}-operations`
}, [toolsNode]);
return (0, _vue.createVNode)(_vue.Fragment, null, [(0, _vue.createVNode)(_vcDialog.default, (0, _objectSpread2.default)((0, _objectSpread2.default)({}, attrs), {}, {
"transitionName": props.transitionName,
"maskTransitionName": props.maskTransitionName,
"closable": false,
"keyboard": true,
"prefixCls": prefixCls,
"onClose": onClose,
"afterClose": onAfterClose,
"visible": visible,
"wrapClassName": wrapClassName,
"rootClassName": rootClassName,
"getContainer": props.getContainer
}), {
default: () => [(0, _vue.createVNode)("div", {
"class": `${props.prefixCls}-img-wrapper`,
"style": {
transform: `translate3d(${position.x}px, ${position.y}px, 0)`
}
}, [(0, _vue.createVNode)("img", {
"onMousedown": onMouseDown,
"onDblclick": onDoubleClick,
"ref": imgRef,
"class": `${props.prefixCls}-img`,
"src": combinationSrc.value,
"alt": props.alt,
"style": {
transform: `scale3d(${flip.x * scale.value}, ${flip.y * scale.value}, 1) rotate(${rotate.value}deg)`
}
}, null)])]
}), visible && (0, _vue.createVNode)("div", {
"class": (0, _classNames.default)(`${props.prefixCls}-operations-wrapper`, rootClassName)
}, [(0, _vue.createVNode)("button", {
"class": `${props.prefixCls}-close`,
"onClick": onClose
}, [((_a = slots.closeIcon) === null || _a === void 0 ? void 0 : _a.call(slots, {
onClose
})) || close]), showLeftOrRightSwitches.value && (0, _vue.createVNode)(_vue.Fragment, null, [(0, _vue.createVNode)("div", {
"class": (0, _classNames.default)(`${prefixCls}-switch-left`, {
[`${props.prefixCls}-switch-left-disabled`]: currentPreviewIndex.value === 0
}),
"onClick": onSwitchLeft
}, [left]), (0, _vue.createVNode)("div", {
"class": (0, _classNames.default)(`${prefixCls}-switch-right`, {
[`${props.prefixCls}-switch-right-disabled`]: currentPreviewIndex.value === previewGroupCount.value - 1
}),
"onClick": onSwitchRight
}, [right])]), (0, _vue.createVNode)("div", {
"class": [`${props.prefixCls}-footer`]
}, [showOperationsProgress.value && (0, _vue.createVNode)("div", {
"class": `${props.prefixCls}-progress`
}, [`${currentPreviewIndex.value + 1} / ${previewGroupCount.value}`]), slots.toolbarRender ? (_b = slots.toolbarRender) === null || _b === void 0 ? void 0 : _b.call(slots, (0, _extends2.default)({
originalNodes: toolsNode,
actions: {
onFlipY,
onFlipX,
onRotateLeft,
onRotateRight,
onZoomOut,
onZoomIn
},
transform: {
x: position.x,
y: position.y,
scale: scale.value,
rotate,
flip
},
image: (0, _vue.unref)(image)
}, groupContext ? {
current: currentPreviewIndex.value,
total: previewGroupCount.value
} : {})) : toolbarNode])])]);
};
}
});
var _default = exports.default = Preview;
;