@gx-design-vue/image 0.2.0-alpha.1 → 0.2.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Image.d.ts +6 -0
- package/dist/Image.js +322 -0
- package/dist/ImagePreview.d.ts +6 -0
- package/dist/ImagePreview.js +593 -0
- package/dist/g-image.esm.js +1577 -0
- package/dist/g-image.js +1 -0
- package/dist/hooks/useImageBoundary.d.ts +15 -0
- package/dist/hooks/useImageBoundary.js +24 -0
- package/dist/hooks/useImagePreview.d.ts +23 -0
- package/dist/hooks/useImagePreview.js +54 -0
- package/dist/hooks/useImageTransform.d.ts +23 -0
- package/dist/hooks/useImageTransform.js +92 -0
- package/dist/hooks/useMouseEvent.d.ts +22 -0
- package/dist/hooks/useMouseEvent.js +71 -0
- package/dist/hooks/useTouchEvent.d.ts +23 -0
- package/dist/{ImagePreview/hooks → hooks}/useTouchEvent.js +31 -32
- package/dist/index.d.ts +4 -5
- package/dist/index.js +3 -6
- package/dist/interface.d.ts +169 -0
- package/dist/interface.js +1 -0
- package/dist/style/index.d.ts +7 -0
- package/dist/{style.js → style/index.js} +19 -26
- package/dist/style/preview.d.ts +14 -0
- package/dist/style/preview.js +182 -0
- package/dist/theme/augment.d.ts +10 -0
- package/dist/theme/augment.js +1 -0
- package/dist/theme/interface/components.d.ts +10 -0
- package/dist/theme/interface/components.js +1 -0
- package/package.json +8 -7
- package/dist/GImage.d.ts +0 -162
- package/dist/GImage.js +0 -221
- package/dist/ImagePreview/Operations.d.ts +0 -83
- package/dist/ImagePreview/Operations.js +0 -71
- package/dist/ImagePreview/hooks/getFixScaleEleTransPosition.d.ts +0 -19
- package/dist/ImagePreview/hooks/getFixScaleEleTransPosition.js +0 -40
- package/dist/ImagePreview/hooks/useImageTransform.d.ts +0 -39
- package/dist/ImagePreview/hooks/useImageTransform.js +0 -105
- package/dist/ImagePreview/hooks/useMouseEvent.d.ts +0 -14
- package/dist/ImagePreview/hooks/useMouseEvent.js +0 -100
- package/dist/ImagePreview/hooks/useTouchEvent.d.ts +0 -12
- package/dist/ImagePreview/index.d.ts +0 -162
- package/dist/ImagePreview/index.js +0 -303
- package/dist/ImagePreview/props.d.ts +0 -88
- package/dist/ImagePreview/props.js +0 -53
- package/dist/ImagePreview/style.d.ts +0 -30
- package/dist/ImagePreview/style.js +0 -286
- package/dist/ImagePreview/typings.d.ts +0 -19
- package/dist/ImagePreview/typings.js +0 -1
- package/dist/ImagePreview/utils/KeyCode.d.ts +0 -438
- package/dist/ImagePreview/utils/KeyCode.js +0 -173
- package/dist/ImagePreview/utils/addEventListener.d.ts +0 -6
- package/dist/ImagePreview/utils/addEventListener.js +0 -22
- package/dist/ImagePreview/utils/util.d.ts +0 -7
- package/dist/ImagePreview/utils/util.js +0 -8
- package/dist/hooks/useFrameSetState.d.ts +0 -5
- package/dist/hooks/useFrameSetState.js +0 -33
- package/dist/image.esm.js +0 -2374
- package/dist/image.js +0 -1
- package/dist/props.d.ts +0 -84
- package/dist/props.js +0 -66
- package/dist/slots.d.ts +0 -6
- package/dist/slots.js +0 -21
- package/dist/style.d.ts +0 -9
- package/dist/typings.d.ts +0 -6
- package/dist/typings.js +0 -1
- package/dist/utils/aria.d.ts +0 -15
- package/dist/utils/aria.js +0 -16
- package/dist/utils/util.d.ts +0 -4
- package/dist/utils/util.js +0 -8
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import addEventListenerWrap from "../utils/addEventListener.js";
|
|
2
|
-
import { BASE_SCALE_RATIO, WHEEL_MAX_SCALE_RATIO } from "../utils/util.js";
|
|
3
|
-
import getFixScaleEleTransPosition from "./getFixScaleEleTransPosition.js";
|
|
4
|
-
import { ref } from "vue";
|
|
5
|
-
import { useEffect, useState } from "@gx-design-vue/pro-hooks";
|
|
6
|
-
|
|
7
|
-
//#region src/ImagePreview/hooks/useMouseEvent.ts
|
|
8
|
-
function useMouseEvent(imgRef, movable, visible, scaleStep, transform, updateTransform, dispatchZoomChange) {
|
|
9
|
-
const [isMoving, setMoving] = useState(false);
|
|
10
|
-
const startPositionInfo = ref({
|
|
11
|
-
diffX: 0,
|
|
12
|
-
diffY: 0,
|
|
13
|
-
transformX: 0,
|
|
14
|
-
transformY: 0
|
|
15
|
-
});
|
|
16
|
-
const onMouseDown = (event) => {
|
|
17
|
-
if (!movable || event.button !== 0) return;
|
|
18
|
-
event.preventDefault();
|
|
19
|
-
event.stopPropagation();
|
|
20
|
-
startPositionInfo.value = {
|
|
21
|
-
diffX: event.pageX - transform.value.x,
|
|
22
|
-
diffY: event.pageY - transform.value.y,
|
|
23
|
-
transformX: transform.value.x,
|
|
24
|
-
transformY: transform.value.y
|
|
25
|
-
};
|
|
26
|
-
setMoving(true);
|
|
27
|
-
};
|
|
28
|
-
const onMouseMove = (event) => {
|
|
29
|
-
if (visible && isMoving.value) updateTransform({
|
|
30
|
-
x: event.pageX - startPositionInfo.value.diffX,
|
|
31
|
-
y: event.pageY - startPositionInfo.value.diffY
|
|
32
|
-
}, "move");
|
|
33
|
-
};
|
|
34
|
-
const onMouseUp = () => {
|
|
35
|
-
if (visible && isMoving.value) {
|
|
36
|
-
setMoving(false);
|
|
37
|
-
/** No need to restore the position when the picture is not moved, So as not to interfere with the click */
|
|
38
|
-
const { transformX, transformY } = startPositionInfo.value;
|
|
39
|
-
if (!(transform.value.x !== transformX && transform.value.y !== transformY)) return;
|
|
40
|
-
const width = imgRef.value.offsetWidth * transform.value.scale;
|
|
41
|
-
const height = imgRef.value.offsetHeight * transform.value.scale;
|
|
42
|
-
const { left, top } = imgRef.value.getBoundingClientRect();
|
|
43
|
-
const isRotate = transform.value.rotate % 180 !== 0;
|
|
44
|
-
const fixState = getFixScaleEleTransPosition(isRotate ? height : width, isRotate ? width : height, left, top);
|
|
45
|
-
if (fixState) updateTransform({ ...fixState }, "dragRebound");
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
const onWheel = (event) => {
|
|
49
|
-
if (!visible || event.deltaY === 0) return;
|
|
50
|
-
const scaleRatio = Math.abs(event.deltaY / 100);
|
|
51
|
-
let ratio = BASE_SCALE_RATIO + Math.min(scaleRatio, WHEEL_MAX_SCALE_RATIO) * scaleStep.value;
|
|
52
|
-
if (event.deltaY > 0) ratio = BASE_SCALE_RATIO / ratio;
|
|
53
|
-
dispatchZoomChange(ratio, "wheel", event.clientX, event.clientY);
|
|
54
|
-
};
|
|
55
|
-
useEffect(() => {
|
|
56
|
-
let onTopMouseUpListener;
|
|
57
|
-
let onTopMouseMoveListener;
|
|
58
|
-
let onMouseUpListener;
|
|
59
|
-
let onMouseMoveListener;
|
|
60
|
-
if (movable) {
|
|
61
|
-
onMouseUpListener = addEventListenerWrap(window, "mouseup", onMouseUp, false);
|
|
62
|
-
onMouseMoveListener = addEventListenerWrap(window, "mousemove", onMouseMove, false);
|
|
63
|
-
try {
|
|
64
|
-
/* istanbul ignore next */
|
|
65
|
-
if (window.top !== window.self) {
|
|
66
|
-
onTopMouseUpListener = addEventListenerWrap(window.top, "mouseup", onMouseUp, false);
|
|
67
|
-
onTopMouseMoveListener = addEventListenerWrap(window.top, "mousemove", onMouseMove, false);
|
|
68
|
-
}
|
|
69
|
-
} catch (error) {
|
|
70
|
-
/* istanbul ignore next */
|
|
71
|
-
console.warn(`[rc-image] ${error}`);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
return () => {
|
|
75
|
-
onMouseUpListener?.remove();
|
|
76
|
-
onMouseMoveListener?.remove();
|
|
77
|
-
/* istanbul ignore next */
|
|
78
|
-
onTopMouseUpListener?.remove();
|
|
79
|
-
/* istanbul ignore next */
|
|
80
|
-
onTopMouseMoveListener?.remove();
|
|
81
|
-
};
|
|
82
|
-
}, [
|
|
83
|
-
visible,
|
|
84
|
-
isMoving,
|
|
85
|
-
() => transform.value.x,
|
|
86
|
-
() => transform.value.y,
|
|
87
|
-
() => transform.value.rotate,
|
|
88
|
-
movable
|
|
89
|
-
]);
|
|
90
|
-
return {
|
|
91
|
-
isMoving,
|
|
92
|
-
onMouseDown,
|
|
93
|
-
onMouseMove,
|
|
94
|
-
onMouseUp,
|
|
95
|
-
onWheel
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
//#endregion
|
|
100
|
-
export { useMouseEvent as default };
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { DispatchZoomChangeFunc, TransformType, UpdateTransformFunc } from "./useImageTransform.js";
|
|
2
|
-
import { Ref } from "vue";
|
|
3
|
-
|
|
4
|
-
//#region src/ImagePreview/hooks/useTouchEvent.d.ts
|
|
5
|
-
declare function useTouchEvent(imgRef: Ref<HTMLImageElement>, movable: Ref<boolean>, visible: Ref<boolean>, minScale: Ref<number>, transform: Ref<TransformType>, updateTransform: UpdateTransformFunc, dispatchZoomChange: DispatchZoomChangeFunc): {
|
|
6
|
-
isTouching: Ref<boolean, boolean>;
|
|
7
|
-
onTouchStart: (event: TouchEvent) => void;
|
|
8
|
-
onTouchMove: (event: TouchEvent) => void;
|
|
9
|
-
onTouchEnd: () => void;
|
|
10
|
-
};
|
|
11
|
-
//#endregion
|
|
12
|
-
export { useTouchEvent as default };
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import { TransformAction, TransformType } from "./hooks/useImageTransform.js";
|
|
2
|
-
import _default, { PreviewPropsIcons } from "./props.js";
|
|
3
|
-
import * as vue6 from "vue";
|
|
4
|
-
import { ExtractPropTypes, SlotsType } from "vue";
|
|
5
|
-
import * as _gx_design_vue_pro_utils3 from "@gx-design-vue/pro-utils";
|
|
6
|
-
import * as ant_design_vue_es__util_type0 from "ant-design-vue/es/_util/type";
|
|
7
|
-
|
|
8
|
-
//#region src/ImagePreview/index.d.ts
|
|
9
|
-
type ImagePreviewProps = Partial<ExtractPropTypes<typeof _default>>;
|
|
10
|
-
declare const GImagePreview: vue6.DefineComponent<ExtractPropTypes<{
|
|
11
|
-
urls: {
|
|
12
|
-
type: vue6.PropType<string[]>;
|
|
13
|
-
default: () => any[];
|
|
14
|
-
};
|
|
15
|
-
open: {
|
|
16
|
-
type: vue6.PropType<boolean>;
|
|
17
|
-
default: boolean;
|
|
18
|
-
};
|
|
19
|
-
scaleStep: {
|
|
20
|
-
type: vue6.PropType<number>;
|
|
21
|
-
default: number;
|
|
22
|
-
};
|
|
23
|
-
minScale: {
|
|
24
|
-
type: vue6.PropType<number>;
|
|
25
|
-
default: number;
|
|
26
|
-
};
|
|
27
|
-
maxScale: {
|
|
28
|
-
type: vue6.PropType<number>;
|
|
29
|
-
default: number;
|
|
30
|
-
};
|
|
31
|
-
movable: {
|
|
32
|
-
type: vue6.PropType<boolean>;
|
|
33
|
-
default: boolean;
|
|
34
|
-
};
|
|
35
|
-
disabled: vue6.PropType<boolean>;
|
|
36
|
-
zIndex: {
|
|
37
|
-
type: vue6.PropType<number>;
|
|
38
|
-
default: number;
|
|
39
|
-
};
|
|
40
|
-
current: {
|
|
41
|
-
type: vue6.PropType<number>;
|
|
42
|
-
default: number;
|
|
43
|
-
};
|
|
44
|
-
infinite: {
|
|
45
|
-
type: vue6.PropType<boolean>;
|
|
46
|
-
default: boolean;
|
|
47
|
-
};
|
|
48
|
-
getContainer: {
|
|
49
|
-
type: vue6.PropType<string>;
|
|
50
|
-
};
|
|
51
|
-
onHideOnClickModal: {
|
|
52
|
-
type: vue6.PropType<boolean>;
|
|
53
|
-
default: boolean;
|
|
54
|
-
};
|
|
55
|
-
countRender: vue6.PropType<_gx_design_vue_pro_utils3.WithFalse<(current: number, total: number) => _gx_design_vue_pro_utils3.CustomRender>>;
|
|
56
|
-
icons: {
|
|
57
|
-
type: vue6.PropType<PreviewPropsIcons>;
|
|
58
|
-
default: () => PreviewPropsIcons;
|
|
59
|
-
};
|
|
60
|
-
onTransform: vue6.PropType<(info: {
|
|
61
|
-
transform: TransformType;
|
|
62
|
-
action: TransformAction;
|
|
63
|
-
}) => void>;
|
|
64
|
-
onOpenChange: vue6.PropType<(val: boolean) => void>;
|
|
65
|
-
'onUpdate:open': vue6.PropType<(val: boolean) => void>;
|
|
66
|
-
}>, () => ant_design_vue_es__util_type0.VueNode, {}, {}, {}, vue6.ComponentOptionsMixin, vue6.ComponentOptionsMixin, {
|
|
67
|
-
close: () => true;
|
|
68
|
-
transform: (_info: {
|
|
69
|
-
transform: TransformType;
|
|
70
|
-
action: TransformAction;
|
|
71
|
-
}) => true;
|
|
72
|
-
'update:open': (_val: boolean) => true;
|
|
73
|
-
}, string, vue6.PublicProps, Readonly<ExtractPropTypes<{
|
|
74
|
-
urls: {
|
|
75
|
-
type: vue6.PropType<string[]>;
|
|
76
|
-
default: () => any[];
|
|
77
|
-
};
|
|
78
|
-
open: {
|
|
79
|
-
type: vue6.PropType<boolean>;
|
|
80
|
-
default: boolean;
|
|
81
|
-
};
|
|
82
|
-
scaleStep: {
|
|
83
|
-
type: vue6.PropType<number>;
|
|
84
|
-
default: number;
|
|
85
|
-
};
|
|
86
|
-
minScale: {
|
|
87
|
-
type: vue6.PropType<number>;
|
|
88
|
-
default: number;
|
|
89
|
-
};
|
|
90
|
-
maxScale: {
|
|
91
|
-
type: vue6.PropType<number>;
|
|
92
|
-
default: number;
|
|
93
|
-
};
|
|
94
|
-
movable: {
|
|
95
|
-
type: vue6.PropType<boolean>;
|
|
96
|
-
default: boolean;
|
|
97
|
-
};
|
|
98
|
-
disabled: vue6.PropType<boolean>;
|
|
99
|
-
zIndex: {
|
|
100
|
-
type: vue6.PropType<number>;
|
|
101
|
-
default: number;
|
|
102
|
-
};
|
|
103
|
-
current: {
|
|
104
|
-
type: vue6.PropType<number>;
|
|
105
|
-
default: number;
|
|
106
|
-
};
|
|
107
|
-
infinite: {
|
|
108
|
-
type: vue6.PropType<boolean>;
|
|
109
|
-
default: boolean;
|
|
110
|
-
};
|
|
111
|
-
getContainer: {
|
|
112
|
-
type: vue6.PropType<string>;
|
|
113
|
-
};
|
|
114
|
-
onHideOnClickModal: {
|
|
115
|
-
type: vue6.PropType<boolean>;
|
|
116
|
-
default: boolean;
|
|
117
|
-
};
|
|
118
|
-
countRender: vue6.PropType<_gx_design_vue_pro_utils3.WithFalse<(current: number, total: number) => _gx_design_vue_pro_utils3.CustomRender>>;
|
|
119
|
-
icons: {
|
|
120
|
-
type: vue6.PropType<PreviewPropsIcons>;
|
|
121
|
-
default: () => PreviewPropsIcons;
|
|
122
|
-
};
|
|
123
|
-
onTransform: vue6.PropType<(info: {
|
|
124
|
-
transform: TransformType;
|
|
125
|
-
action: TransformAction;
|
|
126
|
-
}) => void>;
|
|
127
|
-
onOpenChange: vue6.PropType<(val: boolean) => void>;
|
|
128
|
-
'onUpdate:open': vue6.PropType<(val: boolean) => void>;
|
|
129
|
-
}>> & Readonly<{
|
|
130
|
-
onClose?: () => any;
|
|
131
|
-
onTransform?: (_info: {
|
|
132
|
-
transform: TransformType;
|
|
133
|
-
action: TransformAction;
|
|
134
|
-
}) => any;
|
|
135
|
-
"onUpdate:open"?: (_val: boolean) => any;
|
|
136
|
-
}>, {
|
|
137
|
-
zIndex: number;
|
|
138
|
-
icons: PreviewPropsIcons;
|
|
139
|
-
infinite: boolean;
|
|
140
|
-
current: number;
|
|
141
|
-
open: boolean;
|
|
142
|
-
urls: string[];
|
|
143
|
-
scaleStep: number;
|
|
144
|
-
minScale: number;
|
|
145
|
-
maxScale: number;
|
|
146
|
-
movable: boolean;
|
|
147
|
-
onHideOnClickModal: boolean;
|
|
148
|
-
}, SlotsType<{
|
|
149
|
-
close: () => void;
|
|
150
|
-
left: () => void;
|
|
151
|
-
right: () => void;
|
|
152
|
-
countRender: () => void;
|
|
153
|
-
rotateRight: () => void;
|
|
154
|
-
zoomIn: () => void;
|
|
155
|
-
zoomOut: () => void;
|
|
156
|
-
flipX: () => void;
|
|
157
|
-
flipY: () => void;
|
|
158
|
-
rotateLeft: () => void;
|
|
159
|
-
placeholder: () => void;
|
|
160
|
-
}>, {}, {}, string, vue6.ComponentProvideOptions, true, {}, any>;
|
|
161
|
-
//#endregion
|
|
162
|
-
export { ImagePreviewProps, GImagePreview as default };
|
|
@@ -1,303 +0,0 @@
|
|
|
1
|
-
import useImageTransform from "./hooks/useImageTransform.js";
|
|
2
|
-
import addEventListenerWrap from "./utils/addEventListener.js";
|
|
3
|
-
import { BASE_SCALE_RATIO } from "./utils/util.js";
|
|
4
|
-
import useMouseEvent from "./hooks/useMouseEvent.js";
|
|
5
|
-
import useTouchEvent from "./hooks/useTouchEvent.js";
|
|
6
|
-
import props_default from "./props.js";
|
|
7
|
-
import Operations_default from "./Operations.js";
|
|
8
|
-
import { useStyle as useStyle$1 } from "./style.js";
|
|
9
|
-
import KeyCode_default from "./utils/KeyCode.js";
|
|
10
|
-
import { Fragment, Teleport, Transition, computed, createVNode, defineComponent, mergeProps, onMounted, onUnmounted, reactive, ref, toRef, vShow, watch, withDirectives } from "vue";
|
|
11
|
-
import { RotateLeftOutlined, RotateRightOutlined, SwapOutlined, ZoomInOutlined, ZoomOutOutlined } from "@ant-design/icons-vue";
|
|
12
|
-
import { getTransitionProps } from "@gx-design-vue/pro-provider";
|
|
13
|
-
import { getPrefixCls, getSlot, getSlotVNode, getSlotsProps, isArray, isNumber } from "@gx-design-vue/pro-utils";
|
|
14
|
-
import { omit } from "es-toolkit";
|
|
15
|
-
import { useEffect, useMergedState, useState } from "@gx-design-vue/pro-hooks";
|
|
16
|
-
|
|
17
|
-
//#region src/ImagePreview/index.tsx
|
|
18
|
-
const defaultIcons = {
|
|
19
|
-
rotateLeft: createVNode(RotateLeftOutlined, null, null),
|
|
20
|
-
rotateRight: createVNode(RotateRightOutlined, null, null),
|
|
21
|
-
zoomIn: createVNode(ZoomInOutlined, null, null),
|
|
22
|
-
zoomOut: createVNode(ZoomOutOutlined, null, null),
|
|
23
|
-
flipX: createVNode(SwapOutlined, null, null),
|
|
24
|
-
flipY: createVNode(SwapOutlined, { "rotate": 90 }, null)
|
|
25
|
-
};
|
|
26
|
-
const GImagePreview = /* @__PURE__ */ defineComponent({
|
|
27
|
-
name: "GImagePreview",
|
|
28
|
-
props: props_default,
|
|
29
|
-
inheritAttrs: false,
|
|
30
|
-
slots: Object,
|
|
31
|
-
emits: {
|
|
32
|
-
close: () => true,
|
|
33
|
-
transform: (_info) => true,
|
|
34
|
-
"update:open": (_val) => true
|
|
35
|
-
},
|
|
36
|
-
setup: (props, { emit, expose, slots }) => {
|
|
37
|
-
const baseClassName = getPrefixCls({ suffixCls: "image-view" });
|
|
38
|
-
const { wrapSSR, hashId } = useStyle$1(baseClassName);
|
|
39
|
-
const [_, setOpen, innerOpen] = useMergedState(props.open, {
|
|
40
|
-
value: toRef(props, "open"),
|
|
41
|
-
onChange: (val) => {
|
|
42
|
-
props.onOpenChange?.(val);
|
|
43
|
-
emit("update:open", val);
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
const [animate, setAnimate] = useState(false);
|
|
47
|
-
const [enableTransition, setEnableTransition] = useState(true);
|
|
48
|
-
const imgRef = ref();
|
|
49
|
-
const { transform, resetTransform, updateTransform, dispatchZoomChange } = useImageTransform(imgRef, toRef(props, "minScale"), toRef(props, "maxScale"), props.onTransform);
|
|
50
|
-
const { isMoving, onMouseDown, onWheel } = useMouseEvent(imgRef, toRef(props, "movable"), innerOpen, toRef(props, "scaleStep"), transform, updateTransform, dispatchZoomChange);
|
|
51
|
-
const { isTouching, onTouchStart, onTouchMove, onTouchEnd } = useTouchEvent(imgRef, toRef(props, "movable"), innerOpen, toRef(props, "minScale"), transform, updateTransform, dispatchZoomChange);
|
|
52
|
-
useEffect(() => {
|
|
53
|
-
if (!enableTransition.value) setEnableTransition(true);
|
|
54
|
-
}, [enableTransition]);
|
|
55
|
-
const wrapper = ref(null);
|
|
56
|
-
const current = ref(props.current);
|
|
57
|
-
const urls = reactive(/* @__PURE__ */ new Map());
|
|
58
|
-
const canPreviewUrls = computed(() => new Map(Array.from(urls).map(([id, { url }]) => [id, url])));
|
|
59
|
-
const currentSrc = computed(() => canPreviewUrls.value.get(current.value));
|
|
60
|
-
const previewGroupCount = computed(() => canPreviewUrls.value.size);
|
|
61
|
-
const urlsKeys = computed(() => Array.from(canPreviewUrls.value.keys()));
|
|
62
|
-
const currentPreviewIndex = computed(() => urlsKeys.value.indexOf(current.value));
|
|
63
|
-
const showLeftOrRightSwitches = computed(() => previewGroupCount.value > 1);
|
|
64
|
-
const showOperationsProgress = computed(() => previewGroupCount.value >= 1);
|
|
65
|
-
watch(innerOpen, (val) => {
|
|
66
|
-
if (val) animate.value = true;
|
|
67
|
-
});
|
|
68
|
-
const setCurrent = (val) => {
|
|
69
|
-
current.value = val;
|
|
70
|
-
};
|
|
71
|
-
watch(() => props.current, (val) => {
|
|
72
|
-
if (isNumber(val)) setCurrent(val);
|
|
73
|
-
});
|
|
74
|
-
function registerImage(id, url) {
|
|
75
|
-
urls.set(id, {
|
|
76
|
-
url,
|
|
77
|
-
loading: true,
|
|
78
|
-
canPreview: false
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
const onClose = () => {
|
|
82
|
-
setAnimate(false);
|
|
83
|
-
};
|
|
84
|
-
const onAnimateChange = () => {
|
|
85
|
-
resetTransform("close");
|
|
86
|
-
emit("close");
|
|
87
|
-
};
|
|
88
|
-
const hideMask = (e) => {
|
|
89
|
-
if (isMoving.value) return;
|
|
90
|
-
if (wrapper.value === e?.target) onClose();
|
|
91
|
-
};
|
|
92
|
-
const handleImgLoad = () => {
|
|
93
|
-
const currentImage = urls.get(current.value);
|
|
94
|
-
if (currentImage) {
|
|
95
|
-
currentImage.loading = false;
|
|
96
|
-
currentImage.canPreview = true;
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
const handleImgError = (e) => {
|
|
100
|
-
const currentImage = urls.get(current.value);
|
|
101
|
-
if (currentImage) {
|
|
102
|
-
currentImage.loading = false;
|
|
103
|
-
currentImage.canPreview = false;
|
|
104
|
-
}
|
|
105
|
-
e.target.alt = "加载失败";
|
|
106
|
-
};
|
|
107
|
-
const onSwitchLeft = () => {
|
|
108
|
-
if (currentPreviewIndex.value > 0 || props.infinite) {
|
|
109
|
-
const prevIndex = currentPreviewIndex.value - 1 < 0 ? props.urls.length - 1 : currentPreviewIndex.value - 1;
|
|
110
|
-
setCurrent(urlsKeys.value[prevIndex]);
|
|
111
|
-
resetTransform("prev");
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
const onSwitchRight = () => {
|
|
115
|
-
if (currentPreviewIndex.value < previewGroupCount.value - 1 || props.infinite) {
|
|
116
|
-
const nextIndex = currentPreviewIndex.value + 1 > props.urls.length - 1 ? 0 : currentPreviewIndex.value + 1;
|
|
117
|
-
setCurrent(urlsKeys.value[nextIndex]);
|
|
118
|
-
resetTransform("next");
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
const onZoomIn = () => {
|
|
122
|
-
dispatchZoomChange(BASE_SCALE_RATIO + props.scaleStep, "zoomIn");
|
|
123
|
-
};
|
|
124
|
-
const onZoomOut = () => {
|
|
125
|
-
dispatchZoomChange(BASE_SCALE_RATIO / (BASE_SCALE_RATIO + props.scaleStep), "zoomOut");
|
|
126
|
-
};
|
|
127
|
-
const onRotateRight = () => {
|
|
128
|
-
updateTransform({ rotate: transform.value.rotate + 90 }, "rotateRight");
|
|
129
|
-
};
|
|
130
|
-
const onRotateLeft = () => {
|
|
131
|
-
updateTransform({ rotate: transform.value.rotate - 90 }, "rotateLeft");
|
|
132
|
-
};
|
|
133
|
-
const onFlipX = () => {
|
|
134
|
-
updateTransform({ flipX: !transform.value.flipX }, "flipX");
|
|
135
|
-
};
|
|
136
|
-
const onFlipY = () => {
|
|
137
|
-
updateTransform({ flipY: !transform.value.flipY }, "flipY");
|
|
138
|
-
};
|
|
139
|
-
const toolsFn = () => {
|
|
140
|
-
const slotsProps = getSlotsProps({
|
|
141
|
-
slots,
|
|
142
|
-
props: props.icons,
|
|
143
|
-
keys: [
|
|
144
|
-
"flipY",
|
|
145
|
-
"flipX",
|
|
146
|
-
"rotateLeft",
|
|
147
|
-
"rotateRight",
|
|
148
|
-
"zoomOut",
|
|
149
|
-
"zoomIn"
|
|
150
|
-
],
|
|
151
|
-
render: true,
|
|
152
|
-
defaultVNodes: [
|
|
153
|
-
defaultIcons.flipY,
|
|
154
|
-
defaultIcons.flipX,
|
|
155
|
-
defaultIcons.rotateLeft,
|
|
156
|
-
defaultIcons.rotateRight,
|
|
157
|
-
defaultIcons.zoomOut,
|
|
158
|
-
defaultIcons.zoomIn
|
|
159
|
-
]
|
|
160
|
-
});
|
|
161
|
-
return [
|
|
162
|
-
{
|
|
163
|
-
icon: slotsProps.flipY,
|
|
164
|
-
onClick: onFlipY,
|
|
165
|
-
type: "flipY"
|
|
166
|
-
},
|
|
167
|
-
{
|
|
168
|
-
icon: slotsProps.flipX,
|
|
169
|
-
onClick: onFlipX,
|
|
170
|
-
type: "flipX"
|
|
171
|
-
},
|
|
172
|
-
{
|
|
173
|
-
icon: slotsProps.rotateLeft,
|
|
174
|
-
onClick: onRotateLeft,
|
|
175
|
-
type: "rotateLeft"
|
|
176
|
-
},
|
|
177
|
-
{
|
|
178
|
-
icon: slotsProps.rotateRight,
|
|
179
|
-
onClick: onRotateRight,
|
|
180
|
-
type: "rotateRight"
|
|
181
|
-
},
|
|
182
|
-
{
|
|
183
|
-
icon: slotsProps.zoomOut,
|
|
184
|
-
onClick: () => onZoomOut(),
|
|
185
|
-
type: "zoomOut",
|
|
186
|
-
disabled: computed(() => transform.value.scale <= props.minScale)
|
|
187
|
-
},
|
|
188
|
-
{
|
|
189
|
-
icon: slotsProps.zoomIn,
|
|
190
|
-
onClick: () => onZoomIn(),
|
|
191
|
-
type: "zoomIn",
|
|
192
|
-
disabled: computed(() => transform.value.scale === props.maxScale)
|
|
193
|
-
}
|
|
194
|
-
];
|
|
195
|
-
};
|
|
196
|
-
const onDoubleClick = (event) => {
|
|
197
|
-
if (innerOpen.value) if (transform.value.scale !== 1) updateTransform({
|
|
198
|
-
x: 0,
|
|
199
|
-
y: 0,
|
|
200
|
-
scale: 1
|
|
201
|
-
}, "doubleClick");
|
|
202
|
-
else dispatchZoomChange(BASE_SCALE_RATIO + props.scaleStep, "doubleClick", event.clientX, event.clientY);
|
|
203
|
-
};
|
|
204
|
-
const onKeyDown = (event) => {
|
|
205
|
-
if (event.keyCode === KeyCode_default.ESC) onClose();
|
|
206
|
-
if (!innerOpen.value || !showLeftOrRightSwitches.value) return;
|
|
207
|
-
if (event.keyCode === KeyCode_default.LEFT) onSwitchLeft();
|
|
208
|
-
else if (event.keyCode === KeyCode_default.RIGHT) onSwitchRight();
|
|
209
|
-
};
|
|
210
|
-
let removeListeners = () => {};
|
|
211
|
-
onMounted(() => {
|
|
212
|
-
watch(() => props.urls, (val) => {
|
|
213
|
-
if (isArray(val)) val.forEach((src, currentId) => {
|
|
214
|
-
registerImage(currentId, src);
|
|
215
|
-
});
|
|
216
|
-
}, {
|
|
217
|
-
flush: "post",
|
|
218
|
-
immediate: true
|
|
219
|
-
});
|
|
220
|
-
watch([() => innerOpen.value, () => isMoving.value], () => {
|
|
221
|
-
removeListeners();
|
|
222
|
-
const onKeyDownListener = addEventListenerWrap(window, "keydown", onKeyDown, false);
|
|
223
|
-
removeListeners = () => {
|
|
224
|
-
onKeyDownListener.remove();
|
|
225
|
-
};
|
|
226
|
-
}, {
|
|
227
|
-
flush: "post",
|
|
228
|
-
immediate: true
|
|
229
|
-
});
|
|
230
|
-
});
|
|
231
|
-
onUnmounted(() => {
|
|
232
|
-
removeListeners();
|
|
233
|
-
});
|
|
234
|
-
expose({ setOpen: (val) => {
|
|
235
|
-
setOpen(val);
|
|
236
|
-
current.value = props.current;
|
|
237
|
-
} });
|
|
238
|
-
return () => {
|
|
239
|
-
const transitionProps = getTransitionProps(`${baseClassName}-mask-zoom`);
|
|
240
|
-
const zoomTransitionProps = getTransitionProps(`${baseClassName}-zoom`);
|
|
241
|
-
const icons = {};
|
|
242
|
-
for (const key in props.icons) icons[key] = getSlotVNode({
|
|
243
|
-
slots,
|
|
244
|
-
props: props.icons,
|
|
245
|
-
key
|
|
246
|
-
});
|
|
247
|
-
return wrapSSR(createVNode(Fragment, null, [createVNode(Teleport, { "to": props.getContainer || "body" }, { default: () => [innerOpen.value && createVNode(Fragment, null, [createVNode("div", { "class": `${baseClassName}-root ${hashId.value}` }, [createVNode(Transition, transitionProps, { default: () => [withDirectives(createVNode("div", { "class": `${baseClassName}-mask ${hashId.value}` }, null), [[vShow, innerOpen.value && animate.value]])] }), createVNode("div", {
|
|
248
|
-
"ref": wrapper,
|
|
249
|
-
"tabindex": -1,
|
|
250
|
-
"class": [
|
|
251
|
-
`${baseClassName}-wrap`,
|
|
252
|
-
`${hashId.value}`,
|
|
253
|
-
isMoving.value && `${baseClassName}-moving`
|
|
254
|
-
],
|
|
255
|
-
"onClick": (e) => props.onHideOnClickModal && hideMask(e)
|
|
256
|
-
}, [createVNode(Transition, mergeProps(zoomTransitionProps, { "onAfterLeave": () => onAnimateChange() }), { default: () => [withDirectives(createVNode("div", {
|
|
257
|
-
"role": "dialog",
|
|
258
|
-
"class": `${baseClassName} ${hashId.value}`
|
|
259
|
-
}, [createVNode("div", { "class": `${baseClassName}-content ${hashId.value}` }, [createVNode("div", { "class": `${baseClassName}-body ${hashId.value}` }, [createVNode("div", { "class": `${baseClassName}-img-wrapper ${hashId.value}` }, [createVNode("img", {
|
|
260
|
-
"ref": imgRef,
|
|
261
|
-
"class": `${baseClassName}-img ${hashId.value}`,
|
|
262
|
-
"src": currentSrc.value,
|
|
263
|
-
"onLoad": () => handleImgLoad(),
|
|
264
|
-
"onError": (e) => handleImgError(e),
|
|
265
|
-
"style": {
|
|
266
|
-
transform: `translate3d(${transform.value.x}px, ${transform.value.y}px, 0) scale3d(${transform.value.flipX ? "-" : ""}${transform.value.scale}, ${transform.value.flipY ? "-" : ""}${transform.value.scale}, 1) rotate(${transform.value.rotate}deg)`,
|
|
267
|
-
transitionDuration: !enableTransition.value || isTouching.value ? "0s" : void 0
|
|
268
|
-
},
|
|
269
|
-
"onWheel": onWheel,
|
|
270
|
-
"onMousedown": onMouseDown,
|
|
271
|
-
"onDblclick": onDoubleClick,
|
|
272
|
-
"onTouchstart": onTouchStart,
|
|
273
|
-
"onTouchmove": onTouchMove,
|
|
274
|
-
"onTouchend": onTouchEnd,
|
|
275
|
-
"onTouchcancel": onTouchEnd
|
|
276
|
-
}, null)])])])]), [[vShow, innerOpen.value && animate.value]])] })])])])] }), innerOpen.value && animate.value && createVNode(Operations_default, {
|
|
277
|
-
"open": innerOpen.value && animate.value,
|
|
278
|
-
"hashId": hashId.value,
|
|
279
|
-
"count": props.urls.length,
|
|
280
|
-
"current": current.value,
|
|
281
|
-
"zIndex": props.zIndex + 1,
|
|
282
|
-
"getContainer": props.getContainer,
|
|
283
|
-
"prefixCls": baseClassName,
|
|
284
|
-
"icons": omit(icons, toolsFn().map(({ type }) => type)),
|
|
285
|
-
"tools": toolsFn(),
|
|
286
|
-
"infinite": props.infinite,
|
|
287
|
-
"countRender": getSlot({
|
|
288
|
-
slots,
|
|
289
|
-
props,
|
|
290
|
-
key: "countRender"
|
|
291
|
-
}),
|
|
292
|
-
"showSwitch": showLeftOrRightSwitches.value,
|
|
293
|
-
"showProgress": showOperationsProgress.value,
|
|
294
|
-
"onClose": onClose,
|
|
295
|
-
"onActive": (effect) => effect > 0 ? onSwitchRight() : onSwitchLeft()
|
|
296
|
-
}, null)]));
|
|
297
|
-
};
|
|
298
|
-
}
|
|
299
|
-
});
|
|
300
|
-
var ImagePreview_default = GImagePreview;
|
|
301
|
-
|
|
302
|
-
//#endregion
|
|
303
|
-
export { ImagePreview_default as default };
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { TransformAction, TransformType } from "./hooks/useImageTransform.js";
|
|
2
|
-
import { PropType, VNode } from "vue";
|
|
3
|
-
import { CustomRender, WithFalse } from "@gx-design-vue/pro-utils";
|
|
4
|
-
|
|
5
|
-
//#region src/ImagePreview/props.d.ts
|
|
6
|
-
interface PreviewPropsIcons {
|
|
7
|
-
close?: WithFalse<CustomRender>;
|
|
8
|
-
rotateLeft?: WithFalse<CustomRender>;
|
|
9
|
-
rotateRight?: WithFalse<CustomRender>;
|
|
10
|
-
zoomIn?: WithFalse<CustomRender>;
|
|
11
|
-
zoomOut?: WithFalse<CustomRender>;
|
|
12
|
-
left?: WithFalse<CustomRender>;
|
|
13
|
-
right?: WithFalse<CustomRender>;
|
|
14
|
-
flipX?: WithFalse<CustomRender>;
|
|
15
|
-
flipY?: WithFalse<CustomRender>;
|
|
16
|
-
}
|
|
17
|
-
type BaseImagePreviewProps = Partial<{
|
|
18
|
-
urls: string[];
|
|
19
|
-
mask: VNode | boolean;
|
|
20
|
-
maskClass: string;
|
|
21
|
-
disabled: boolean;
|
|
22
|
-
zIndex: number;
|
|
23
|
-
current: number;
|
|
24
|
-
infinite: boolean;
|
|
25
|
-
getContainer: string;
|
|
26
|
-
onHideOnClickModal: boolean;
|
|
27
|
-
countRender: WithFalse<(current: number, total: number) => CustomRender>;
|
|
28
|
-
icons: PreviewPropsIcons;
|
|
29
|
-
}>;
|
|
30
|
-
declare const _default: {
|
|
31
|
-
urls: {
|
|
32
|
-
type: PropType<string[]>;
|
|
33
|
-
default: () => any[];
|
|
34
|
-
};
|
|
35
|
-
open: {
|
|
36
|
-
type: PropType<boolean>;
|
|
37
|
-
default: boolean;
|
|
38
|
-
};
|
|
39
|
-
scaleStep: {
|
|
40
|
-
type: PropType<number>;
|
|
41
|
-
default: number;
|
|
42
|
-
};
|
|
43
|
-
minScale: {
|
|
44
|
-
type: PropType<number>;
|
|
45
|
-
default: number;
|
|
46
|
-
};
|
|
47
|
-
maxScale: {
|
|
48
|
-
type: PropType<number>;
|
|
49
|
-
default: number;
|
|
50
|
-
};
|
|
51
|
-
movable: {
|
|
52
|
-
type: PropType<boolean>;
|
|
53
|
-
default: boolean;
|
|
54
|
-
};
|
|
55
|
-
disabled: PropType<boolean>;
|
|
56
|
-
zIndex: {
|
|
57
|
-
type: PropType<number>;
|
|
58
|
-
default: number;
|
|
59
|
-
};
|
|
60
|
-
current: {
|
|
61
|
-
type: PropType<number>;
|
|
62
|
-
default: number;
|
|
63
|
-
};
|
|
64
|
-
infinite: {
|
|
65
|
-
type: PropType<boolean>;
|
|
66
|
-
default: boolean;
|
|
67
|
-
};
|
|
68
|
-
getContainer: {
|
|
69
|
-
type: PropType<string>;
|
|
70
|
-
};
|
|
71
|
-
onHideOnClickModal: {
|
|
72
|
-
type: PropType<boolean>;
|
|
73
|
-
default: boolean;
|
|
74
|
-
};
|
|
75
|
-
countRender: PropType<WithFalse<(current: number, total: number) => CustomRender>>;
|
|
76
|
-
icons: {
|
|
77
|
-
type: PropType<PreviewPropsIcons>;
|
|
78
|
-
default: () => PreviewPropsIcons;
|
|
79
|
-
};
|
|
80
|
-
onTransform: PropType<(info: {
|
|
81
|
-
transform: TransformType;
|
|
82
|
-
action: TransformAction;
|
|
83
|
-
}) => void>;
|
|
84
|
-
onOpenChange: PropType<(val: boolean) => void>;
|
|
85
|
-
'onUpdate:open': PropType<(val: boolean) => void>;
|
|
86
|
-
};
|
|
87
|
-
//#endregion
|
|
88
|
-
export { BaseImagePreviewProps, PreviewPropsIcons, _default as default };
|