@koi-br/ocr-web-sdk 1.0.39 → 1.0.41
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/{index-CSqGQ8S7.mjs → index-B1W65EDF.mjs} +7954 -7889
- package/dist/{index-B1uZCXKP.js → index-OEZMBeqD.js} +80 -80
- package/dist/index.cjs.js +2 -2
- package/dist/index.esm.js +2 -2
- package/dist/{tiff.min-CqXFy9Hv.mjs → tiff.min-D_NeHpVc.mjs} +1 -1
- package/dist/{tiff.min-D3W7y7O-.js → tiff.min-qFtp92t-.js} +1 -1
- package/package.json +1 -1
- package/preview/ImagePreview.vue +143 -21
package/package.json
CHANGED
package/preview/ImagePreview.vue
CHANGED
|
@@ -120,6 +120,13 @@
|
|
|
120
120
|
<div v-if="isCalculatingAutoFit && autoFitWidth" class="auto-fit-loading">
|
|
121
121
|
<div class="loading-spinner"></div>
|
|
122
122
|
<div class="loading-text">加载中...</div>
|
|
123
|
+
<!-- 调试信息(开发环境显示) -->
|
|
124
|
+
<div style="font-size: 12px; color: #999; margin-top: 8px; text-align: center;">
|
|
125
|
+
isImageReady: {{ isImageReady }},
|
|
126
|
+
isCalculatingAutoFit: {{ isCalculatingAutoFit }},
|
|
127
|
+
autoFitWidth: {{ autoFitWidth }},
|
|
128
|
+
scale: {{ scale }}
|
|
129
|
+
</div>
|
|
123
130
|
</div>
|
|
124
131
|
|
|
125
132
|
<div
|
|
@@ -407,13 +414,24 @@ const isImageReady = ref(false); // 标记图片是否已准备好显示(自
|
|
|
407
414
|
watch(
|
|
408
415
|
() => imageUrls.value,
|
|
409
416
|
(newUrls, oldUrls) => {
|
|
417
|
+
console.log('[ImagePreview] imageUrls changed:', {
|
|
418
|
+
newUrls: newUrls?.length,
|
|
419
|
+
oldUrls: oldUrls?.length,
|
|
420
|
+
autoFitWidth: props.autoFitWidth,
|
|
421
|
+
isImageReady: isImageReady.value,
|
|
422
|
+
isCalculatingAutoFit: isCalculatingAutoFit.value,
|
|
423
|
+
});
|
|
424
|
+
|
|
410
425
|
// 如果有新的图片URL,且启用自适应宽度,立即隐藏图片
|
|
411
426
|
if (newUrls && newUrls.length > 0 && props.autoFitWidth) {
|
|
427
|
+
console.log('[ImagePreview] 设置图片隐藏,等待自适应宽度计算');
|
|
412
428
|
isImageReady.value = false;
|
|
413
429
|
isCalculatingAutoFit.value = true;
|
|
414
430
|
} else if (!props.autoFitWidth) {
|
|
415
431
|
// 如果没有启用自适应宽度,立即显示
|
|
432
|
+
console.log('[ImagePreview] 未启用自适应宽度,立即显示图片');
|
|
416
433
|
isImageReady.value = true;
|
|
434
|
+
isCalculatingAutoFit.value = false;
|
|
417
435
|
}
|
|
418
436
|
},
|
|
419
437
|
{ immediate: true }
|
|
@@ -426,7 +444,10 @@ const isScrollPaging = ref(false); // 标记是否正在进行滚动翻页
|
|
|
426
444
|
|
|
427
445
|
// ResizeObserver 相关
|
|
428
446
|
let resizeObserver: ResizeObserver | null = null;
|
|
429
|
-
let resizeTimer: any = null; //
|
|
447
|
+
let resizeTimer: any = null; // handleContainerResize 内部的定时器
|
|
448
|
+
let resizeDebounceTimer: any = null; // ResizeObserver 的防抖定时器
|
|
449
|
+
let isResizing = false; // 标记是否正在处理 resize
|
|
450
|
+
let lastContainerWidth = 0; // 记录上次容器宽度,用于判断是否真的变化了
|
|
430
451
|
|
|
431
452
|
// 图片和容器引用
|
|
432
453
|
const containerRef = ref<HTMLElement>();
|
|
@@ -916,13 +937,25 @@ const original = () => {
|
|
|
916
937
|
|
|
917
938
|
// 计算自适应宽度的缩放比例
|
|
918
939
|
const calculateAutoFitScale = () => {
|
|
940
|
+
console.log('[ImagePreview] calculateAutoFitScale 开始:', {
|
|
941
|
+
autoFitWidth: props.autoFitWidth,
|
|
942
|
+
hasContainerRef: !!containerRef.value,
|
|
943
|
+
containerRect: containerRef.value?.getBoundingClientRect(),
|
|
944
|
+
firstPageSize: imageSizes.get(1),
|
|
945
|
+
rotation: rotation.value,
|
|
946
|
+
minScale: props.minScale,
|
|
947
|
+
maxScale: props.maxScale,
|
|
948
|
+
});
|
|
949
|
+
|
|
919
950
|
if (!props.autoFitWidth || !containerRef.value) {
|
|
951
|
+
console.log('[ImagePreview] calculateAutoFitScale 返回 1 (条件不满足)');
|
|
920
952
|
return 1;
|
|
921
953
|
}
|
|
922
954
|
|
|
923
955
|
// 使用第一页的图片尺寸作为基准(所有页面使用相同的缩放比例)
|
|
924
956
|
const firstPageSize = imageSizes.get(1);
|
|
925
957
|
if (!firstPageSize || firstPageSize.width === 0) {
|
|
958
|
+
console.log('[ImagePreview] calculateAutoFitScale 返回 1 (第一页尺寸无效)', firstPageSize);
|
|
926
959
|
return 1;
|
|
927
960
|
}
|
|
928
961
|
|
|
@@ -932,6 +965,7 @@ const calculateAutoFitScale = () => {
|
|
|
932
965
|
const containerWidth = containerRect.width - 4;
|
|
933
966
|
|
|
934
967
|
if (containerWidth <= 0) {
|
|
968
|
+
console.log('[ImagePreview] calculateAutoFitScale 返回 1 (容器宽度无效)', containerWidth);
|
|
935
969
|
return 1;
|
|
936
970
|
}
|
|
937
971
|
|
|
@@ -942,20 +976,38 @@ const calculateAutoFitScale = () => {
|
|
|
942
976
|
const imageWidth = isRotated ? firstPageSize.height : firstPageSize.width;
|
|
943
977
|
|
|
944
978
|
if (imageWidth <= 0) {
|
|
979
|
+
console.log('[ImagePreview] calculateAutoFitScale 返回 1 (图片宽度无效)', imageWidth);
|
|
945
980
|
return 1;
|
|
946
981
|
}
|
|
947
982
|
|
|
948
983
|
// 计算缩放比例,使图片宽度完全适应容器宽度
|
|
949
984
|
const calculatedScale = containerWidth / imageWidth;
|
|
985
|
+
const finalScale = Math.max(props.minScale, Math.min(props.maxScale, calculatedScale));
|
|
986
|
+
|
|
987
|
+
console.log('[ImagePreview] calculateAutoFitScale 计算结果:', {
|
|
988
|
+
containerWidth,
|
|
989
|
+
imageWidth,
|
|
990
|
+
calculatedScale,
|
|
991
|
+
finalScale,
|
|
992
|
+
});
|
|
950
993
|
|
|
951
994
|
// 确保缩放比例在允许的范围内
|
|
952
|
-
return
|
|
995
|
+
return finalScale;
|
|
953
996
|
};
|
|
954
997
|
|
|
955
998
|
// 图片加载完成处理
|
|
956
999
|
const onImageLoad = (event: Event, pageNum: number) => {
|
|
957
1000
|
const img = event.target as HTMLImageElement;
|
|
958
1001
|
|
|
1002
|
+
console.log('[ImagePreview] 图片加载完成:', {
|
|
1003
|
+
pageNum,
|
|
1004
|
+
naturalWidth: img.naturalWidth,
|
|
1005
|
+
naturalHeight: img.naturalHeight,
|
|
1006
|
+
autoFitWidth: props.autoFitWidth,
|
|
1007
|
+
isImageReady: isImageReady.value,
|
|
1008
|
+
isCalculatingAutoFit: isCalculatingAutoFit.value,
|
|
1009
|
+
});
|
|
1010
|
+
|
|
959
1011
|
// 存储该页的图片尺寸
|
|
960
1012
|
imageSizes.set(pageNum, {
|
|
961
1013
|
width: img.naturalWidth,
|
|
@@ -964,6 +1016,7 @@ const onImageLoad = (event: Event, pageNum: number) => {
|
|
|
964
1016
|
|
|
965
1017
|
// 如果是第一页且启用自适应宽度,计算并设置初始缩放比例
|
|
966
1018
|
if (pageNum === 1 && props.autoFitWidth) {
|
|
1019
|
+
console.log('[ImagePreview] 第一页加载完成,开始计算自适应宽度');
|
|
967
1020
|
// 重置用户缩放标记
|
|
968
1021
|
isUserZooming.value = false;
|
|
969
1022
|
|
|
@@ -985,21 +1038,38 @@ const onImageLoad = (event: Event, pageNum: number) => {
|
|
|
985
1038
|
// 添加小延迟确保容器完全渲染
|
|
986
1039
|
setTimeout(() => {
|
|
987
1040
|
try {
|
|
1041
|
+
console.log('[ImagePreview] onImageLoad: 开始计算自适应宽度...');
|
|
988
1042
|
const autoScale = calculateAutoFitScale();
|
|
1043
|
+
console.log('[ImagePreview] onImageLoad: 自适应宽度计算结果:', {
|
|
1044
|
+
autoScale,
|
|
1045
|
+
containerRef: !!containerRef.value,
|
|
1046
|
+
containerWidth: containerRef.value?.getBoundingClientRect()?.width,
|
|
1047
|
+
firstPageSize: imageSizes.get(1),
|
|
1048
|
+
});
|
|
1049
|
+
|
|
989
1050
|
if (autoScale > 0) {
|
|
990
1051
|
scale.value = autoScale;
|
|
991
1052
|
initialAutoFitScale.value = autoScale; // 记录初始自适应缩放比例
|
|
1053
|
+
// 记录当前容器宽度,用于后续 resize 检查
|
|
1054
|
+
if (containerRef.value) {
|
|
1055
|
+
lastContainerWidth = containerRef.value.getBoundingClientRect().width;
|
|
1056
|
+
}
|
|
1057
|
+
console.log('[ImagePreview] onImageLoad: 缩放比例已设置:', autoScale);
|
|
1058
|
+
} else {
|
|
1059
|
+
console.warn('[ImagePreview] onImageLoad: 计算出的缩放比例无效:', autoScale);
|
|
992
1060
|
}
|
|
993
1061
|
} catch (error) {
|
|
994
|
-
console.
|
|
1062
|
+
console.error('[ImagePreview] onImageLoad: 计算自适应宽度失败:', error);
|
|
995
1063
|
} finally {
|
|
996
1064
|
// 清除超时保护
|
|
997
1065
|
clearTimeout(timeoutId);
|
|
1066
|
+
console.log('[ImagePreview] onImageLoad: 更新状态: isCalculatingAutoFit = false, isImageReady = true');
|
|
998
1067
|
// 无论计算结果如何,都要更新状态,避免一直显示 loading
|
|
999
1068
|
isCalculatingAutoFit.value = false;
|
|
1000
1069
|
// 使用 requestAnimationFrame 确保在下一帧显示,避免闪烁
|
|
1001
1070
|
requestAnimationFrame(() => {
|
|
1002
1071
|
isImageReady.value = true;
|
|
1072
|
+
console.log('[ImagePreview] onImageLoad: 图片已准备好显示');
|
|
1003
1073
|
});
|
|
1004
1074
|
}
|
|
1005
1075
|
}, 100); // 增加延迟,确保所有图片都已加载
|
|
@@ -2321,6 +2391,33 @@ const handleContainerResize = () => {
|
|
|
2321
2391
|
return;
|
|
2322
2392
|
}
|
|
2323
2393
|
|
|
2394
|
+
// 如果正在计算中或正在处理 resize,跳过(避免重复计算)
|
|
2395
|
+
if (isCalculatingAutoFit.value || isResizing) {
|
|
2396
|
+
return;
|
|
2397
|
+
}
|
|
2398
|
+
|
|
2399
|
+
// 检查容器尺寸是否真的变化了(避免无意义的重复计算)
|
|
2400
|
+
if (containerRef.value) {
|
|
2401
|
+
const currentWidth = containerRef.value.getBoundingClientRect().width;
|
|
2402
|
+
// 如果宽度变化小于 5px,认为是渲染抖动,不处理
|
|
2403
|
+
if (Math.abs(currentWidth - lastContainerWidth) < 5) {
|
|
2404
|
+
return;
|
|
2405
|
+
}
|
|
2406
|
+
lastContainerWidth = currentWidth;
|
|
2407
|
+
}
|
|
2408
|
+
|
|
2409
|
+
console.log('[ImagePreview] handleContainerResize 被调用:', {
|
|
2410
|
+
autoFitWidth: props.autoFitWidth,
|
|
2411
|
+
isUserZooming: isUserZooming.value,
|
|
2412
|
+
isImageReady: isImageReady.value,
|
|
2413
|
+
isCalculatingAutoFit: isCalculatingAutoFit.value,
|
|
2414
|
+
hasFirstPageSize: !!imageSizes.get(1),
|
|
2415
|
+
containerWidth: containerRef.value?.getBoundingClientRect()?.width,
|
|
2416
|
+
});
|
|
2417
|
+
|
|
2418
|
+
// 标记正在处理 resize
|
|
2419
|
+
isResizing = true;
|
|
2420
|
+
|
|
2324
2421
|
// 清除之前的定时器
|
|
2325
2422
|
if (resizeTimer) {
|
|
2326
2423
|
clearTimeout(resizeTimer);
|
|
@@ -2328,31 +2425,46 @@ const handleContainerResize = () => {
|
|
|
2328
2425
|
}
|
|
2329
2426
|
|
|
2330
2427
|
// 隐藏图片,显示 loading
|
|
2428
|
+
console.log('[ImagePreview] handleContainerResize: 开始重新计算');
|
|
2331
2429
|
isImageReady.value = false;
|
|
2332
2430
|
isCalculatingAutoFit.value = true;
|
|
2333
2431
|
|
|
2334
2432
|
// 立即计算并应用新的缩放比例,避免过渡期间露出底色
|
|
2335
2433
|
// 使用 requestAnimationFrame 确保在浏览器重绘前更新
|
|
2336
2434
|
requestAnimationFrame(() => {
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2435
|
+
try {
|
|
2436
|
+
console.log('[ImagePreview] handleContainerResize: 开始计算自适应宽度...');
|
|
2437
|
+
const newScale = calculateAutoFitScale();
|
|
2438
|
+
console.log('[ImagePreview] handleContainerResize: 计算结果:', newScale);
|
|
2439
|
+
|
|
2440
|
+
if (newScale > 0) {
|
|
2441
|
+
// 即使变化很小也立即更新,确保过渡期间图片始终填满容器
|
|
2442
|
+
scale.value = newScale;
|
|
2443
|
+
initialAutoFitScale.value = newScale;
|
|
2444
|
+
}
|
|
2445
|
+
} catch (error) {
|
|
2446
|
+
console.error('[ImagePreview] handleContainerResize: 计算失败:', error);
|
|
2342
2447
|
}
|
|
2343
2448
|
|
|
2344
2449
|
// 在过渡动画完成后再次检查,确保最终状态正确(处理过渡动画期间的连续变化)
|
|
2345
2450
|
resizeTimer = setTimeout(() => {
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
scale.value
|
|
2349
|
-
|
|
2451
|
+
try {
|
|
2452
|
+
const finalScale = calculateAutoFitScale();
|
|
2453
|
+
if (finalScale > 0 && Math.abs(finalScale - scale.value) > 0.01) {
|
|
2454
|
+
scale.value = finalScale;
|
|
2455
|
+
initialAutoFitScale.value = finalScale;
|
|
2456
|
+
}
|
|
2457
|
+
} catch (error) {
|
|
2458
|
+
console.error('[ImagePreview] handleContainerResize: 最终计算失败:', error);
|
|
2459
|
+
} finally {
|
|
2460
|
+
// 计算完成后,显示图片并隐藏 loading
|
|
2461
|
+
console.log('[ImagePreview] handleContainerResize: 更新状态完成');
|
|
2462
|
+
isCalculatingAutoFit.value = false;
|
|
2463
|
+
isResizing = false; // 重置标记
|
|
2464
|
+
requestAnimationFrame(() => {
|
|
2465
|
+
isImageReady.value = true;
|
|
2466
|
+
});
|
|
2350
2467
|
}
|
|
2351
|
-
// 计算完成后,显示图片并隐藏 loading
|
|
2352
|
-
isCalculatingAutoFit.value = false;
|
|
2353
|
-
requestAnimationFrame(() => {
|
|
2354
|
-
isImageReady.value = true;
|
|
2355
|
-
});
|
|
2356
2468
|
}, 350); // 350ms 延迟,略大于过渡动画时间(300ms),确保过渡完成后稳定
|
|
2357
2469
|
});
|
|
2358
2470
|
};
|
|
@@ -2410,11 +2522,17 @@ onMounted(() => {
|
|
|
2410
2522
|
nextTick(() => {
|
|
2411
2523
|
if (containerRef.value && typeof ResizeObserver !== 'undefined') {
|
|
2412
2524
|
resizeObserver = new ResizeObserver((entries) => {
|
|
2413
|
-
//
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
handleContainerResize();
|
|
2525
|
+
// 使用防抖,避免频繁触发
|
|
2526
|
+
if (resizeDebounceTimer) {
|
|
2527
|
+
clearTimeout(resizeDebounceTimer);
|
|
2417
2528
|
}
|
|
2529
|
+
resizeDebounceTimer = setTimeout(() => {
|
|
2530
|
+
// 使用 entries 参数立即获取新尺寸,避免延迟
|
|
2531
|
+
for (const entry of entries) {
|
|
2532
|
+
// 立即响应尺寸变化,避免过渡期间露出底色
|
|
2533
|
+
handleContainerResize();
|
|
2534
|
+
}
|
|
2535
|
+
}, 100); // 100ms 防抖,避免频繁触发
|
|
2418
2536
|
});
|
|
2419
2537
|
resizeObserver.observe(containerRef.value);
|
|
2420
2538
|
} else {
|
|
@@ -2440,6 +2558,10 @@ onBeforeUnmount(() => {
|
|
|
2440
2558
|
clearTimeout(resizeTimer);
|
|
2441
2559
|
resizeTimer = null;
|
|
2442
2560
|
}
|
|
2561
|
+
if (resizeDebounceTimer) {
|
|
2562
|
+
clearTimeout(resizeDebounceTimer);
|
|
2563
|
+
resizeDebounceTimer = null;
|
|
2564
|
+
}
|
|
2443
2565
|
if (resizeObserver) {
|
|
2444
2566
|
resizeObserver.disconnect();
|
|
2445
2567
|
resizeObserver = null;
|