@gx-design-vue/image 0.1.2 → 0.2.0-beta.0
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 +69 -10
- package/dist/components/ImageViewer.d.ts +138 -4
- package/dist/components/style.d.ts +22 -0
- package/dist/image.mjs +1495 -0
- package/dist/image.umd.js +2 -1
- package/dist/index.d.ts +0 -3
- package/dist/props.d.ts +51 -3
- package/dist/style.d.ts +6 -0
- package/package.json +11 -12
- package/dist/components/ImageViewerGroup.d.ts +0 -14
- package/dist/design/config.less +0 -2
- package/dist/image.es.js +0 -801
- package/dist/style.css +0 -1
- package/dist/style.less +0 -177
package/dist/image.es.js
DELETED
|
@@ -1,801 +0,0 @@
|
|
|
1
|
-
import { createVNode, defineComponent, ref, computed, watch, nextTick, Fragment, resolveComponent, cloneVNode, Teleport, isVNode, createTextVNode, mergeProps } from "vue";
|
|
2
|
-
import { ExpandOutlined, OneToOneOutlined, CloseOutlined, LeftOutlined, RightOutlined, ZoomOutOutlined, ZoomInOutlined, RotateLeftOutlined, RotateRightOutlined, LoadingOutlined } from "@ant-design/icons-vue";
|
|
3
|
-
import { getPrefixCls, isServer, getSlotVNode, isInContainer, isString, getScrollContainer } from "@gx-design-vue/pro-utils";
|
|
4
|
-
import { onMountedOrActivated } from "@gx-design-vue/pro-hooks";
|
|
5
|
-
import { createTypes } from "vue-types";
|
|
6
|
-
import { useThrottleFn, useEventListener } from "@vueuse/core";
|
|
7
|
-
var config = "";
|
|
8
|
-
var style = "";
|
|
9
|
-
var PropTypes = createTypes({
|
|
10
|
-
func: void 0,
|
|
11
|
-
bool: void 0,
|
|
12
|
-
string: void 0,
|
|
13
|
-
number: void 0,
|
|
14
|
-
array: void 0,
|
|
15
|
-
object: void 0,
|
|
16
|
-
integer: void 0
|
|
17
|
-
});
|
|
18
|
-
PropTypes.extend([{
|
|
19
|
-
name: "looseBool",
|
|
20
|
-
getter: true,
|
|
21
|
-
type: Boolean,
|
|
22
|
-
default: void 0
|
|
23
|
-
}, {
|
|
24
|
-
name: "style",
|
|
25
|
-
getter: true,
|
|
26
|
-
type: [String, Object],
|
|
27
|
-
default: void 0
|
|
28
|
-
}, {
|
|
29
|
-
name: "VueNode",
|
|
30
|
-
getter: true,
|
|
31
|
-
type: null
|
|
32
|
-
}]);
|
|
33
|
-
var PropTypes$1 = PropTypes;
|
|
34
|
-
const gImagePorps = {
|
|
35
|
-
appendToBody: {
|
|
36
|
-
type: Boolean,
|
|
37
|
-
default: false
|
|
38
|
-
},
|
|
39
|
-
hideOnClickModal: {
|
|
40
|
-
type: Boolean,
|
|
41
|
-
default: true
|
|
42
|
-
},
|
|
43
|
-
src: {
|
|
44
|
-
type: String,
|
|
45
|
-
default: ""
|
|
46
|
-
},
|
|
47
|
-
fit: {
|
|
48
|
-
type: String,
|
|
49
|
-
default: ""
|
|
50
|
-
},
|
|
51
|
-
lazy: PropTypes$1.bool,
|
|
52
|
-
scrollContainer: {
|
|
53
|
-
type: [String, Object]
|
|
54
|
-
},
|
|
55
|
-
placeholder: {
|
|
56
|
-
type: [Function, Object],
|
|
57
|
-
default: () => void 0
|
|
58
|
-
},
|
|
59
|
-
fallback: {
|
|
60
|
-
type: [Function, Object],
|
|
61
|
-
default: () => void 0
|
|
62
|
-
},
|
|
63
|
-
onError: {
|
|
64
|
-
type: Function
|
|
65
|
-
},
|
|
66
|
-
onClick: {
|
|
67
|
-
type: Function
|
|
68
|
-
},
|
|
69
|
-
disablePreview: PropTypes$1.bool,
|
|
70
|
-
previewSrcList: {
|
|
71
|
-
type: Array,
|
|
72
|
-
default: () => []
|
|
73
|
-
},
|
|
74
|
-
width: PropTypes$1.number,
|
|
75
|
-
height: PropTypes$1.number,
|
|
76
|
-
zIndex: {
|
|
77
|
-
type: Number,
|
|
78
|
-
default: 2e3
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
const gImageViewProps = {
|
|
82
|
-
urlList: {
|
|
83
|
-
type: Array,
|
|
84
|
-
default: () => []
|
|
85
|
-
},
|
|
86
|
-
zIndex: gImagePorps.zIndex,
|
|
87
|
-
initialIndex: {
|
|
88
|
-
type: Number,
|
|
89
|
-
default: 0
|
|
90
|
-
},
|
|
91
|
-
infinite: {
|
|
92
|
-
type: Boolean,
|
|
93
|
-
default: true
|
|
94
|
-
},
|
|
95
|
-
onHideOnClickModal: gImagePorps.hideOnClickModal
|
|
96
|
-
};
|
|
97
|
-
const EVENT_CODE = {
|
|
98
|
-
tab: "Tab",
|
|
99
|
-
enter: "Enter",
|
|
100
|
-
space: "Space",
|
|
101
|
-
left: "ArrowLeft",
|
|
102
|
-
up: "ArrowUp",
|
|
103
|
-
right: "ArrowRight",
|
|
104
|
-
down: "ArrowDown",
|
|
105
|
-
esc: "Escape",
|
|
106
|
-
delete: "Delete",
|
|
107
|
-
backspace: "Backspace"
|
|
108
|
-
};
|
|
109
|
-
const on = function(element, event, handler, useCapture = false) {
|
|
110
|
-
if (element && event && handler) {
|
|
111
|
-
element.addEventListener(event, handler, useCapture);
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
const off = function(element, event, handler, useCapture = false) {
|
|
115
|
-
if (element && event && handler) {
|
|
116
|
-
element.removeEventListener(event, handler, useCapture);
|
|
117
|
-
}
|
|
118
|
-
};
|
|
119
|
-
const Mode = {
|
|
120
|
-
CONTAIN: {
|
|
121
|
-
name: "contain",
|
|
122
|
-
icon: createVNode(ExpandOutlined, null, null)
|
|
123
|
-
},
|
|
124
|
-
ORIGINAL: {
|
|
125
|
-
name: "original",
|
|
126
|
-
icon: createVNode(OneToOneOutlined, null, null)
|
|
127
|
-
}
|
|
128
|
-
};
|
|
129
|
-
const isFirefox = function() {
|
|
130
|
-
return !isServer && !!window.navigator.userAgent.match(/firefox/i);
|
|
131
|
-
};
|
|
132
|
-
const mousewheelEventName = isFirefox() ? "DOMMouseScroll" : "mousewheel";
|
|
133
|
-
function rafThrottle(fn) {
|
|
134
|
-
let locked = false;
|
|
135
|
-
return function(...args) {
|
|
136
|
-
if (locked)
|
|
137
|
-
return;
|
|
138
|
-
locked = true;
|
|
139
|
-
window.requestAnimationFrame(() => {
|
|
140
|
-
fn.apply(this, args);
|
|
141
|
-
locked = false;
|
|
142
|
-
});
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
const GImageViewer = defineComponent({
|
|
146
|
-
props: gImageViewProps,
|
|
147
|
-
emits: ["close", "switch"],
|
|
148
|
-
setup: function(props, {
|
|
149
|
-
emit
|
|
150
|
-
}) {
|
|
151
|
-
let _keyDownHandler = null;
|
|
152
|
-
let _mouseWheelHandler = null;
|
|
153
|
-
let _dragHandler = null;
|
|
154
|
-
const baseClassName = getPrefixCls({
|
|
155
|
-
suffixCls: "image-viewer"
|
|
156
|
-
});
|
|
157
|
-
const loading = ref(true);
|
|
158
|
-
const index = ref(props.initialIndex);
|
|
159
|
-
const wrapper = ref(null);
|
|
160
|
-
const img = ref(null);
|
|
161
|
-
const mode = ref(Mode.CONTAIN);
|
|
162
|
-
const transform = ref({
|
|
163
|
-
scale: 1,
|
|
164
|
-
deg: 0,
|
|
165
|
-
offsetX: 0,
|
|
166
|
-
offsetY: 0,
|
|
167
|
-
enableTransition: false
|
|
168
|
-
});
|
|
169
|
-
const isSingle = computed(() => {
|
|
170
|
-
const {
|
|
171
|
-
urlList
|
|
172
|
-
} = props;
|
|
173
|
-
return urlList.length <= 1;
|
|
174
|
-
});
|
|
175
|
-
const isFirst = computed(() => {
|
|
176
|
-
return index.value === 0;
|
|
177
|
-
});
|
|
178
|
-
const isLast = computed(() => {
|
|
179
|
-
return index.value === props.urlList.length - 1;
|
|
180
|
-
});
|
|
181
|
-
const currentImg = computed(() => {
|
|
182
|
-
return props.urlList[index.value];
|
|
183
|
-
});
|
|
184
|
-
const animateCss = ref("viewer-fade-enter-active");
|
|
185
|
-
const imgStyle = computed(() => {
|
|
186
|
-
const {
|
|
187
|
-
scale,
|
|
188
|
-
deg,
|
|
189
|
-
offsetX,
|
|
190
|
-
offsetY,
|
|
191
|
-
enableTransition
|
|
192
|
-
} = transform.value;
|
|
193
|
-
const style2 = {
|
|
194
|
-
transform: `scale(${scale}) rotate(${deg}deg)`,
|
|
195
|
-
transition: enableTransition ? "transform .3s" : "",
|
|
196
|
-
marginLeft: `${offsetX}px`,
|
|
197
|
-
marginTop: `${offsetY}px`
|
|
198
|
-
};
|
|
199
|
-
if (mode.value.name === Mode.CONTAIN.name) {
|
|
200
|
-
style2.maxWidth = style2.maxHeight = "100%";
|
|
201
|
-
}
|
|
202
|
-
return style2;
|
|
203
|
-
});
|
|
204
|
-
const hide = () => {
|
|
205
|
-
deviceSupportUninstall();
|
|
206
|
-
setTimeout(() => {
|
|
207
|
-
emit("close");
|
|
208
|
-
}, 200);
|
|
209
|
-
};
|
|
210
|
-
const deviceSupportInstall = () => {
|
|
211
|
-
animateCss.value = "viewer-fade-enter-active";
|
|
212
|
-
_keyDownHandler = rafThrottle((e) => {
|
|
213
|
-
switch (e.code) {
|
|
214
|
-
case EVENT_CODE.esc:
|
|
215
|
-
hide();
|
|
216
|
-
break;
|
|
217
|
-
case EVENT_CODE.space:
|
|
218
|
-
toggleMode();
|
|
219
|
-
break;
|
|
220
|
-
case EVENT_CODE.left:
|
|
221
|
-
prev();
|
|
222
|
-
break;
|
|
223
|
-
case EVENT_CODE.up:
|
|
224
|
-
handleActions("zoomIn");
|
|
225
|
-
break;
|
|
226
|
-
case EVENT_CODE.right:
|
|
227
|
-
next();
|
|
228
|
-
break;
|
|
229
|
-
case EVENT_CODE.down:
|
|
230
|
-
handleActions("zoomOut");
|
|
231
|
-
break;
|
|
232
|
-
}
|
|
233
|
-
});
|
|
234
|
-
_mouseWheelHandler = rafThrottle((e) => {
|
|
235
|
-
const delta = e.wheelDelta ? e.wheelDelta : -e.detail;
|
|
236
|
-
if (delta > 0) {
|
|
237
|
-
handleActions("zoomIn", {
|
|
238
|
-
zoomRate: 0.015,
|
|
239
|
-
enableTransition: false
|
|
240
|
-
});
|
|
241
|
-
} else {
|
|
242
|
-
handleActions("zoomOut", {
|
|
243
|
-
zoomRate: 0.015,
|
|
244
|
-
enableTransition: false
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
});
|
|
248
|
-
on(document, "keydown", _keyDownHandler);
|
|
249
|
-
on(document, mousewheelEventName, _mouseWheelHandler);
|
|
250
|
-
};
|
|
251
|
-
const deviceSupportUninstall = () => {
|
|
252
|
-
animateCss.value = "viewer-fade-leave-active";
|
|
253
|
-
off(document, "keydown", _keyDownHandler);
|
|
254
|
-
off(document, mousewheelEventName, _mouseWheelHandler);
|
|
255
|
-
_keyDownHandler = null;
|
|
256
|
-
_mouseWheelHandler = null;
|
|
257
|
-
};
|
|
258
|
-
const handleImgLoad = () => {
|
|
259
|
-
loading.value = false;
|
|
260
|
-
};
|
|
261
|
-
const handleImgError = (e) => {
|
|
262
|
-
loading.value = false;
|
|
263
|
-
e.target.alt = "\u52A0\u8F7D\u5931\u8D25";
|
|
264
|
-
};
|
|
265
|
-
const handleMouseDown = (e) => {
|
|
266
|
-
if (loading.value || e.button !== 0)
|
|
267
|
-
return;
|
|
268
|
-
const {
|
|
269
|
-
offsetX,
|
|
270
|
-
offsetY
|
|
271
|
-
} = transform.value;
|
|
272
|
-
const startX = e.pageX;
|
|
273
|
-
const startY = e.pageY;
|
|
274
|
-
_dragHandler = rafThrottle((ev) => {
|
|
275
|
-
transform.value = {
|
|
276
|
-
...transform.value,
|
|
277
|
-
offsetX: offsetX + ev.pageX - startX,
|
|
278
|
-
offsetY: offsetY + ev.pageY - startY
|
|
279
|
-
};
|
|
280
|
-
});
|
|
281
|
-
on(document, "mousemove", _dragHandler);
|
|
282
|
-
on(document, "mouseup", () => {
|
|
283
|
-
off(document, "mousemove", _dragHandler);
|
|
284
|
-
});
|
|
285
|
-
e.preventDefault();
|
|
286
|
-
};
|
|
287
|
-
const reset = () => {
|
|
288
|
-
transform.value = {
|
|
289
|
-
scale: 1,
|
|
290
|
-
deg: 0,
|
|
291
|
-
offsetX: 0,
|
|
292
|
-
offsetY: 0,
|
|
293
|
-
enableTransition: false
|
|
294
|
-
};
|
|
295
|
-
};
|
|
296
|
-
const toggleMode = () => {
|
|
297
|
-
if (loading.value)
|
|
298
|
-
return;
|
|
299
|
-
const modeNames = Object.keys(Mode);
|
|
300
|
-
const modeValues = Object.values(Mode);
|
|
301
|
-
const currentMode = mode.value.name;
|
|
302
|
-
const index2 = modeValues.findIndex((i) => i.name === currentMode);
|
|
303
|
-
const nextIndex = (index2 + 1) % modeNames.length;
|
|
304
|
-
mode.value = Mode[modeNames[nextIndex]];
|
|
305
|
-
reset();
|
|
306
|
-
};
|
|
307
|
-
const prev = () => {
|
|
308
|
-
if (isFirst.value && !props.infinite)
|
|
309
|
-
return;
|
|
310
|
-
const len = props.urlList.length;
|
|
311
|
-
index.value = (index.value - 1 + len) % len;
|
|
312
|
-
};
|
|
313
|
-
const next = () => {
|
|
314
|
-
if (isLast.value && !props.infinite)
|
|
315
|
-
return;
|
|
316
|
-
const len = props.urlList.length;
|
|
317
|
-
index.value = (index.value + 1) % len;
|
|
318
|
-
};
|
|
319
|
-
const handleActions = (action, options = {}) => {
|
|
320
|
-
if (loading.value)
|
|
321
|
-
return;
|
|
322
|
-
const {
|
|
323
|
-
zoomRate,
|
|
324
|
-
rotateDeg,
|
|
325
|
-
enableTransition
|
|
326
|
-
} = {
|
|
327
|
-
zoomRate: 0.2,
|
|
328
|
-
rotateDeg: 90,
|
|
329
|
-
enableTransition: true,
|
|
330
|
-
...options
|
|
331
|
-
};
|
|
332
|
-
switch (action) {
|
|
333
|
-
case "zoomOut":
|
|
334
|
-
if (transform.value.scale > 0.2) {
|
|
335
|
-
transform.value.scale = parseFloat((transform.value.scale - zoomRate).toFixed(3));
|
|
336
|
-
}
|
|
337
|
-
break;
|
|
338
|
-
case "zoomIn":
|
|
339
|
-
transform.value.scale = parseFloat((transform.value.scale + zoomRate).toFixed(3));
|
|
340
|
-
break;
|
|
341
|
-
case "clocelise":
|
|
342
|
-
transform.value.deg += rotateDeg;
|
|
343
|
-
break;
|
|
344
|
-
case "anticlocelise":
|
|
345
|
-
transform.value.deg -= rotateDeg;
|
|
346
|
-
break;
|
|
347
|
-
}
|
|
348
|
-
transform.value.enableTransition = enableTransition;
|
|
349
|
-
};
|
|
350
|
-
watch(currentImg, () => {
|
|
351
|
-
nextTick(() => {
|
|
352
|
-
const $img = img.value;
|
|
353
|
-
if (!$img.complete) {
|
|
354
|
-
loading.value = true;
|
|
355
|
-
}
|
|
356
|
-
});
|
|
357
|
-
});
|
|
358
|
-
watch(index, (val) => {
|
|
359
|
-
reset();
|
|
360
|
-
emit("switch", val);
|
|
361
|
-
});
|
|
362
|
-
onMountedOrActivated(() => {
|
|
363
|
-
var _a, _b;
|
|
364
|
-
deviceSupportInstall();
|
|
365
|
-
(_b = (_a = wrapper.value) == null ? void 0 : _a.focus) == null ? void 0 : _b.call(_a);
|
|
366
|
-
});
|
|
367
|
-
return () => {
|
|
368
|
-
return createVNode("div", {
|
|
369
|
-
"ref": (e) => wrapper.value = e,
|
|
370
|
-
"tabindex": 1,
|
|
371
|
-
"class": [`${baseClassName}-wrapper`, `${animateCss.value}`],
|
|
372
|
-
"style": {
|
|
373
|
-
zIndex: props.zIndex
|
|
374
|
-
}
|
|
375
|
-
}, [createVNode("div", {
|
|
376
|
-
"class": `${baseClassName}-mask`,
|
|
377
|
-
"onClick": () => props.onHideOnClickModal && hide()
|
|
378
|
-
}, null), createVNode("span", {
|
|
379
|
-
"class": [`${baseClassName}-btn`, `${baseClassName}-close`],
|
|
380
|
-
"onClick": () => hide()
|
|
381
|
-
}, [createVNode(CloseOutlined, null, null)]), !isSingle.value && createVNode(Fragment, null, [createVNode("span", {
|
|
382
|
-
"class": {
|
|
383
|
-
[`${baseClassName}-btn`]: true,
|
|
384
|
-
[`${baseClassName}-prev`]: true,
|
|
385
|
-
[`is-disabled`]: !props.infinite && isFirst.value
|
|
386
|
-
},
|
|
387
|
-
"onClick": () => prev()
|
|
388
|
-
}, [createVNode(LeftOutlined, null, null)]), createVNode("span", {
|
|
389
|
-
"class": {
|
|
390
|
-
[`${baseClassName}-btn`]: true,
|
|
391
|
-
[`${baseClassName}-next`]: true,
|
|
392
|
-
[`is-disabled`]: !props.infinite && isFirst.value
|
|
393
|
-
},
|
|
394
|
-
"onClick": () => next()
|
|
395
|
-
}, [createVNode(RightOutlined, null, null)])]), createVNode("div", {
|
|
396
|
-
"class": [`${baseClassName}-btn`, `${baseClassName}-actions`]
|
|
397
|
-
}, [createVNode("div", {
|
|
398
|
-
"class": `${baseClassName}-actions-inner`
|
|
399
|
-
}, [createVNode(ZoomOutOutlined, {
|
|
400
|
-
"onClick": () => handleActions("zoomOut")
|
|
401
|
-
}, null), createVNode(ZoomInOutlined, {
|
|
402
|
-
"onClick": () => handleActions("zoomIn")
|
|
403
|
-
}, null), createVNode("i", {
|
|
404
|
-
"class": `${baseClassName}-actions-divider`
|
|
405
|
-
}, null), createVNode("i", {
|
|
406
|
-
"onClick": () => toggleMode()
|
|
407
|
-
}, [mode.value.icon]), createVNode("i", {
|
|
408
|
-
"class": `${baseClassName}-actions-divider`
|
|
409
|
-
}, null), createVNode(RotateLeftOutlined, {
|
|
410
|
-
"onClick": () => handleActions("anticlocelise")
|
|
411
|
-
}, null), createVNode(RotateRightOutlined, {
|
|
412
|
-
"onClick": () => handleActions("clocelise")
|
|
413
|
-
}, null)])]), loading.value && createVNode("div", {
|
|
414
|
-
"class": `${baseClassName}-canvas`
|
|
415
|
-
}, [createVNode(resolveComponent("a-spin"), {
|
|
416
|
-
"indicator": createVNode(LoadingOutlined, {
|
|
417
|
-
"style": {
|
|
418
|
-
color: "#fff",
|
|
419
|
-
fontSize: "40px"
|
|
420
|
-
}
|
|
421
|
-
}, null)
|
|
422
|
-
}, null)]), createVNode("div", {
|
|
423
|
-
"class": `${baseClassName}-canvas`
|
|
424
|
-
}, [props.urlList.map((url, i) => {
|
|
425
|
-
return createVNode("img", {
|
|
426
|
-
"ref": (e) => img.value = e,
|
|
427
|
-
"class": `${baseClassName}-img`,
|
|
428
|
-
"key": url,
|
|
429
|
-
"style": {
|
|
430
|
-
...imgStyle.value,
|
|
431
|
-
display: i === index.value ? "block" : "none"
|
|
432
|
-
},
|
|
433
|
-
"src": url,
|
|
434
|
-
"onLoad": () => handleImgLoad(),
|
|
435
|
-
"onError": (e) => handleImgError(e),
|
|
436
|
-
"onMousedown": (e) => handleMouseDown(e)
|
|
437
|
-
}, null);
|
|
438
|
-
})])]);
|
|
439
|
-
};
|
|
440
|
-
}
|
|
441
|
-
});
|
|
442
|
-
function _isSlot(s) {
|
|
443
|
-
return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
|
|
444
|
-
}
|
|
445
|
-
let prevOverflow$1 = "";
|
|
446
|
-
const gImageViewerGroup = defineComponent({
|
|
447
|
-
props: {
|
|
448
|
-
hideOnClickModal: gImagePorps.hideOnClickModal
|
|
449
|
-
},
|
|
450
|
-
setup(props, {
|
|
451
|
-
slots
|
|
452
|
-
}) {
|
|
453
|
-
const baseClassName = getPrefixCls({
|
|
454
|
-
suffixCls: "image-viewer-group"
|
|
455
|
-
});
|
|
456
|
-
const showViewer = ref(false);
|
|
457
|
-
const initialSrc = ref("");
|
|
458
|
-
const getChildrenSlots = computed(() => {
|
|
459
|
-
var _a, _b, _c, _d, _e;
|
|
460
|
-
return ((_a = slots.default) == null ? void 0 : _a.call(slots).length) === 1 && (String((_b = slots.default) == null ? void 0 : _b.call(slots)[0].type) === String(Symbol("Fragment")) || String((_c = slots.default) == null ? void 0 : _c.call(slots)[0].type) === String(Symbol())) ? ((_d = slots.default) == null ? void 0 : _d.call(slots)[0].children) || [] : ((_e = slots.default) == null ? void 0 : _e.call(slots)) || [];
|
|
461
|
-
});
|
|
462
|
-
const previewSrcList = computed(() => {
|
|
463
|
-
const childrenArray = getChildrenSlots.value;
|
|
464
|
-
const checkedTags = childrenArray.filter((child) => isGImage(child)).map((child) => child.props.src).filter((src) => src);
|
|
465
|
-
return checkedTags || [];
|
|
466
|
-
});
|
|
467
|
-
const preview = computed(() => {
|
|
468
|
-
return Array.isArray(previewSrcList.value) && previewSrcList.value.length > 0;
|
|
469
|
-
});
|
|
470
|
-
const isGImage = (node) => {
|
|
471
|
-
return node && node.type && (node.type.isGImage || node.type.name === "GImage");
|
|
472
|
-
};
|
|
473
|
-
const imageIndex = () => {
|
|
474
|
-
let previewIndex = 0;
|
|
475
|
-
const srcIndex = previewSrcList.value.findIndex((item) => item === initialSrc.value);
|
|
476
|
-
if (srcIndex >= 0) {
|
|
477
|
-
previewIndex = srcIndex;
|
|
478
|
-
}
|
|
479
|
-
return previewIndex;
|
|
480
|
-
};
|
|
481
|
-
const clickHandler = (src) => {
|
|
482
|
-
if (!preview.value || !src) {
|
|
483
|
-
return;
|
|
484
|
-
}
|
|
485
|
-
initialSrc.value = src;
|
|
486
|
-
prevOverflow$1 = document.body.style.overflow;
|
|
487
|
-
document.body.style.overflow = "hidden";
|
|
488
|
-
showViewer.value = true;
|
|
489
|
-
};
|
|
490
|
-
const closeViewer = () => {
|
|
491
|
-
document.body.style.overflow = prevOverflow$1;
|
|
492
|
-
showViewer.value = false;
|
|
493
|
-
};
|
|
494
|
-
return () => {
|
|
495
|
-
let _slot;
|
|
496
|
-
return createVNode("div", {
|
|
497
|
-
"class": `${baseClassName}`
|
|
498
|
-
}, [createVNode(resolveComponent("a-space"), {
|
|
499
|
-
"size": 15
|
|
500
|
-
}, _isSlot(_slot = getChildrenSlots.value.map((child, index) => {
|
|
501
|
-
if (isGImage(child)) {
|
|
502
|
-
return createVNode("div", {
|
|
503
|
-
"key": index,
|
|
504
|
-
"class": `${baseClassName}-item`,
|
|
505
|
-
"onClick": () => {
|
|
506
|
-
var _a;
|
|
507
|
-
return clickHandler(((_a = child.props) == null ? void 0 : _a.src) || "");
|
|
508
|
-
}
|
|
509
|
-
}, [cloneVNode(child, {
|
|
510
|
-
disablePreview: true
|
|
511
|
-
})]);
|
|
512
|
-
}
|
|
513
|
-
return null;
|
|
514
|
-
})) ? _slot : {
|
|
515
|
-
default: () => [_slot]
|
|
516
|
-
}), createVNode(Teleport, {
|
|
517
|
-
"to": "body"
|
|
518
|
-
}, {
|
|
519
|
-
default: () => [preview.value && showViewer.value && createVNode(GImageViewer, {
|
|
520
|
-
"initialIndex": imageIndex(),
|
|
521
|
-
"urlList": previewSrcList.value,
|
|
522
|
-
"onHideOnClickModal": props.hideOnClickModal,
|
|
523
|
-
"onClose": () => closeViewer()
|
|
524
|
-
}, null)]
|
|
525
|
-
})]);
|
|
526
|
-
};
|
|
527
|
-
}
|
|
528
|
-
});
|
|
529
|
-
const isHtmlElement = (e) => e && e.nodeType === Node.ELEMENT_NODE;
|
|
530
|
-
const isSupportObjectFit = () => document.documentElement.style.objectFit !== void 0;
|
|
531
|
-
let prevOverflow = "";
|
|
532
|
-
const ObjectFit = {
|
|
533
|
-
NONE: "none",
|
|
534
|
-
CONTAIN: "contain",
|
|
535
|
-
COVER: "cover",
|
|
536
|
-
FILL: "fill",
|
|
537
|
-
SCALE_DOWN: "scale-down"
|
|
538
|
-
};
|
|
539
|
-
const GImage = defineComponent({
|
|
540
|
-
props: gImagePorps,
|
|
541
|
-
name: "GImage",
|
|
542
|
-
inheritAttrs: false,
|
|
543
|
-
emits: ["error", "click"],
|
|
544
|
-
setup(props, {
|
|
545
|
-
slots,
|
|
546
|
-
emit,
|
|
547
|
-
attrs
|
|
548
|
-
}) {
|
|
549
|
-
const baseClassName = getPrefixCls({
|
|
550
|
-
suffixCls: "image"
|
|
551
|
-
});
|
|
552
|
-
const hasLoadError = ref(false);
|
|
553
|
-
const loading = ref(true);
|
|
554
|
-
const imgWidth = ref(0);
|
|
555
|
-
const imgHeight = ref(0);
|
|
556
|
-
const showViewer = ref(false);
|
|
557
|
-
const container = ref(null);
|
|
558
|
-
const _scrollContainer = ref();
|
|
559
|
-
let stopScrollListener;
|
|
560
|
-
let stopWheelListener;
|
|
561
|
-
const imageWidthHeightStyle = computed(() => {
|
|
562
|
-
return {
|
|
563
|
-
width: props.width ? `${props.width}px` : void 0,
|
|
564
|
-
height: props.height ? `${props.height}px` : void 0
|
|
565
|
-
};
|
|
566
|
-
});
|
|
567
|
-
const imageStyle = computed(() => {
|
|
568
|
-
const {
|
|
569
|
-
fit
|
|
570
|
-
} = props;
|
|
571
|
-
if (!isServer && fit) {
|
|
572
|
-
return isSupportObjectFit() ? {
|
|
573
|
-
"object-fit": fit,
|
|
574
|
-
...imageWidthHeightStyle.value
|
|
575
|
-
} : {
|
|
576
|
-
...getImageStyle(fit),
|
|
577
|
-
...imageWidthHeightStyle.value
|
|
578
|
-
};
|
|
579
|
-
}
|
|
580
|
-
return imageWidthHeightStyle.value;
|
|
581
|
-
});
|
|
582
|
-
const alignCenter = computed(() => {
|
|
583
|
-
const {
|
|
584
|
-
fit
|
|
585
|
-
} = props;
|
|
586
|
-
return !isServer && !isSupportObjectFit() && fit !== ObjectFit.FILL;
|
|
587
|
-
});
|
|
588
|
-
const preview = computed(() => {
|
|
589
|
-
const {
|
|
590
|
-
previewSrcList
|
|
591
|
-
} = props;
|
|
592
|
-
return Array.isArray(previewSrcList) && previewSrcList.length > 0;
|
|
593
|
-
});
|
|
594
|
-
const imageIndex = computed(() => {
|
|
595
|
-
const {
|
|
596
|
-
src,
|
|
597
|
-
previewSrcList
|
|
598
|
-
} = props;
|
|
599
|
-
let previewIndex = 0;
|
|
600
|
-
const srcIndex = previewSrcList.indexOf(src);
|
|
601
|
-
if (srcIndex >= 0) {
|
|
602
|
-
previewIndex = srcIndex;
|
|
603
|
-
}
|
|
604
|
-
return previewIndex;
|
|
605
|
-
});
|
|
606
|
-
const getAttrs = computed(() => attrs);
|
|
607
|
-
const getImageStyle = (fit) => {
|
|
608
|
-
const imageWidth = props.width || imgWidth.value;
|
|
609
|
-
const imageHeight = props.height || imgHeight.value;
|
|
610
|
-
if (!container.value)
|
|
611
|
-
return {};
|
|
612
|
-
const {
|
|
613
|
-
clientWidth: containerWidth,
|
|
614
|
-
clientHeight: containerHeight
|
|
615
|
-
} = container.value;
|
|
616
|
-
if (!imageWidth || !imageHeight || !containerWidth || !containerHeight)
|
|
617
|
-
return {};
|
|
618
|
-
const imageAspectRatio = imageWidth / imageHeight;
|
|
619
|
-
const containerAspectRatio = containerWidth / containerHeight;
|
|
620
|
-
if (fit === ObjectFit.SCALE_DOWN) {
|
|
621
|
-
const isSmaller = imageWidth < containerWidth && imageHeight < containerHeight;
|
|
622
|
-
fit = isSmaller ? ObjectFit.NONE : ObjectFit.CONTAIN;
|
|
623
|
-
}
|
|
624
|
-
switch (fit) {
|
|
625
|
-
case ObjectFit.NONE:
|
|
626
|
-
return {
|
|
627
|
-
width: "auto",
|
|
628
|
-
height: "auto"
|
|
629
|
-
};
|
|
630
|
-
case ObjectFit.CONTAIN:
|
|
631
|
-
return imageAspectRatio < containerAspectRatio ? {
|
|
632
|
-
width: "auto"
|
|
633
|
-
} : {
|
|
634
|
-
height: "auto"
|
|
635
|
-
};
|
|
636
|
-
case ObjectFit.COVER:
|
|
637
|
-
return imageAspectRatio < containerAspectRatio ? {
|
|
638
|
-
height: "auto"
|
|
639
|
-
} : {
|
|
640
|
-
width: "auto"
|
|
641
|
-
};
|
|
642
|
-
default:
|
|
643
|
-
return {};
|
|
644
|
-
}
|
|
645
|
-
};
|
|
646
|
-
const loadImage = () => {
|
|
647
|
-
if (isServer)
|
|
648
|
-
return;
|
|
649
|
-
const attributes = getAttrs.value;
|
|
650
|
-
loading.value = true;
|
|
651
|
-
hasLoadError.value = false;
|
|
652
|
-
const img = new Image();
|
|
653
|
-
img.onload = (e) => handleLoad(e, img);
|
|
654
|
-
img.onerror = handleError;
|
|
655
|
-
Object.keys(attributes).forEach((key) => {
|
|
656
|
-
if (key.toLowerCase() === "onload")
|
|
657
|
-
return;
|
|
658
|
-
const value = attributes[key];
|
|
659
|
-
img.setAttribute(key, value);
|
|
660
|
-
});
|
|
661
|
-
img.src = props.src;
|
|
662
|
-
};
|
|
663
|
-
function handleLazyLoad() {
|
|
664
|
-
if (isInContainer(container.value, _scrollContainer.value)) {
|
|
665
|
-
loadImage();
|
|
666
|
-
removeLazyLoadListener();
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
const lazyLoadHandler = useThrottleFn(handleLazyLoad, 200);
|
|
670
|
-
const addLazyLoadListener = async () => {
|
|
671
|
-
var _a;
|
|
672
|
-
if (isServer)
|
|
673
|
-
return;
|
|
674
|
-
await nextTick();
|
|
675
|
-
const {
|
|
676
|
-
scrollContainer
|
|
677
|
-
} = props;
|
|
678
|
-
if (isHtmlElement(scrollContainer)) {
|
|
679
|
-
_scrollContainer.value = scrollContainer;
|
|
680
|
-
} else if (isString(scrollContainer) && scrollContainer !== "") {
|
|
681
|
-
_scrollContainer.value = (_a = document.querySelector(scrollContainer)) != null ? _a : void 0;
|
|
682
|
-
} else if (container.value) {
|
|
683
|
-
_scrollContainer.value = getScrollContainer(container.value);
|
|
684
|
-
}
|
|
685
|
-
if (_scrollContainer.value) {
|
|
686
|
-
stopScrollListener = useEventListener(_scrollContainer, "scroll", lazyLoadHandler);
|
|
687
|
-
setTimeout(() => handleLazyLoad(), 200);
|
|
688
|
-
}
|
|
689
|
-
};
|
|
690
|
-
const removeLazyLoadListener = () => {
|
|
691
|
-
if (isServer || !_scrollContainer.value || !lazyLoadHandler)
|
|
692
|
-
return;
|
|
693
|
-
stopScrollListener();
|
|
694
|
-
_scrollContainer.value = void 0;
|
|
695
|
-
};
|
|
696
|
-
const handleLoad = (_, img) => {
|
|
697
|
-
imgWidth.value = img.width;
|
|
698
|
-
imgHeight.value = img.height;
|
|
699
|
-
loading.value = false;
|
|
700
|
-
hasLoadError.value = false;
|
|
701
|
-
};
|
|
702
|
-
const handleError = (e) => {
|
|
703
|
-
loading.value = false;
|
|
704
|
-
hasLoadError.value = true;
|
|
705
|
-
emit("error", e);
|
|
706
|
-
};
|
|
707
|
-
const wheelHandler = (e) => {
|
|
708
|
-
if (!e.ctrlKey)
|
|
709
|
-
return;
|
|
710
|
-
if (e.deltaY < 0) {
|
|
711
|
-
e.preventDefault();
|
|
712
|
-
return false;
|
|
713
|
-
} else if (e.deltaY > 0) {
|
|
714
|
-
e.preventDefault();
|
|
715
|
-
return false;
|
|
716
|
-
}
|
|
717
|
-
};
|
|
718
|
-
const clickHandler = () => {
|
|
719
|
-
if (!preview.value || props.disablePreview) {
|
|
720
|
-
return;
|
|
721
|
-
}
|
|
722
|
-
stopWheelListener = useEventListener("wheel", wheelHandler, {
|
|
723
|
-
passive: false
|
|
724
|
-
});
|
|
725
|
-
prevOverflow = document.body.style.overflow;
|
|
726
|
-
document.body.style.overflow = "hidden";
|
|
727
|
-
showViewer.value = true;
|
|
728
|
-
};
|
|
729
|
-
const closeViewer = () => {
|
|
730
|
-
stopWheelListener == null ? void 0 : stopWheelListener();
|
|
731
|
-
document.body.style.overflow = prevOverflow;
|
|
732
|
-
showViewer.value = false;
|
|
733
|
-
};
|
|
734
|
-
watch(() => props.src, () => {
|
|
735
|
-
if (props.lazy) {
|
|
736
|
-
loading.value = true;
|
|
737
|
-
hasLoadError.value = false;
|
|
738
|
-
removeLazyLoadListener();
|
|
739
|
-
addLazyLoadListener();
|
|
740
|
-
} else {
|
|
741
|
-
loadImage();
|
|
742
|
-
}
|
|
743
|
-
});
|
|
744
|
-
onMountedOrActivated(() => {
|
|
745
|
-
if (props.lazy) {
|
|
746
|
-
addLazyLoadListener();
|
|
747
|
-
} else {
|
|
748
|
-
loadImage();
|
|
749
|
-
}
|
|
750
|
-
});
|
|
751
|
-
return () => {
|
|
752
|
-
const fallbackRender = getSlotVNode(slots, props, "fallback");
|
|
753
|
-
const placeholderRender = getSlotVNode(slots, props, "placeholder");
|
|
754
|
-
return createVNode(Fragment, null, [createVNode("div", {
|
|
755
|
-
"class": {
|
|
756
|
-
[`${baseClassName}`]: true,
|
|
757
|
-
[`${getAttrs.value.class}`]: getAttrs.value.class
|
|
758
|
-
},
|
|
759
|
-
"ref": (e) => container.value = e,
|
|
760
|
-
"style": {
|
|
761
|
-
...getAttrs.value.style || {},
|
|
762
|
-
display: props.lazy ? "block" : void 0
|
|
763
|
-
},
|
|
764
|
-
"onClick": () => {
|
|
765
|
-
emit("click");
|
|
766
|
-
}
|
|
767
|
-
}, [loading.value ? placeholderRender || createVNode("div", {
|
|
768
|
-
"class": `${baseClassName}-placeholder`
|
|
769
|
-
}, null) : hasLoadError.value ? fallbackRender || createVNode("div", {
|
|
770
|
-
"class": `${baseClassName}-error`
|
|
771
|
-
}, [createTextVNode("\u52A0\u8F7D\u5931\u8D25")]) : createVNode("img", mergeProps({
|
|
772
|
-
"class": {
|
|
773
|
-
[`${baseClassName}-inner`]: true,
|
|
774
|
-
[`${baseClassName}-inner-center`]: alignCenter.value,
|
|
775
|
-
[`${baseClassName}-preview`]: preview.value
|
|
776
|
-
}
|
|
777
|
-
}, getAttrs.value, {
|
|
778
|
-
"src": props.src,
|
|
779
|
-
"style": imageStyle.value,
|
|
780
|
-
"onClick": () => clickHandler()
|
|
781
|
-
}), null), createVNode(Teleport, {
|
|
782
|
-
"to": "body",
|
|
783
|
-
"disabled": !props.appendToBody
|
|
784
|
-
}, {
|
|
785
|
-
default: () => [preview.value && showViewer.value && createVNode(GImageViewer, {
|
|
786
|
-
"zIndex": props.zIndex,
|
|
787
|
-
"initialIndex": imageIndex.value,
|
|
788
|
-
"urlList": props.previewSrcList,
|
|
789
|
-
"onHideOnClickModal": props.hideOnClickModal,
|
|
790
|
-
"onClose": () => closeViewer()
|
|
791
|
-
}, null)]
|
|
792
|
-
})])]);
|
|
793
|
-
};
|
|
794
|
-
}
|
|
795
|
-
});
|
|
796
|
-
GImage.isWImage = true;
|
|
797
|
-
GImage.install = (app) => {
|
|
798
|
-
app.component(GImage.name, GImage);
|
|
799
|
-
return app;
|
|
800
|
-
};
|
|
801
|
-
export { GImage, GImageViewer as ImageViewer, gImageViewerGroup as ImageViewerGroup, GImage as default };
|