hookehuyr

feat(PdfViewer): 添加缩放时保持滚动位置功能

在PDF查看器中添加滚动位置记录功能,当用户进行缩放操作时,会基于当前视口中心点计算并保持相对滚动位置,提升用户体验
...@@ -110,6 +110,7 @@ const loadingProgress = ref(0); ...@@ -110,6 +110,7 @@ const loadingProgress = ref(0);
110 const loadingError = ref(false); 110 const loadingError = ref(false);
111 const errorMessage = ref(''); 111 const errorMessage = ref('');
112 const zoomLevel = ref(1); // 缩放级别,1为100% 112 const zoomLevel = ref(1); // 缩放级别,1为100%
113 +const scrollPosition = ref({ x: 0, y: 0 }); // 记录滚动位置
113 114
114 /** 115 /**
115 * 监听show属性变化,控制PDF加载 116 * 监听show属性变化,控制PDF加载
...@@ -171,7 +172,14 @@ const handleComplete = () => { ...@@ -171,7 +172,14 @@ const handleComplete = () => {
171 * @param {number} scrollOffset - 滚动偏移量 172 * @param {number} scrollOffset - 滚动偏移量
172 */ 173 */
173 const handleScroll = (scrollOffset) => { 174 const handleScroll = (scrollOffset) => {
174 - // 可以在这里处理滚动事件 175 + // 记录当前滚动位置
176 + const pdfContainer = document.querySelector('.pdf-viewer-container .pdf-content');
177 + if (pdfContainer) {
178 + scrollPosition.value = {
179 + x: pdfContainer.scrollLeft,
180 + y: pdfContainer.scrollTop
181 + };
182 + }
175 }; 183 };
176 184
177 /** 185 /**
...@@ -237,7 +245,29 @@ const retryLoad = () => { ...@@ -237,7 +245,29 @@ const retryLoad = () => {
237 */ 245 */
238 const zoomIn = () => { 246 const zoomIn = () => {
239 if (zoomLevel.value < 3) { // 最大放大到300% 247 if (zoomLevel.value < 3) { // 最大放大到300%
240 - zoomLevel.value = Math.min(3, zoomLevel.value + 0.25); 248 + // 记录缩放前的滚动位置
249 + const pdfContainer = document.querySelector('.pdf-viewer-container .pdf-content');
250 + if (pdfContainer) {
251 + const centerX = pdfContainer.scrollLeft + pdfContainer.clientWidth / 2;
252 + const centerY = pdfContainer.scrollTop + pdfContainer.clientHeight / 2;
253 +
254 + const oldZoom = zoomLevel.value;
255 + zoomLevel.value = Math.min(3, zoomLevel.value + 0.25);
256 + const newZoom = zoomLevel.value;
257 +
258 + // 使用nextTick确保DOM更新后再调整滚动位置
259 + nextTick(() => {
260 + const zoomRatio = newZoom / oldZoom;
261 + const newScrollLeft = centerX * zoomRatio - pdfContainer.clientWidth / 2;
262 + const newScrollTop = centerY * zoomRatio - pdfContainer.clientHeight / 2;
263 +
264 + pdfContainer.scrollTo({
265 + left: Math.max(0, newScrollLeft),
266 + top: Math.max(0, newScrollTop),
267 + behavior: 'smooth'
268 + });
269 + });
270 + }
241 } 271 }
242 }; 272 };
243 273
...@@ -246,7 +276,29 @@ const zoomIn = () => { ...@@ -246,7 +276,29 @@ const zoomIn = () => {
246 */ 276 */
247 const zoomOut = () => { 277 const zoomOut = () => {
248 if (zoomLevel.value > 0.5) { // 最小缩小到50% 278 if (zoomLevel.value > 0.5) { // 最小缩小到50%
249 - zoomLevel.value = Math.max(0.5, zoomLevel.value - 0.25); 279 + // 记录缩放前的滚动位置
280 + const pdfContainer = document.querySelector('.pdf-viewer-container .pdf-content');
281 + if (pdfContainer) {
282 + const centerX = pdfContainer.scrollLeft + pdfContainer.clientWidth / 2;
283 + const centerY = pdfContainer.scrollTop + pdfContainer.clientHeight / 2;
284 +
285 + const oldZoom = zoomLevel.value;
286 + zoomLevel.value = Math.max(0.5, zoomLevel.value - 0.25);
287 + const newZoom = zoomLevel.value;
288 +
289 + // 使用nextTick确保DOM更新后再调整滚动位置
290 + nextTick(() => {
291 + const zoomRatio = newZoom / oldZoom;
292 + const newScrollLeft = centerX * zoomRatio - pdfContainer.clientWidth / 2;
293 + const newScrollTop = centerY * zoomRatio - pdfContainer.clientHeight / 2;
294 +
295 + pdfContainer.scrollTo({
296 + left: Math.max(0, newScrollLeft),
297 + top: Math.max(0, newScrollTop),
298 + behavior: 'smooth'
299 + });
300 + });
301 + }
250 } 302 }
251 }; 303 };
252 304
...@@ -254,7 +306,21 @@ const zoomOut = () => { ...@@ -254,7 +306,21 @@ const zoomOut = () => {
254 * 重置缩放 306 * 重置缩放
255 */ 307 */
256 const resetZoom = () => { 308 const resetZoom = () => {
257 - zoomLevel.value = 1; 309 + const pdfContainer = document.querySelector('.pdf-viewer-container .pdf-content');
310 + if (pdfContainer) {
311 + // 重置到顶部中央位置
312 + zoomLevel.value = 1;
313 +
314 + nextTick(() => {
315 + pdfContainer.scrollTo({
316 + left: 0,
317 + top: 0,
318 + behavior: 'smooth'
319 + });
320 + });
321 + } else {
322 + zoomLevel.value = 1;
323 + }
258 }; 324 };
259 325
260 /** 326 /**
......