@eternalheart/vue-file-preview 1.3.13 → 1.3.14

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.
Files changed (49) hide show
  1. package/lib/FilePreviewContent.vue.d.ts +3 -0
  2. package/lib/FilePreviewContent.vue.d.ts.map +1 -1
  3. package/lib/FilePreviewEmbed.vue.d.ts +5 -0
  4. package/lib/FilePreviewEmbed.vue.d.ts.map +1 -1
  5. package/lib/FilePreviewModal.vue.d.ts.map +1 -1
  6. package/lib/chunks/{index-BHi1WRQZ.mjs → index-5hGtGeD4.mjs} +2 -2
  7. package/lib/chunks/{index-BHi1WRQZ.mjs.map → index-5hGtGeD4.mjs.map} +1 -1
  8. package/lib/chunks/{index-DBw8tvyb.mjs → index-B-f41wjl.mjs} +2 -2
  9. package/lib/chunks/{index-DBw8tvyb.mjs.map → index-B-f41wjl.mjs.map} +1 -1
  10. package/lib/chunks/{index-CYt6tpQC.mjs → index-BI32fnT-.mjs} +2 -2
  11. package/lib/chunks/{index-CYt6tpQC.mjs.map → index-BI32fnT-.mjs.map} +1 -1
  12. package/lib/chunks/{index-DTtHrdBl.mjs → index-BgdBpGYv.mjs} +2 -2
  13. package/lib/chunks/{index-DTtHrdBl.mjs.map → index-BgdBpGYv.mjs.map} +1 -1
  14. package/lib/chunks/{index-DT9dPz8I.mjs → index-BkMYaea2.mjs} +2 -2
  15. package/lib/chunks/{index-DT9dPz8I.mjs.map → index-BkMYaea2.mjs.map} +1 -1
  16. package/lib/chunks/{index-BTW1xwB9.mjs → index-BlD2p_KC.mjs} +2 -2
  17. package/lib/chunks/{index-BTW1xwB9.mjs.map → index-BlD2p_KC.mjs.map} +1 -1
  18. package/lib/chunks/{index-B2lqsdp7.mjs → index-Bz9nKaz5.mjs} +2 -2
  19. package/lib/chunks/{index-B2lqsdp7.mjs.map → index-Bz9nKaz5.mjs.map} +1 -1
  20. package/lib/chunks/{index-GGGDPwxX.mjs → index-C0OWrmU8.mjs} +2 -2
  21. package/lib/chunks/{index-GGGDPwxX.mjs.map → index-C0OWrmU8.mjs.map} +1 -1
  22. package/lib/chunks/{index-Oxwizt6-.mjs → index-CFaWV6cC.mjs} +87 -82
  23. package/lib/chunks/index-CFaWV6cC.mjs.map +1 -0
  24. package/lib/chunks/{index-BvegaxQF.mjs → index-CJ86PaaF.mjs} +2 -2
  25. package/lib/chunks/{index-BvegaxQF.mjs.map → index-CJ86PaaF.mjs.map} +1 -1
  26. package/lib/chunks/{index-DIe0vHlt.mjs → index-CMKtCKpo.mjs} +2 -2
  27. package/lib/chunks/{index-DIe0vHlt.mjs.map → index-CMKtCKpo.mjs.map} +1 -1
  28. package/lib/chunks/{index-Cjnw238n.mjs → index-CUA_z4GJ.mjs} +2 -2
  29. package/lib/chunks/{index-Cjnw238n.mjs.map → index-CUA_z4GJ.mjs.map} +1 -1
  30. package/lib/chunks/{index-CyrFxdIJ.mjs → index-Cr0Z36a0.mjs} +3 -3
  31. package/lib/chunks/{index-CyrFxdIJ.mjs.map → index-Cr0Z36a0.mjs.map} +1 -1
  32. package/lib/chunks/{index-Ctd0JQ6K.mjs → index-DVJfd09T.mjs} +2 -2
  33. package/lib/chunks/{index-Ctd0JQ6K.mjs.map → index-DVJfd09T.mjs.map} +1 -1
  34. package/lib/chunks/{index-DyipSoKh.mjs → index-DYrRDrZL.mjs} +2 -2
  35. package/lib/chunks/{index-DyipSoKh.mjs.map → index-DYrRDrZL.mjs.map} +1 -1
  36. package/lib/chunks/{index-Zwl5J-Uw.mjs → index-GcvjVFMf.mjs} +2 -2
  37. package/lib/chunks/{index-Zwl5J-Uw.mjs.map → index-GcvjVFMf.mjs.map} +1 -1
  38. package/lib/chunks/{index-DX_NBPzS.mjs → index-P8naV3DU.mjs} +2 -2
  39. package/lib/chunks/{index-DX_NBPzS.mjs.map → index-P8naV3DU.mjs.map} +1 -1
  40. package/lib/chunks/{index-Dw1U4YqT.mjs → index-VTsO_yR7.mjs} +2 -2
  41. package/lib/chunks/{index-Dw1U4YqT.mjs.map → index-VTsO_yR7.mjs.map} +1 -1
  42. package/lib/chunks/{index-DEoR7aDN.mjs → index-dG-p4BPD.mjs} +2 -2
  43. package/lib/chunks/{index-DEoR7aDN.mjs.map → index-dG-p4BPD.mjs.map} +1 -1
  44. package/lib/index.cjs +20 -20
  45. package/lib/index.cjs.map +1 -1
  46. package/lib/index.css +1 -1
  47. package/lib/index.mjs +1 -1
  48. package/package.json +1 -1
  49. package/lib/chunks/index-Oxwizt6-.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index-DT9dPz8I.mjs","sources":["../../src/renderers/Image/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, watch, onMounted, onBeforeUnmount, computed } from 'vue';\nimport { Loader2 } from 'lucide-vue-next';\nimport { formatFileSize, detectImageFormat, getLoaderForMimeType } from '@eternalheart/file-preview-core';\nimport type { PreviewFile } from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../composables/useTranslator';\nimport RendererError from '../RendererError.vue';\n\nconst props = defineProps<{\n url: string;\n zoom: number;\n rotation: number;\n resetKey?: number;\n fileSize?: number;\n file?: PreviewFile | File;\n}>();\n\nconst emit = defineEmits<{\n (e: 'zoomChange', zoom: number): void;\n (e: 'naturalWidthChange', width: number): void;\n (e: 'naturalHeightChange', height: number): void;\n}>();\n\nconst { t } = useTranslator();\n\nconst loaded = ref(false);\nconst error = ref<string | null>(null);\nconst decoding = ref(false);\nconst decodeProgress = ref(0);\nconst decodeError = ref<string | null>(null);\nconst imageSrc = ref<string>('');\nconst currentPage = ref(1);\nconst totalPages = ref(1);\nconst isRawThumbnail = ref(false);\nconst position = ref({ x: 0, y: 0 });\nconst isDragging = ref(false);\nlet dragStart = { x: 0, y: 0 };\nconst internalZoom = ref(1);\nconst naturalSize = ref({ width: 0, height: 0 });\n\nconst imgRef = ref<HTMLImageElement | null>(null);\nconst containerRef = ref<HTMLDivElement | null>(null);\nlet blobUrl: string | null = null;\nlet fileBlobCache: Blob | null = null;\nlet loaderCache: any = null;\nconst pageCache = new Map<number, string>();\n\nlet isTouchDevice = false;\nlet touchStartDistance = 0;\nlet touchStartZoom = 1;\nlet touchStartPos = { x: 0, y: 0 };\nlet lastTapTime = 0;\n\n// 解码逻辑\nwatch(\n () => [props.url, props.file] as const,\n async () => {\n // 重置状态:清空 src 以避免上一张图片的 onLoad/onError 误触发到新文件\n imageSrc.value = '';\n loaded.value = false;\n error.value = null;\n decoding.value = false;\n decodeError.value = null;\n decodeProgress.value = 0;\n position.value = { x: 0, y: 0 };\n internalZoom.value = 1;\n currentPage.value = 1;\n totalPages.value = 1;\n isRawThumbnail.value = false;\n\n // 清理旧的 blob URL 与缓存\n if (blobUrl) {\n URL.revokeObjectURL(blobUrl);\n blobUrl = null;\n }\n pageCache.forEach((url) => URL.revokeObjectURL(url));\n pageCache.clear();\n fileBlobCache = null;\n loaderCache = null;\n\n // 如果没有 file 对象,直接使用 url\n if (!props.file) {\n imageSrc.value = props.url;\n return;\n }\n\n try {\n // 检测图片格式\n const mimeType = await detectImageFormat(props.file);\n const loader = await getLoaderForMimeType(mimeType);\n\n // 如果不需要解码,直接使用原 URL\n if (!loader || !(await loader.needsDecode(mimeType))) {\n imageSrc.value = props.url;\n return;\n }\n\n // 需要解码\n decoding.value = true;\n\n // 获取文件 Blob\n let fileBlob: Blob;\n if (props.file instanceof Blob) {\n fileBlob = props.file;\n } else {\n const response = await fetch(props.url);\n if (!response.ok) throw new Error('Failed to fetch file');\n fileBlob = await response.blob();\n }\n\n // 缓存 Blob 与 loader\n fileBlobCache = fileBlob;\n loaderCache = loader;\n\n // 标记 RAW 缩略图模式\n const isRaw = mimeType.startsWith('image/x-');\n if (isRaw) {\n isRawThumbnail.value = true;\n }\n\n // 获取元数据(用于检测多页 TIFF)\n if (loader.getMetadata) {\n try {\n const metadata = await loader.getMetadata(fileBlob);\n if (metadata.pageCount && metadata.pageCount > 1) {\n totalPages.value = metadata.pageCount;\n }\n } catch {\n // 忽略元数据获取失败\n }\n }\n\n // 调用 loader 解码(第 1 页 / 缩略图模式)\n const decodedBlob = await loader.decode(fileBlob, {\n page: 1,\n fullQuality: false,\n onProgress: (percent: number) => {\n decodeProgress.value = percent;\n },\n });\n\n // 生成 blob URL\n const url = typeof decodedBlob === 'string'\n ? decodedBlob\n : URL.createObjectURL(decodedBlob);\n\n blobUrl = url;\n pageCache.set(1, url);\n imageSrc.value = url;\n decoding.value = false;\n } catch (err: any) {\n decodeError.value = err?.message || '解码失败';\n decoding.value = false;\n }\n },\n { immediate: true }\n);\n\n// 多页 TIFF 翻页\nconst handlePageChange = async (page: number) => {\n if (!fileBlobCache || !loaderCache) return;\n if (page < 1 || page > totalPages.value) return;\n\n // 命中缓存:直接切换\n const cached = pageCache.get(page);\n if (cached) {\n currentPage.value = page;\n imageSrc.value = cached;\n return;\n }\n\n // 解码新页面\n decoding.value = true;\n try {\n const decodedBlob = await loaderCache.decode(fileBlobCache, { page });\n const url = typeof decodedBlob === 'string'\n ? decodedBlob\n : URL.createObjectURL(decodedBlob);\n\n // LRU:缓存超过 10 页时删除最早的\n if (pageCache.size >= 10) {\n const firstKey = pageCache.keys().next().value;\n if (firstKey !== undefined) {\n const oldUrl = pageCache.get(firstKey);\n if (oldUrl) URL.revokeObjectURL(oldUrl);\n pageCache.delete(firstKey);\n }\n }\n\n pageCache.set(page, url);\n currentPage.value = page;\n imageSrc.value = url;\n decoding.value = false;\n } catch (err: any) {\n decodeError.value = err?.message || '翻页解码失败';\n decoding.value = false;\n }\n};\n\n// Cleanup on unmount\nonBeforeUnmount(() => {\n if (blobUrl) {\n URL.revokeObjectURL(blobUrl);\n }\n pageCache.forEach((url) => URL.revokeObjectURL(url));\n pageCache.clear();\n const container = containerRef.value;\n if (container) {\n container.removeEventListener('wheel', handleWheelNative);\n }\n});\n\nwatch(\n () => props.zoom,\n (z) => {\n internalZoom.value = z;\n }\n);\n\nwatch(\n () => props.resetKey,\n () => {\n position.value = { x: 0, y: 0 };\n }\n);\n\nconst clampPosition = (pos: { x: number; y: number }, currentZoom: number) => {\n const container = containerRef.value;\n if (!container || naturalSize.value.width === 0) return pos;\n\n const containerW = container.clientWidth;\n const containerH = container.clientHeight;\n const imgW = naturalSize.value.width * currentZoom;\n const imgH = naturalSize.value.height * currentZoom;\n\n const margin = Math.min(80, containerW * 0.15, containerH * 0.15);\n const rangeX = (containerW + imgW) / 2 - margin;\n const rangeY = (containerH + imgH) / 2 - margin;\n\n return {\n x: rangeX > 0 ? Math.max(-rangeX, Math.min(rangeX, pos.x)) : 0,\n y: rangeY > 0 ? Math.max(-rangeY, Math.min(rangeY, pos.y)) : 0,\n };\n};\n\nconst handleLoad = (e: Event) => {\n loaded.value = true;\n const img = e.currentTarget as HTMLImageElement;\n naturalSize.value = { width: img.naturalWidth, height: img.naturalHeight };\n emit('naturalWidthChange', img.naturalWidth);\n emit('naturalHeightChange', img.naturalHeight);\n};\n\nconst handleError = () => {\n error.value = t.value('image.load_failed');\n loaded.value = true;\n};\n\nconst handleDoubleClick = () => {\n position.value = { x: 0, y: 0 };\n internalZoom.value = 1;\n emit('zoomChange', 1);\n};\n\n// 鼠标滚轮缩放\nconst handleWheelNative = (e: WheelEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const container = containerRef.value;\n if (!container) return;\n\n const rect = container.getBoundingClientRect();\n const mouseX = e.clientX - rect.left - rect.width / 2;\n const mouseY = e.clientY - rect.top - rect.height / 2;\n\n const delta = e.deltaY > 0 ? -0.05 : 0.05;\n const prev = internalZoom.value;\n const newZoom = Math.max(0.01, Math.min(10, prev + delta));\n const scale = newZoom / prev;\n\n position.value = clampPosition(\n {\n x: mouseX - scale * (mouseX - position.value.x),\n y: mouseY - scale * (mouseY - position.value.y),\n },\n newZoom\n );\n\n internalZoom.value = newZoom;\n emit('zoomChange', newZoom);\n};\n\nonMounted(() => {\n const container = containerRef.value;\n if (container) {\n container.addEventListener('wheel', handleWheelNative, { passive: false });\n container.addEventListener('touchstart', handleTouchStart, { passive: false });\n container.addEventListener('touchmove', handleTouchMove, { passive: false });\n container.addEventListener('touchend', handleTouchEnd);\n container.addEventListener('touchcancel', handleTouchEnd);\n }\n});\n\nonBeforeUnmount(() => {\n const container = containerRef.value;\n if (container) {\n container.removeEventListener('wheel', handleWheelNative);\n container.removeEventListener('touchstart', handleTouchStart);\n container.removeEventListener('touchmove', handleTouchMove);\n container.removeEventListener('touchend', handleTouchEnd);\n container.removeEventListener('touchcancel', handleTouchEnd);\n }\n});\n\nconst handleMouseDown = (e: MouseEvent) => {\n if (isTouchDevice) return;\n if (e.button !== 0) return;\n isDragging.value = true;\n dragStart = {\n x: e.clientX - position.value.x,\n y: e.clientY - position.value.y,\n };\n};\n\nconst handleMouseMove = (e: MouseEvent) => {\n if (isTouchDevice) return;\n if (!isDragging.value) return;\n position.value = clampPosition(\n {\n x: e.clientX - dragStart.x,\n y: e.clientY - dragStart.y,\n },\n internalZoom.value\n );\n};\n\nconst handleMouseUp = () => {\n if (isTouchDevice) return;\n isDragging.value = false;\n};\n\n// 触屏事件处理\nconst handleTouchStart = (e: TouchEvent) => {\n isTouchDevice = true;\n e.preventDefault();\n\n const touches = e.touches;\n if (touches.length === 1) {\n // 单指拖拽\n isDragging.value = true;\n dragStart = {\n x: touches[0].clientX - position.value.x,\n y: touches[0].clientY - position.value.y,\n };\n\n // 双击检测\n const now = Date.now();\n if (now - lastTapTime < 300) {\n // 双击复原:居中 + 缩放100%\n position.value = { x: 0, y: 0 };\n internalZoom.value = 1;\n emit('zoomChange', 1);\n }\n lastTapTime = now;\n } else if (touches.length === 2) {\n // 双指缩放初始化\n isDragging.value = false;\n const distance = Math.hypot(\n touches[1].clientX - touches[0].clientX,\n touches[1].clientY - touches[0].clientY\n );\n touchStartDistance = distance;\n touchStartZoom = internalZoom.value;\n touchStartPos = { ...position.value };\n }\n};\n\nconst handleTouchMove = (e: TouchEvent) => {\n e.preventDefault();\n\n const touches = e.touches;\n if (touches.length === 1 && isDragging.value) {\n // 单指拖拽\n position.value = clampPosition(\n {\n x: touches[0].clientX - dragStart.x,\n y: touches[0].clientY - dragStart.y,\n },\n internalZoom.value\n );\n } else if (touches.length === 2) {\n // 双指缩放\n const container = containerRef.value;\n if (!container) return;\n\n const distance = Math.hypot(\n touches[1].clientX - touches[0].clientX,\n touches[1].clientY - touches[0].clientY\n );\n\n // 最小距离变化阈值,防止抖动\n if (Math.abs(distance - touchStartDistance) < 5) return;\n\n const scale = distance / touchStartDistance;\n const newZoom = Math.max(0.01, Math.min(10, touchStartZoom * scale));\n\n // 双指中心点作为缩放原点\n const rect = container.getBoundingClientRect();\n const centerX = (touches[0].clientX + touches[1].clientX) / 2 - rect.left - rect.width / 2;\n const centerY = (touches[0].clientY + touches[1].clientY) / 2 - rect.top - rect.height / 2;\n\n const zoomScale = newZoom / internalZoom.value;\n position.value = clampPosition(\n {\n x: centerX - zoomScale * (centerX - touchStartPos.x),\n y: centerY - zoomScale * (centerY - touchStartPos.y),\n },\n newZoom\n );\n\n internalZoom.value = newZoom;\n emit('zoomChange', newZoom);\n }\n};\n\nconst handleTouchEnd = () => {\n isDragging.value = false;\n touchStartDistance = 0;\n};\n\nconst transformStyle = computed(() => ({\n transform: `translate(${position.value.x}px, ${position.value.y}px) scale(${internalZoom.value}) rotate(${props.rotation}deg)`,\n transformOrigin: 'center',\n transition: isDragging.value ? 'none' : 'transform 0.3s ease-out',\n opacity: loaded.value && !error.value && !decodeError.value ? 1 : 0,\n}));\n\nconst sizeText = computed(() => {\n if (props.fileSize == null) return '';\n return ` · ${formatFileSize(props.fileSize)}`;\n});\n</script>\n\n<template>\n <div\n ref=\"containerRef\"\n class=\"vfp-relative vfp-flex vfp-items-center vfp-justify-center vfp-w-full vfp-h-full vfp-overflow-hidden\"\n :style=\"{ cursor: isDragging ? 'grabbing' : 'grab', touchAction: 'none' }\"\n @mousedown=\"handleMouseDown\"\n @mousemove=\"handleMouseMove\"\n @mouseup=\"handleMouseUp\"\n @mouseleave=\"handleMouseUp\"\n >\n <!-- 解码中 -->\n <div\n v-if=\"decoding\"\n class=\"vfp-absolute vfp-inset-0 vfp-flex vfp-flex-col vfp-items-center vfp-justify-center vfp-bg-surface-1/80 vfp-z-10\"\n >\n <Loader2 class=\"vfp-w-12 vfp-h-12 vfp-text-fg-primary vfp-animate-spin\" />\n <p class=\"vfp-mt-4 vfp-text-fg-secondary\">\n 正在解码... <span v-if=\"decodeProgress > 0\">{{ Math.round(decodeProgress) }}%</span>\n </p>\n </div>\n\n <!-- 解码错误 -->\n <RendererError v-if=\"decodeError\" :message=\"t('image.decode_failed')\" :detail=\"decodeError\" />\n\n <div v-if=\"!loaded && !error && !decoding && !decodeError\" class=\"vfp-flex vfp-items-center vfp-justify-center\">\n <div\n class=\"vfp-w-12 vfp-h-12 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin\"\n />\n </div>\n\n <RendererError v-if=\"error\" :message=\"error\" />\n\n <img\n v-if=\"imageSrc\"\n ref=\"imgRef\"\n :src=\"imageSrc\"\n alt=\"Preview\"\n :class=\"['vfp-max-w-none vfp-select-none', (!loaded || error || decodeError) && 'vfp-hidden']\"\n :style=\"transformStyle\"\n :draggable=\"false\"\n @load=\"handleLoad\"\n @error=\"handleError\"\n @dblclick=\"handleDoubleClick\"\n />\n\n <div\n v-if=\"loaded && !error && naturalSize.width > 0\"\n class=\"vfp-absolute vfp-bottom-2 vfp-right-3 vfp-text-[10px] vfp-text-fg-disabled hover:vfp-text-fg-secondary vfp-transition-colors vfp-pointer-events-auto vfp-select-none vfp-cursor-default\"\n >\n {{ naturalSize.width }} × {{ naturalSize.height }}{{ sizeText }}\n </div>\n\n <!-- 多页 TIFF 翻页器 -->\n <div\n v-if=\"totalPages > 1\"\n class=\"vfp-absolute vfp-bottom-2 vfp-left-1/2 -vfp-translate-x-1/2 vfp-flex vfp-items-center vfp-gap-2 vfp-px-3 vfp-py-1.5 vfp-bg-surface-toolbar vfp-border vfp-border-line vfp-rounded-lg vfp-text-sm vfp-text-fg-primary vfp-shadow-md\"\n >\n <button\n type=\"button\"\n :disabled=\"currentPage <= 1 || decoding\"\n class=\"vfp-px-2 vfp-py-0.5 vfp-rounded hover:vfp-bg-surface-nav-hover disabled:vfp-opacity-40 disabled:vfp-cursor-not-allowed\"\n @click=\"handlePageChange(currentPage - 1)\"\n >\n 上一页\n </button>\n <span class=\"vfp-text-fg-secondary vfp-tabular-nums\">\n {{ currentPage }} / {{ totalPages }}\n </span>\n <button\n type=\"button\"\n :disabled=\"currentPage >= totalPages || decoding\"\n class=\"vfp-px-2 vfp-py-0.5 vfp-rounded hover:vfp-bg-surface-nav-hover disabled:vfp-opacity-40 disabled:vfp-cursor-not-allowed\"\n @click=\"handlePageChange(currentPage + 1)\"\n >\n 下一页\n </button>\n </div>\n </div>\n</template>\n"],"names":["props","__props","emit","__emit","t","useTranslator","loaded","ref","error","decoding","decodeProgress","decodeError","imageSrc","currentPage","totalPages","isRawThumbnail","position","isDragging","dragStart","internalZoom","naturalSize","imgRef","containerRef","blobUrl","fileBlobCache","loaderCache","pageCache","isTouchDevice","touchStartDistance","touchStartZoom","touchStartPos","lastTapTime","watch","url","mimeType","detectImageFormat","loader","getLoaderForMimeType","fileBlob","response","metadata","decodedBlob","percent","err","handlePageChange","page","cached","firstKey","oldUrl","onBeforeUnmount","container","handleWheelNative","z","clampPosition","pos","currentZoom","containerW","containerH","imgW","imgH","margin","rangeX","rangeY","handleLoad","img","handleError","handleDoubleClick","rect","mouseX","mouseY","delta","prev","newZoom","scale","onMounted","handleTouchStart","handleTouchMove","handleTouchEnd","handleMouseDown","handleMouseMove","handleMouseUp","touches","now","distance","centerX","centerY","zoomScale","transformStyle","computed","sizeText","formatFileSize","_createElementBlock","_openBlock","_hoisted_1","_createVNode","_unref","Loader2","_createElementVNode","_hoisted_2","_createBlock","RendererError","_hoisted_4","_cache","_normalizeClass","_hoisted_6","_toDisplayString","_hoisted_7","$event","_hoisted_8","_hoisted_9","_hoisted_10"],"mappings":"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"}
