feat(PdfViewer): 添加放大缩小图标并优化缩放功能
将PDF查看器的缩放按钮从Vant组件替换为FontAwesome图标 添加faMagnifyingGlassPlus和faMagnifyingGlassMinus图标 优化双指缩放的手势处理逻辑
Showing
2 changed files
with
16 additions
and
14 deletions
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2025-01-21 | 2 | * @Date: 2025-01-21 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-10-22 12:17:03 | 4 | + * @LastEditTime: 2025-10-22 13:28:38 |
| 5 | * @FilePath: /mlaj/src/components/ui/PdfViewer.vue | 5 | * @FilePath: /mlaj/src/components/ui/PdfViewer.vue |
| 6 | * @Description: PDF预览组件 - 使用pdf-vue3库 | 6 | * @Description: PDF预览组件 - 使用pdf-vue3库 |
| 7 | --> | 7 | --> |
| ... | @@ -55,7 +55,8 @@ | ... | @@ -55,7 +55,8 @@ |
| 55 | <!-- 缩放控制按钮 --> | 55 | <!-- 缩放控制按钮 --> |
| 56 | <div v-if="!loading && !loadingError" class="zoom-controls"> | 56 | <div v-if="!loading && !loadingError" class="zoom-controls"> |
| 57 | <van-button class="zoom-btn zoom-close-btn" type="default" icon="cross" round @click="handleClose" /> | 57 | <van-button class="zoom-btn zoom-close-btn" type="default" icon="cross" round @click="handleClose" /> |
| 58 | - <van-button class="zoom-btn zoom-in-btn" type="default" icon="plus" round @click="zoomIn" /> | 58 | + <!-- <van-button class="zoom-btn zoom-in-btn" type="default" icon="plus" round @click="zoomIn" /> --> |
| 59 | + <font-awesome-icon icon="magnifying-glass-plus" class="text-2xl text-gray-600 ml-2 mr-2" @click="zoomIn" /> | ||
| 59 | <div class="page-jump" @click="focusPageInput"> | 60 | <div class="page-jump" @click="focusPageInput"> |
| 60 | <span class="page-display">{{ currentPage }}/{{ totalPages || 0 }}</span> | 61 | <span class="page-display">{{ currentPage }}/{{ totalPages || 0 }}</span> |
| 61 | <input | 62 | <input |
| ... | @@ -70,7 +71,8 @@ | ... | @@ -70,7 +71,8 @@ |
| 70 | v-show="isEditingPage" | 71 | v-show="isEditingPage" |
| 71 | /> | 72 | /> |
| 72 | </div> | 73 | </div> |
| 73 | - <van-button class="zoom-btn zoom-out-btn" type="default" icon="minus" round @click="zoomOut" /> | 74 | + <!-- <van-button class="zoom-btn zoom-out-btn" type="default" icon="minus" round @click="zoomOut" /> --> |
| 75 | + <font-awesome-icon icon="magnifying-glass-minus" class="text-2xl text-gray-600 ml-2 mr-2" @click="zoomOut" /> | ||
| 74 | <van-button class="zoom-btn zoom-reset-btn" type="default" round @click="resetZoom"> | 76 | <van-button class="zoom-btn zoom-reset-btn" type="default" round @click="resetZoom"> |
| 75 | <van-icon name="replay" size="16" /> | 77 | <van-icon name="replay" size="16" /> |
| 76 | </van-button> | 78 | </van-button> |
| ... | @@ -570,7 +572,7 @@ const addPinchZoomListeners = (container) => { | ... | @@ -570,7 +572,7 @@ const addPinchZoomListeners = (container) => { |
| 570 | // 触摸开始 | 572 | // 触摸开始 |
| 571 | container.addEventListener('touchstart', (e) => { | 573 | container.addEventListener('touchstart', (e) => { |
| 572 | touches = Array.from(e.touches); | 574 | touches = Array.from(e.touches); |
| 573 | - | 575 | + |
| 574 | if (touches.length === 2) { | 576 | if (touches.length === 2) { |
| 575 | // 双指触摸开始 | 577 | // 双指触摸开始 |
| 576 | e.preventDefault(); | 578 | e.preventDefault(); |
| ... | @@ -587,21 +589,21 @@ const addPinchZoomListeners = (container) => { | ... | @@ -587,21 +589,21 @@ const addPinchZoomListeners = (container) => { |
| 587 | container.addEventListener('touchmove', (e) => { | 589 | container.addEventListener('touchmove', (e) => { |
| 588 | if (e.touches.length === 2 && isZooming) { | 590 | if (e.touches.length === 2 && isZooming) { |
| 589 | e.preventDefault(); | 591 | e.preventDefault(); |
| 590 | - | 592 | + |
| 591 | const currentTouches = Array.from(e.touches); | 593 | const currentTouches = Array.from(e.touches); |
| 592 | const currentDistance = getDistance(currentTouches[0], currentTouches[1]); | 594 | const currentDistance = getDistance(currentTouches[0], currentTouches[1]); |
| 593 | const scale = currentDistance / initialDistance; | 595 | const scale = currentDistance / initialDistance; |
| 594 | - | 596 | + |
| 595 | // 计算新的缩放级别 | 597 | // 计算新的缩放级别 |
| 596 | let newZoom = initialZoom * scale; | 598 | let newZoom = initialZoom * scale; |
| 597 | newZoom = Math.max(0.5, Math.min(3, newZoom)); // 限制缩放范围 | 599 | newZoom = Math.max(0.5, Math.min(3, newZoom)); // 限制缩放范围 |
| 598 | - | 600 | + |
| 599 | // 获取缩放中心点 | 601 | // 获取缩放中心点 |
| 600 | const center = getCenter(currentTouches[0], currentTouches[1]); | 602 | const center = getCenter(currentTouches[0], currentTouches[1]); |
| 601 | const rect = container.getBoundingClientRect(); | 603 | const rect = container.getBoundingClientRect(); |
| 602 | const centerX = center.x - rect.left; | 604 | const centerX = center.x - rect.left; |
| 603 | const centerY = center.y - rect.top; | 605 | const centerY = center.y - rect.top; |
| 604 | - | 606 | + |
| 605 | // 应用缩放 | 607 | // 应用缩放 |
| 606 | applyPinchZoom(newZoom, centerX, centerY, container); | 608 | applyPinchZoom(newZoom, centerX, centerY, container); |
| 607 | } | 609 | } |
| ... | @@ -631,18 +633,18 @@ const applyPinchZoom = (newZoom, centerX, centerY, container) => { | ... | @@ -631,18 +633,18 @@ const applyPinchZoom = (newZoom, centerX, centerY, container) => { |
| 631 | const oldZoom = zoomLevel.value; | 633 | const oldZoom = zoomLevel.value; |
| 632 | const oldScrollLeft = container.scrollLeft; | 634 | const oldScrollLeft = container.scrollLeft; |
| 633 | const oldScrollTop = container.scrollTop; | 635 | const oldScrollTop = container.scrollTop; |
| 634 | - | 636 | + |
| 635 | // 更新缩放级别 | 637 | // 更新缩放级别 |
| 636 | zoomLevel.value = newZoom; | 638 | zoomLevel.value = newZoom; |
| 637 | - | 639 | + |
| 638 | // 等待DOM更新后调整滚动位置 | 640 | // 等待DOM更新后调整滚动位置 |
| 639 | nextTick(() => { | 641 | nextTick(() => { |
| 640 | const zoomRatio = newZoom / oldZoom; | 642 | const zoomRatio = newZoom / oldZoom; |
| 641 | - | 643 | + |
| 642 | // 计算新的滚动位置,以缩放中心为锚点 | 644 | // 计算新的滚动位置,以缩放中心为锚点 |
| 643 | const newScrollLeft = (oldScrollLeft + centerX) * zoomRatio - centerX; | 645 | const newScrollLeft = (oldScrollLeft + centerX) * zoomRatio - centerX; |
| 644 | const newScrollTop = (oldScrollTop + centerY) * zoomRatio - centerY; | 646 | const newScrollTop = (oldScrollTop + centerY) * zoomRatio - centerY; |
| 645 | - | 647 | + |
| 646 | // 应用新的滚动位置 | 648 | // 应用新的滚动位置 |
| 647 | container.scrollLeft = Math.max(0, newScrollLeft); | 649 | container.scrollLeft = Math.max(0, newScrollLeft); |
| 648 | container.scrollTop = Math.max(0, newScrollTop); | 650 | container.scrollTop = Math.max(0, newScrollTop); | ... | ... |
| ... | @@ -18,10 +18,10 @@ import { library } from '@fortawesome/fontawesome-svg-core' | ... | @@ -18,10 +18,10 @@ import { library } from '@fortawesome/fontawesome-svg-core' |
| 18 | /* import font awesome icon component */ | 18 | /* import font awesome icon component */ |
| 19 | import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' | 19 | import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' |
| 20 | /* import specific icons */ | 20 | /* import specific icons */ |
| 21 | -import { faCirclePause, faCirclePlay, faPlay, faPause, faBackwardStep, faForwardStep, faVolumeUp, faRedo, faRepeat, faList, faChevronDown, faVolumeOff, faXmark, faFileAlt, faTimes, faEye, faFilePdf, faExternalLinkAlt, faSpinner, faExclamationCircle, faDownload, faVenus, faMars } from '@fortawesome/free-solid-svg-icons' | 21 | +import { faCirclePause, faCirclePlay, faPlay, faPause, faBackwardStep, faForwardStep, faVolumeUp, faRedo, faRepeat, faList, faChevronDown, faVolumeOff, faXmark, faFileAlt, faTimes, faEye, faFilePdf, faExternalLinkAlt, faSpinner, faExclamationCircle, faDownload, faVenus, faMars, faMagnifyingGlassPlus, faMagnifyingGlassMinus } from '@fortawesome/free-solid-svg-icons' |
| 22 | 22 | ||
| 23 | /* add icons to the library */ | 23 | /* add icons to the library */ |
| 24 | -library.add(faCirclePause, faCirclePlay, faPlay, faPause, faBackwardStep, faForwardStep, faVolumeUp, faRedo, faRepeat, faList, faChevronDown, faVolumeOff, faXmark, faFileAlt, faTimes, faEye, faFilePdf, faExternalLinkAlt, faSpinner, faExclamationCircle, faDownload, faVenus, faMars ) | 24 | +library.add(faCirclePause, faCirclePlay, faPlay, faPause, faBackwardStep, faForwardStep, faVolumeUp, faRedo, faRepeat, faList, faChevronDown, faVolumeOff, faXmark, faFileAlt, faTimes, faEye, faFilePdf, faExternalLinkAlt, faSpinner, faExclamationCircle, faDownload, faVenus, faMars, faMagnifyingGlassPlus, faMagnifyingGlassMinus ) |
| 25 | 25 | ||
| 26 | if (!Array.prototype.at) { | 26 | if (!Array.prototype.at) { |
| 27 | Array.prototype.at = function(n) { | 27 | Array.prototype.at = function(n) { | ... | ... |
-
Please register or login to post a comment