1
+ {"version":3,"file":"index-BkMYaea2.mjs","sources":["../../src/renderers/Image/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, watch, onMounted, onBeforeUnmount, computed } from 'vue';\nimport { Loader2 } from 'lucide-vue-next';\nimport { formatFileSize, detectImageFormat, getLoaderForMimeType } from '@eternalheart/file-preview-core';\nimport type { PreviewFile } from '@eternalheart/file-preview-core';\nimport { useTranslator } from '../../composables/useTranslator';\nimport RendererError from '../RendererError.vue';\n\nconst props = defineProps<{\n url: string;\n zoom: number;\n rotation: number;\n resetKey?: number;\n fileSize?: number;\n file?: PreviewFile | File;\n}>();\n\nconst emit = defineEmits<{\n (e: 'zoomChange', zoom: number): void;\n (e: 'naturalWidthChange', width: number): void;\n (e: 'naturalHeightChange', height: number): void;\n}>();\n\nconst { t } = useTranslator();\n\nconst loaded = ref(false);\nconst error = ref<string | null>(null);\nconst decoding = ref(false);\nconst decodeProgress = ref(0);\nconst decodeError = ref<string | null>(null);\nconst imageSrc = ref<string>('');\nconst currentPage = ref(1);\nconst totalPages = ref(1);\nconst isRawThumbnail = ref(false);\nconst position = ref({ x: 0, y: 0 });\nconst isDragging = ref(false);\nlet dragStart = { x: 0, y: 0 };\nconst internalZoom = ref(1);\nconst naturalSize = ref({ width: 0, height: 0 });\n\nconst imgRef = ref<HTMLImageElement | null>(null);\nconst containerRef = ref<HTMLDivElement | null>(null);\nlet blobUrl: string | null = null;\nlet fileBlobCache: Blob | null = null;\nlet loaderCache: any = null;\nconst pageCache = new Map<number, string>();\n\nlet isTouchDevice = false;\nlet touchStartDistance = 0;\nlet touchStartZoom = 1;\nlet touchStartPos = { x: 0, y: 0 };\nlet lastTapTime = 0;\n\n// 解码逻辑\nwatch(\n () => [props.url, props.file] as const,\n async () => {\n // 重置状态:清空 src 以避免上一张图片的 onLoad/onError 误触发到新文件\n imageSrc.value = '';\n loaded.value = false;\n error.value = null;\n decoding.value = false;\n decodeError.value = null;\n decodeProgress.value = 0;\n position.value = { x: 0, y: 0 };\n internalZoom.value = 1;\n currentPage.value = 1;\n totalPages.value = 1;\n isRawThumbnail.value = false;\n\n // 清理旧的 blob URL 与缓存\n if (blobUrl) {\n URL.revokeObjectURL(blobUrl);\n blobUrl = null;\n }\n pageCache.forEach((url) => URL.revokeObjectURL(url));\n pageCache.clear();\n fileBlobCache = null;\n loaderCache = null;\n\n // 如果没有 file 对象,直接使用 url\n if (!props.file) {\n imageSrc.value = props.url;\n return;\n }\n\n try {\n // 检测图片格式\n const mimeType = await detectImageFormat(props.file);\n const loader = await getLoaderForMimeType(mimeType);\n\n // 如果不需要解码,直接使用原 URL\n if (!loader || !(await loader.needsDecode(mimeType))) {\n imageSrc.value = props.url;\n return;\n }\n\n // 需要解码\n decoding.value = true;\n\n // 获取文件 Blob\n let fileBlob: Blob;\n if (props.file instanceof Blob) {\n fileBlob = props.file;\n } else {\n const response = await fetch(props.url);\n if (!response.ok) throw new Error('Failed to fetch file');\n fileBlob = await response.blob();\n }\n\n // 缓存 Blob 与 loader\n fileBlobCache = fileBlob;\n loaderCache = loader;\n\n // 标记 RAW 缩略图模式\n const isRaw = mimeType.startsWith('image/x-');\n if (isRaw) {\n isRawThumbnail.value = true;\n }\n\n // 获取元数据(用于检测多页 TIFF)\n if (loader.getMetadata) {\n try {\n const metadata = await loader.getMetadata(fileBlob);\n if (metadata.pageCount && metadata.pageCount > 1) {\n totalPages.value = metadata.pageCount;\n }\n } catch {\n // 忽略元数据获取失败\n }\n }\n\n // 调用 loader 解码(第 1 页 / 缩略图模式)\n const decodedBlob = await loader.decode(fileBlob, {\n page: 1,\n fullQuality: false,\n onProgress: (percent: number) => {\n decodeProgress.value = percent;\n },\n });\n\n // 生成 blob URL\n const url = typeof decodedBlob === 'string'\n ? decodedBlob\n : URL.createObjectURL(decodedBlob);\n\n blobUrl = url;\n pageCache.set(1, url);\n imageSrc.value = url;\n decoding.value = false;\n } catch (err: any) {\n decodeError.value = err?.message || '解码失败';\n decoding.value = false;\n }\n },\n { immediate: true }\n);\n\n// 多页 TIFF 翻页\nconst handlePageChange = async (page: number) => {\n if (!fileBlobCache || !loaderCache) return;\n if (page < 1 || page > totalPages.value) return;\n\n // 命中缓存:直接切换\n const cached = pageCache.get(page);\n if (cached) {\n currentPage.value = page;\n imageSrc.value = cached;\n return;\n }\n\n // 解码新页面\n decoding.value = true;\n try {\n const decodedBlob = await loaderCache.decode(fileBlobCache, { page });\n const url = typeof decodedBlob === 'string'\n ? decodedBlob\n : URL.createObjectURL(decodedBlob);\n\n // LRU:缓存超过 10 页时删除最早的\n if (pageCache.size >= 10) {\n const firstKey = pageCache.keys().next().value;\n if (firstKey !== undefined) {\n const oldUrl = pageCache.get(firstKey);\n if (oldUrl) URL.revokeObjectURL(oldUrl);\n pageCache.delete(firstKey);\n }\n }\n\n pageCache.set(page, url);\n currentPage.value = page;\n imageSrc.value = url;\n decoding.value = false;\n } catch (err: any) {\n decodeError.value = err?.message || '翻页解码失败';\n decoding.value = false;\n }\n};\n\n// Cleanup on unmount\nonBeforeUnmount(() => {\n if (blobUrl) {\n URL.revokeObjectURL(blobUrl);\n }\n pageCache.forEach((url) => URL.revokeObjectURL(url));\n pageCache.clear();\n const container = containerRef.value;\n if (container) {\n container.removeEventListener('wheel', handleWheelNative);\n }\n});\n\nwatch(\n () => props.zoom,\n (z) => {\n internalZoom.value = z;\n }\n);\n\nwatch(\n () => props.resetKey,\n () => {\n position.value = { x: 0, y: 0 };\n }\n);\n\nconst clampPosition = (pos: { x: number; y: number }, currentZoom: number) => {\n const container = containerRef.value;\n if (!container || naturalSize.value.width === 0) return pos;\n\n const containerW = container.clientWidth;\n const containerH = container.clientHeight;\n const imgW = naturalSize.value.width * currentZoom;\n const imgH = naturalSize.value.height * currentZoom;\n\n const margin = Math.min(80, containerW * 0.15, containerH * 0.15);\n const rangeX = (containerW + imgW) / 2 - margin;\n const rangeY = (containerH + imgH) / 2 - margin;\n\n return {\n x: rangeX > 0 ? Math.max(-rangeX, Math.min(rangeX, pos.x)) : 0,\n y: rangeY > 0 ? Math.max(-rangeY, Math.min(rangeY, pos.y)) : 0,\n };\n};\n\nconst handleLoad = (e: Event) => {\n loaded.value = true;\n const img = e.currentTarget as HTMLImageElement;\n naturalSize.value = { width: img.naturalWidth, height: img.naturalHeight };\n emit('naturalWidthChange', img.naturalWidth);\n emit('naturalHeightChange', img.naturalHeight);\n};\n\nconst handleError = () => {\n error.value = t.value('image.load_failed');\n loaded.value = true;\n};\n\nconst handleDoubleClick = () => {\n position.value = { x: 0, y: 0 };\n internalZoom.value = 1;\n emit('zoomChange', 1);\n};\n\n// 鼠标滚轮缩放\nconst handleWheelNative = (e: WheelEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const container = containerRef.value;\n if (!container) return;\n\n const rect = container.getBoundingClientRect();\n const mouseX = e.clientX - rect.left - rect.width / 2;\n const mouseY = e.clientY - rect.top - rect.height / 2;\n\n const delta = e.deltaY > 0 ? -0.05 : 0.05;\n const prev = internalZoom.value;\n const newZoom = Math.max(0.01, Math.min(10, prev + delta));\n const scale = newZoom / prev;\n\n position.value = clampPosition(\n {\n x: mouseX - scale * (mouseX - position.value.x),\n y: mouseY - scale * (mouseY - position.value.y),\n },\n newZoom\n );\n\n internalZoom.value = newZoom;\n emit('zoomChange', newZoom);\n};\n\nonMounted(() => {\n const container = containerRef.value;\n if (container) {\n container.addEventListener('wheel', handleWheelNative, { passive: false });\n container.addEventListener('touchstart', handleTouchStart, { passive: false });\n container.addEventListener('touchmove', handleTouchMove, { passive: false });\n container.addEventListener('touchend', handleTouchEnd);\n container.addEventListener('touchcancel', handleTouchEnd);\n }\n});\n\nonBeforeUnmount(() => {\n const container = containerRef.value;\n if (container) {\n container.removeEventListener('wheel', handleWheelNative);\n container.removeEventListener('touchstart', handleTouchStart);\n container.removeEventListener('touchmove', handleTouchMove);\n container.removeEventListener('touchend', handleTouchEnd);\n container.removeEventListener('touchcancel', handleTouchEnd);\n }\n});\n\nconst handleMouseDown = (e: MouseEvent) => {\n if (isTouchDevice) return;\n if (e.button !== 0) return;\n isDragging.value = true;\n dragStart = {\n x: e.clientX - position.value.x,\n y: e.clientY - position.value.y,\n };\n};\n\nconst handleMouseMove = (e: MouseEvent) => {\n if (isTouchDevice) return;\n if (!isDragging.value) return;\n position.value = clampPosition(\n {\n x: e.clientX - dragStart.x,\n y: e.clientY - dragStart.y,\n },\n internalZoom.value\n );\n};\n\nconst handleMouseUp = () => {\n if (isTouchDevice) return;\n isDragging.value = false;\n};\n\n// 触屏事件处理\nconst handleTouchStart = (e: TouchEvent) => {\n isTouchDevice = true;\n e.preventDefault();\n\n const touches = e.touches;\n if (touches.length === 1) {\n // 单指拖拽\n isDragging.value = true;\n dragStart = {\n x: touches[0].clientX - position.value.x,\n y: touches[0].clientY - position.value.y,\n };\n\n // 双击检测\n const now = Date.now();\n if (now - lastTapTime < 300) {\n // 双击复原:居中 + 缩放100%\n position.value = { x: 0, y: 0 };\n internalZoom.value = 1;\n emit('zoomChange', 1);\n }\n lastTapTime = now;\n } else if (touches.length === 2) {\n // 双指缩放初始化\n isDragging.value = false;\n const distance = Math.hypot(\n touches[1].clientX - touches[0].clientX,\n touches[1].clientY - touches[0].clientY\n );\n touchStartDistance = distance;\n touchStartZoom = internalZoom.value;\n touchStartPos = { ...position.value };\n }\n};\n\nconst handleTouchMove = (e: TouchEvent) => {\n e.preventDefault();\n\n const touches = e.touches;\n if (touches.length === 1 && isDragging.value) {\n // 单指拖拽\n position.value = clampPosition(\n {\n x: touches[0].clientX - dragStart.x,\n y: touches[0].clientY - dragStart.y,\n },\n internalZoom.value\n );\n } else if (touches.length === 2) {\n // 双指缩放\n const container = containerRef.value;\n if (!container) return;\n\n const distance = Math.hypot(\n touches[1].clientX - touches[0].clientX,\n touches[1].clientY - touches[0].clientY\n );\n\n // 最小距离变化阈值,防止抖动\n if (Math.abs(distance - touchStartDistance) < 5) return;\n\n const scale = distance / touchStartDistance;\n const newZoom = Math.max(0.01, Math.min(10, touchStartZoom * scale));\n\n // 双指中心点作为缩放原点\n const rect = container.getBoundingClientRect();\n const centerX = (touches[0].clientX + touches[1].clientX) / 2 - rect.left - rect.width / 2;\n const centerY = (touches[0].clientY + touches[1].clientY) / 2 - rect.top - rect.height / 2;\n\n const zoomScale = newZoom / internalZoom.value;\n position.value = clampPosition(\n {\n x: centerX - zoomScale * (centerX - touchStartPos.x),\n y: centerY - zoomScale * (centerY - touchStartPos.y),\n },\n newZoom\n );\n\n internalZoom.value = newZoom;\n emit('zoomChange', newZoom);\n }\n};\n\nconst handleTouchEnd = () => {\n isDragging.value = false;\n touchStartDistance = 0;\n};\n\nconst transformStyle = computed(() => ({\n transform: `translate(${position.value.x}px, ${position.value.y}px) scale(${internalZoom.value}) rotate(${props.rotation}deg)`,\n transformOrigin: 'center',\n transition: isDragging.value ? 'none' : 'transform 0.3s ease-out',\n opacity: loaded.value && !error.value && !decodeError.value ? 1 : 0,\n}));\n\nconst sizeText = computed(() => {\n if (props.fileSize == null) return '';\n return ` · ${formatFileSize(props.fileSize)}`;\n});\n</script>\n\n<template>\n <div\n ref=\"containerRef\"\n class=\"vfp-relative vfp-flex vfp-items-center vfp-justify-center vfp-w-full vfp-h-full vfp-overflow-hidden\"\n :style=\"{ cursor: isDragging ? 'grabbing' : 'grab', touchAction: 'none' }\"\n @mousedown=\"handleMouseDown\"\n @mousemove=\"handleMouseMove\"\n @mouseup=\"handleMouseUp\"\n @mouseleave=\"handleMouseUp\"\n >\n <!-- 解码中 -->\n <div\n v-if=\"decoding\"\n class=\"vfp-absolute vfp-inset-0 vfp-flex vfp-flex-col vfp-items-center vfp-justify-center vfp-bg-surface-1/80 vfp-z-10\"\n >\n <Loader2 class=\"vfp-w-12 vfp-h-12 vfp-text-fg-primary vfp-animate-spin\" />\n <p class=\"vfp-mt-4 vfp-text-fg-secondary\">\n 正在解码... <span v-if=\"decodeProgress > 0\">{{ Math.round(decodeProgress) }}%</span>\n </p>\n </div>\n\n <!-- 解码错误 -->\n <RendererError v-if=\"decodeError\" :message=\"t('image.decode_failed')\" :detail=\"decodeError\" />\n\n <div v-if=\"!loaded && !error && !decoding && !decodeError\" class=\"vfp-flex vfp-items-center vfp-justify-center\">\n <div\n class=\"vfp-w-12 vfp-h-12 vfp-border-4 vfp-border-line-strong vfp-border-t-spinner-head vfp-rounded-full vfp-animate-spin\"\n />\n </div>\n\n <RendererError v-if=\"error\" :message=\"error\" />\n\n <img\n v-if=\"imageSrc\"\n ref=\"imgRef\"\n :src=\"imageSrc\"\n alt=\"Preview\"\n :class=\"['vfp-max-w-none vfp-select-none', (!loaded || error || decodeError) && 'vfp-hidden']\"\n :style=\"transformStyle\"\n :draggable=\"false\"\n @load=\"handleLoad\"\n @error=\"handleError\"\n @dblclick=\"handleDoubleClick\"\n />\n\n <div\n v-if=\"loaded && !error && naturalSize.width > 0\"\n class=\"vfp-absolute vfp-bottom-2 vfp-right-3 vfp-text-[10px] vfp-text-fg-disabled hover:vfp-text-fg-secondary vfp-transition-colors vfp-pointer-events-auto vfp-select-none vfp-cursor-default\"\n >\n {{ naturalSize.width }} × {{ naturalSize.height }}{{ sizeText }}\n </div>\n\n <!-- 多页 TIFF 翻页器 -->\n <div\n v-if=\"totalPages > 1\"\n class=\"vfp-absolute vfp-bottom-2 vfp-left-1/2 -vfp-translate-x-1/2 vfp-flex vfp-items-center vfp-gap-2 vfp-px-3 vfp-py-1.5 vfp-bg-surface-toolbar vfp-border vfp-border-line vfp-rounded-lg vfp-text-sm vfp-text-fg-primary vfp-shadow-md\"\n >\n <button\n type=\"button\"\n :disabled=\"currentPage <= 1 || decoding\"\n class=\"vfp-px-2 vfp-py-0.5 vfp-rounded hover:vfp-bg-surface-nav-hover disabled:vfp-opacity-40 disabled:vfp-cursor-not-allowed\"\n @click=\"handlePageChange(currentPage - 1)\"\n >\n 上一页\n </button>\n <span class=\"vfp-text-fg-secondary vfp-tabular-nums\">\n {{ currentPage }} / {{ totalPages }}\n </span>\n <button\n type=\"button\"\n :disabled=\"currentPage >= totalPages || decoding\"\n class=\"vfp-px-2 vfp-py-0.5 vfp-rounded hover:vfp-bg-surface-nav-hover disabled:vfp-opacity-40 disabled:vfp-cursor-not-allowed\"\n @click=\"handlePageChange(currentPage + 1)\"\n >\n 下一页\n </button>\n </div>\n </div>\n</template>\n"],"names":["props","__props","emit","__emit","t","useTranslator","loaded","ref","error","decoding","decodeProgress","decodeError","imageSrc","currentPage","totalPages","isRawThumbnail","position","isDragging","dragStart","internalZoom","naturalSize","imgRef","containerRef","blobUrl","fileBlobCache","loaderCache","pageCache","isTouchDevice","touchStartDistance","touchStartZoom","touchStartPos","lastTapTime","watch","url","mimeType","detectImageFormat","loader","getLoaderForMimeType","fileBlob","response","metadata","decodedBlob","percent","err","handlePageChange","page","cached","firstKey","oldUrl","onBeforeUnmount","container","handleWheelNative","z","clampPosition","pos","currentZoom","containerW","containerH","imgW","imgH","margin","rangeX","rangeY","handleLoad","img","handleError","handleDoubleClick","rect","mouseX","mouseY","delta","prev","newZoom","scale","onMounted","handleTouchStart","handleTouchMove","handleTouchEnd","handleMouseDown","handleMouseMove","handleMouseUp","touches","now","distance","centerX","centerY","zoomScale","transformStyle","computed","sizeText","formatFileSize","_createElementBlock","_openBlock","_hoisted_1","_createVNode","_unref","Loader2","_createElementVNode","_hoisted_2","_createBlock","RendererError","_hoisted_4","_cache","_normalizeClass","_hoisted_6","_toDisplayString","_hoisted_7","$event","_hoisted_8","_hoisted_9","_hoisted_10"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { defineComponent as Os, ref as Ie, onMounted as ws, onBeforeUnmount as Es, watch as Mr, openBlock as de, createElementBlock as Ce, normalizeStyle as Pr, toDisplayString as Y, computed as mt, createElementVNode as B, unref as re, createBlock as Br, Fragment as Dn, createCommentVNode as Wt, withDirectives as Nr, vModelText as _r, renderList as Gr, createVNode as qt } from "vue";
2
- import { u as Hr, a as Vr, c as zr } from "./index-Oxwizt6-.mjs";
2
+ import { u as Hr, a as Vr, c as zr } from "./index-CFaWV6cC.mjs";
3
3
  import { _ as jr } from "./RendererError.vue_vue_type_script_setup_true_lang-CbgZBSDr.mjs";
4
4
  var mn = 0, Rs = -3;
5
5
  function at() {
@@ -12347,4 +12347,4 @@ abcdefghijklmnopqrstuvwxyz
12347
12347
  export {
12348
12348
  Lf as default
12349
12349
  };
12350
- //# sourceMappingURL=index-BTW1xwB9.mjs.map
12350
+ //# sourceMappingURL=index-BlD2p_KC.mjs.map