askbot-dragon 1.8.35-beta → 1.8.36-beta

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.
@@ -88,7 +88,8 @@ export default {
88
88
  pdf: null,
89
89
  numPages: 0,
90
90
  scale: 1, // 初始缩小比例
91
- pages: [], // { pageNumber: number, loaded: boolean, canvas: ref, loading: boolean, retryCount: number }
91
+ renderInProgress: false,
92
+ pages: [], // { pageNumber: number, loaded: boolean, canvas: ref, loading: boolean }
92
93
  // 静态高亮(坐标采用顶部为原点)
93
94
  highlights: [],
94
95
  searchQuery: "",
@@ -178,22 +179,28 @@ export default {
178
179
  loaded: false,
179
180
  canvas: null,
180
181
  loading: false,
181
- retryCount: 0,
182
182
  }));
183
183
  // 清空搜索高亮
184
184
  this.searchHighlights = [];
185
185
  this.searchTermCount = 0;
186
186
  this.currentSearchIndex = 0;
187
- setTimeout(async () => {
188
- await this.setCanvasRef();
189
- },100)
187
+ // 确保 DOM 更新完成后再设置 canvas 引用
188
+ await this.$nextTick();
189
+ await this.setCanvasRef();
190
+ }).catch(error => {
191
+ console.error('PDF 加载失败:', error);
190
192
  })
191
193
 
192
194
  },
193
195
  async loadPdf() {
194
196
  if (!this.pdfFile) return;
195
197
  await this.initPdf();
196
- this.initObserver();
198
+ // 确保 canvas 引用设置完成后再初始化观察器
199
+ await this.$nextTick();
200
+ // 延迟初始化观察器,确保所有 canvas 都已准备好
201
+ setTimeout(() => {
202
+ this.initObserver();
203
+ }, 200);
197
204
  },
198
205
  initObserver(type) {
199
206
  if (this.observer) {
@@ -206,7 +213,7 @@ export default {
206
213
  const index = Number(entry.target.getAttribute('data-index'));
207
214
  const page = this.pages[index];
208
215
  if (page && !page.loaded && !page.loading) {
209
- this.renderPage(page.pageNumber);
216
+ this.renderPage(page.pageNumber);
210
217
  }
211
218
  this.updateCurrentPage();
212
219
  }
@@ -218,7 +225,9 @@ export default {
218
225
  threshold: 0.1,
219
226
  }
220
227
  );
221
- this.$nextTick( () => {
228
+ // 确保 canvas 引用都已设置好后再开始观察
229
+ this.$nextTick(() => {
230
+ // 增加延迟确保所有 canvas 引用都已设置
222
231
  setTimeout(() => {
223
232
  this.pages.forEach((page, index) => {
224
233
  const canvas = page.canvas;
@@ -227,7 +236,7 @@ export default {
227
236
  this.observer.observe(canvas);
228
237
  }
229
238
  });
230
- },300)
239
+ },500)
231
240
  if (type !== 'changeScale' && type !== 'onResize'){
232
241
  setTimeout(async () => {
233
242
  let currentPage = this.split_paragraphs.length > 0 ? this.split_paragraphs[0] : null;
@@ -250,195 +259,161 @@ export default {
250
259
  await this.updateCurrentPage();
251
260
  }
252
261
  },
253
- async renderPage(pageNumber, retry = false) {
262
+ async renderPage(pageNumber) {
254
263
  if (!this.pdf) return;
255
264
  const pageIndex = pageNumber - 1;
256
265
  const pageData = this.pages[pageIndex];
257
266
  if (!pageData) return;
258
-
259
- // 如果正在加载且不是重试,避免重复渲染
260
- if (pageData.loading && !retry) return;
261
- // 如果已加载且不是重试,直接返回
262
- if (pageData.loaded && !retry) return;
263
-
264
- // 重试机制:最多重试 3 次
265
- const maxRetries = 3;
266
- if (retry && pageData.retryCount >= maxRetries) {
267
- console.error(`Max retries reached for page ${pageNumber}`);
268
- this.$set(pageData, 'loading', false);
269
- return;
270
- }
271
-
267
+ // 如果已经在加载或已加载,避免重复渲染
268
+ if (pageData.loaded || pageData.loading) return;
269
+
272
270
  this.pageNumber = pageNumber;
273
-
271
+
274
272
  try {
273
+ // 标记为加载中,防止重复渲染
274
+ this.$set(pageData, 'loading', true);
275
+
275
276
  const page = await this.pdf.getPage(pageNumber);
276
- let pdfWidth = page.getViewport({ scale: 1}).width;
277
+ let pdfWidth = page.getViewport({ scale: 1 }).width;
277
278
  const viewport = page.getViewport({ scale: this.calculateScale(pdfWidth) });
278
279
  this.viewport = viewport;
279
-
280
+
280
281
  const canvas = pageData.canvas;
281
282
  if (!canvas) {
282
- console.warn(`Canvas not found for page ${pageNumber}, will retry...`);
283
- // 如果 canvas 不存在,增加重试计数并延迟重试
284
- if (!retry) {
285
- this.$set(pageData, 'retryCount', (pageData.retryCount || 0) + 1);
286
- setTimeout(() => {
287
- this.renderPage(pageNumber, true);
288
- }, 200);
289
- }
283
+ console.warn(`页面 ${pageNumber} canvas 引用不存在`);
284
+ this.$set(pageData, 'loading', false);
290
285
  return;
291
286
  }
292
287
 
293
288
  const context = canvas.getContext("2d");
294
289
  if (!context) {
295
- console.warn(`Failed to get context for page ${pageNumber}, will retry...`);
296
- // 如果无法获取 context,增加重试计数并延迟重试
297
- if (!retry) {
298
- this.$set(pageData, 'retryCount', (pageData.retryCount || 0) + 1);
299
- setTimeout(() => {
300
- this.renderPage(pageNumber, true);
301
- }, 200);
302
- }
290
+ console.warn(`页面 ${pageNumber} 无法获取 canvas context`);
291
+ this.$set(pageData, 'loading', false);
303
292
  return;
304
293
  }
305
-
294
+
306
295
  this.context = context;
307
- const devicePixelRatio = window.devicePixelRatio || 1;
308
- canvas.width = (viewport.width) * devicePixelRatio;
309
- canvas.height = viewport.height * devicePixelRatio;
310
- canvas.style.width = `${viewport.width}px`;
311
- canvas.style.height = `${viewport.height}px`;
312
- context.scale(devicePixelRatio, devicePixelRatio);
313
-
314
- // 设置加载状态
315
- this.$set(pageData, 'loading', true);
316
-
317
- // 清理旧的文本层
296
+
297
+ // 计算输出缩放比例(与 vuePdf 保持一致)
298
+ const outputScale = this.calculateScale(pdfWidth);
299
+
300
+ // 计算实际显示的尺寸
301
+ let domWidth = Math.floor(viewport.width);
302
+ let domHeight = Math.floor(viewport.height);
303
+
304
+ // 设置 canvas 尺寸(与 vuePdf 保持一致,使用 outputScale)
305
+ // 注意:vuePdf 不使用 devicePixelRatio,为了保持一致,我们也只使用 outputScale
306
+ canvas.width = Math.floor(viewport.width * outputScale);
307
+ canvas.height = Math.floor(viewport.height * outputScale);
308
+ canvas.style.width = `${domWidth}px`;
309
+ canvas.style.height = `${domHeight}px`;
310
+
311
+ // 创建 transform 矩阵(与 vuePdf 保持一致)
312
+ const transform = outputScale !== 1
313
+ ? [outputScale, 0, 0, outputScale, 0, 0]
314
+ : null;
315
+
316
+ // 清除旧的文本层
318
317
  let hasDoc = document.getElementById('textLayer' + pageNumber);
319
- if (hasDoc && hasDoc.parentNode) {
318
+ if (hasDoc) {
320
319
  hasDoc.parentNode.removeChild(hasDoc);
321
320
  }
322
-
323
- // 渲染 PDF 页面
324
- const renderTask = page.render({ canvasContext: context, viewport });
325
-
326
- // 等待渲染完成后再处理文本层和高亮
327
- await renderTask.promise.then(async () => {
328
- // 获取文本内容
321
+
322
+ // 渲染 PDF 页面到 canvas(传入 transform 确保正确渲染)
323
+ const renderTask = page.render({
324
+ canvasContext: context,
325
+ viewport: viewport,
326
+ transform: transform
327
+ });
328
+ await renderTask.promise;
329
+
330
+ // 渲染文本层(必须在高亮渲染之前,确保文本层在最上层)
331
+ try {
329
332
  const textContent = await page.getTextContent();
330
-
331
- // 创建文本层
332
333
  const textDiv = document.createElement('div');
333
334
  textDiv.setAttribute('class', 'textLayer');
334
335
  textDiv.setAttribute('id', 'textLayer' + pageNumber);
336
+ // 关键:TextLayerBuilder 也需要传入 transform,确保文本位置正确
335
337
  let textLayer = new TextLayerBuilder({
336
338
  textLayerDiv: textDiv,
337
339
  pageIndex: pageIndex,
338
340
  viewport: viewport,
341
+ transform: transform, // 添加 transform 参数
339
342
  });
340
-
341
- // 设置文本层样式 - 移除高度限制和 overflow hidden,避免文字被裁剪
342
- textDiv.style.width = `${viewport.width}px`;
343
- // 不设置固定高度,让内容自然展开,或者设置为足够大的值
344
- // textDiv.style.height = `${viewport.height}px`; // 移除固定高度
345
- textDiv.style.minHeight = `${viewport.height}px`; // 使用最小高度
346
- textDiv.style.overflow = 'visible'; // 改为 visible,避免裁剪文字
343
+ // 使用 domWidth 和 domHeight(与 vuePdf 保持一致)
344
+ textDiv.style.width = `${domWidth}px`;
345
+ textDiv.style.height = `${domHeight}px`;
346
+ // 使用 hidden 但确保尺寸正确(与 vuePdf 保持一致)
347
+ textDiv.style.overflow = 'hidden';
347
348
  textDiv.style.whiteSpace = 'pre-wrap';
348
349
  textDiv.style.position = 'absolute';
349
350
  textDiv.style.top = '0';
350
351
  textDiv.style.left = '0';
351
352
  textDiv.style.fontSize = '20px';
352
353
  textDiv.style.color = 'black';
353
- textDiv.style.pointerEvents = 'none'; // 确保文本层不阻挡交互
354
-
355
- // 将文本 div 先添加到覆盖层中(TextLayerBuilder 需要 DOM 元素存在)
356
- let pagesDiv = document.getElementById('canvas-wrapper' + pageIndex);
357
- if (!pagesDiv) {
358
- console.warn(`Canvas wrapper not found for page ${pageNumber}`);
359
- return;
360
- }
361
- pagesDiv.appendChild(textDiv);
362
-
363
- // 设置文本内容并渲染
364
354
  textLayer.setTextContent(textContent);
365
355
  textLayer.render();
366
-
367
- // 等待文本层渲染完成(使用 nextTick 和 setTimeout 确保 DOM 完全更新)
356
+
357
+ // 渲染完成后,检查文本层实际内容高度,如果超出则调整
368
358
  await this.$nextTick();
369
- // 额外等待一小段时间,确保 TextLayerBuilder 完成渲染
370
- await new Promise(resolve => setTimeout(resolve, 50));
371
-
372
- // 确保容器有足够的高度来显示所有文本
373
- // 获取文本层的实际高度(包括所有子元素)
374
- const textLayerHeight = Math.max(
375
- textDiv.scrollHeight,
376
- textDiv.offsetHeight,
377
- viewport.height
378
- );
379
-
380
- // 如果文本层实际高度超过 viewport,调整容器和 canvas 的高度
381
- if (textLayerHeight > viewport.height) {
382
- // 调整 canvas wrapper 的最小高度
383
- if (pagesDiv) {
384
- pagesDiv.style.minHeight = `${textLayerHeight}px`;
385
- }
386
- // 调整 canvas 的显示高度(如果需要)
387
- const canvas = pageData.canvas;
388
- if (canvas && canvas.parentElement) {
389
- canvas.parentElement.style.minHeight = `${textLayerHeight}px`;
359
+ const textLayerSpans = textDiv.querySelectorAll('span');
360
+ if (textLayerSpans.length > 0) {
361
+ let maxBottom = 0;
362
+ textLayerSpans.forEach(span => {
363
+ const rect = span.getBoundingClientRect();
364
+ const parentRect = textDiv.getBoundingClientRect();
365
+ const relativeBottom = rect.bottom - parentRect.top;
366
+ if (relativeBottom > maxBottom) {
367
+ maxBottom = relativeBottom;
368
+ }
369
+ });
370
+ // 如果文本内容超出当前高度,增加文本层高度(增加一些边距)
371
+ if (maxBottom > domHeight) {
372
+ textDiv.style.height = `${Math.ceil(maxBottom + 10)}px`;
390
373
  }
391
374
  }
392
-
393
- // 在文本层渲染完成后,再渲染高亮区域
394
- // 注意:高亮是在 canvas 上绘制的,不会遮挡文本层(文本层在 canvas 上方)
395
- // 渲染已有高亮区域(静态highlights)
396
- this.renderHighlights(context, pageNumber, viewport);
397
- // 渲染搜索高亮区域
398
- this.renderSearchHighlights(context, pageNumber, viewport);
399
-
400
- // 重置重试计数
401
- this.$set(pageData, 'retryCount', 0);
402
- // 更新页面状态
403
- this.$set(pageData, 'loading', false);
404
- this.$set(pageData, 'loaded', true);
405
- }).catch((error) => {
406
- console.error(`Error rendering page ${pageNumber}:`, error);
407
- // 如果渲染失败,尝试重试
408
- if (!retry && (pageData.retryCount || 0) < maxRetries) {
409
- this.$set(pageData, 'retryCount', (pageData.retryCount || 0) + 1);
410
- this.$set(pageData, 'loading', false);
411
- // 延迟后重试
412
- setTimeout(() => {
413
- this.renderPage(pageNumber, true);
414
- }, 500);
415
- } else {
416
- // 确保在错误时也更新状态
417
- this.$set(pageData, 'loading', false);
418
- this.$set(pageData, 'loaded', false);
375
+
376
+ // 将文本 div 添加到覆盖层中
377
+ let pagesDiv = document.getElementById('canvas-wrapper' + pageIndex);
378
+ if (pagesDiv) {
379
+ pagesDiv.appendChild(textDiv);
419
380
  }
420
- });
421
- } catch (error) {
422
- console.error(`Error loading page ${pageNumber}:`, error);
423
- // 如果加载失败,尝试重试
424
- if (!retry && (pageData.retryCount || 0) < maxRetries) {
425
- this.$set(pageData, 'retryCount', (pageData.retryCount || 0) + 1);
426
- this.$set(pageData, 'loading', false);
427
- // 延迟后重试
428
- setTimeout(() => {
429
- this.renderPage(pageNumber, true);
430
- }, 500);
431
- } else {
432
- this.$set(pageData, 'loading', false);
433
- this.$set(pageData, 'loaded', false);
381
+ } catch (textError) {
382
+ console.warn(`页面 ${pageNumber} 文本层渲染失败:`, textError);
383
+ // 文本层渲染失败不影响页面继续渲染
384
+ }
385
+
386
+ // 渲染已有高亮区域(静态highlights)
387
+ // 注意:高亮是在 canvas 上绘制的,不会覆盖文本层(文本层在 canvas 上方)
388
+ // 需要传入 outputScale,因为 canvas 使用了 transform 渲染
389
+ try {
390
+ this.renderHighlights(context, pageNumber, viewport, outputScale);
391
+ } catch (highlightError) {
392
+ console.warn(`页面 ${pageNumber} 高亮渲染失败:`, highlightError);
393
+ }
394
+
395
+ // 渲染搜索高亮区域
396
+ try {
397
+ this.renderSearchHighlights(context, pageNumber, viewport, outputScale);
398
+ } catch (searchHighlightError) {
399
+ console.warn(`页面 ${pageNumber} 搜索高亮渲染失败:`, searchHighlightError);
434
400
  }
401
+
402
+ // 标记为已加载
403
+ this.$set(pageData, 'loading', false);
404
+ this.$set(pageData, 'loaded', true);
405
+ } catch (error) {
406
+ console.error(`页面 ${pageNumber} 渲染失败:`, error);
407
+ // 渲染失败时重置状态,允许重试
408
+ this.$set(pageData, 'loading', false);
409
+ this.$set(pageData, 'loaded', false);
435
410
  }
436
411
  },
437
412
  calculateScale(pdfWidth) {
438
413
  const containerWidth = document.getElementById('pdfViewPage').clientWidth - 50;
439
414
  return (containerWidth / pdfWidth) * this.scale;
440
415
  },
441
- async renderHighlights(context, number,viewport) {
416
+ async renderHighlights(context, number, viewport, outputScale = 1) {
442
417
  const pageHighlights = this.highlights.filter(item => (item.page === number ))
443
418
  let highlights = this.mergedGroups(pageHighlights);
444
419
  this.mergedGroupsList = this.mergedGroupsList.concat(highlights)
@@ -452,63 +427,60 @@ export default {
452
427
  groups.push(position.slice(i, i + 4));
453
428
  }
454
429
  for (let i = 0;i<groups.length;i++){
455
- this.drawHighlight(context, viewport, groups[i], fillStyle, false);
430
+ this.drawHighlight(context, viewport, groups[i], fillStyle, false, outputScale);
456
431
  }
457
432
  });
458
433
  }
459
434
  },
460
- renderSearchHighlights(context, pageNumber, viewport) {
435
+ renderSearchHighlights(context, pageNumber, viewport, outputScale = 1) {
461
436
  const pageHighlights = this.searchHighlights.filter(h => h.pageNumber === pageNumber);
462
437
  pageHighlights.forEach(({ position }) => {
463
- this.drawHighlight(context, viewport, position, "rgba(255, 255, 0, 0.4)", true);
438
+ this.drawHighlight(context, viewport, position, "rgba(255, 255, 0, 0.4)", true, outputScale);
464
439
  });
465
440
  },
466
- drawHighlight(context, viewport, position, fillStyle, fromSearch = false) {
467
- if (!context || !position || position.length < 4) return;
468
-
441
+ drawHighlight(context, viewport, position, fillStyle, fromSearch = false, outputScale = 1) {
469
442
  const [x1, y1, x2, y2] = position;
443
+ // 使用 viewport.scale 计算 PDF 坐标到 viewport 坐标的转换
470
444
  const scale = viewport.scale;
445
+ // PDF 页面的实际高度(未缩放)
471
446
  const pageHeight = viewport.height / viewport.scale;
472
447
 
473
- let canvasX1 = x1 * scale;
474
- let canvasX2 = x2 * scale;
475
- let canvasY1, canvasY2;
448
+ // 计算在 viewport 坐标系中的位置(PDF 坐标 → viewport 坐标)
449
+ let viewportX1 = x1 * scale;
450
+ let viewportX2 = x2 * scale;
451
+ let viewportY1, viewportY2;
476
452
 
477
453
  if (fromSearch) {
478
- // 搜索高亮:PDF坐标系(左下原点)
479
- canvasY1 = (pageHeight - y1) * scale;
480
- canvasY2 = (pageHeight - y2) * scale;
454
+ // 搜索高亮:PDF坐标系(左下原点),需要转换为顶部原点
455
+ viewportY1 = (pageHeight - y1) * scale;
456
+ viewportY2 = (pageHeight - y2) * scale;
481
457
  } else {
482
- // 静态 highlights 假设顶部坐标原点不需翻转
483
- canvasY1 = y1 * scale;
484
- canvasY2 = y2 * scale;
458
+ // 静态 highlights:顶部坐标原点,直接使用
459
+ viewportY1 = y1 * scale;
460
+ viewportY2 = y2 * scale;
485
461
  }
486
462
 
487
- // 确保坐标在有效范围内
488
- const minX = Math.min(canvasX1, canvasX2);
489
- const minY = Math.min(canvasY1, canvasY2);
490
- const width = Math.abs(canvasX2 - canvasX1);
491
- const height = Math.abs(canvasY2 - canvasY1);
463
+ // 由于 canvas 使用了 transform 渲染,PDF.js 会在内部应用 transform
464
+ // context 的坐标系统是 canvas 的实际尺寸(viewport.width * outputScale)
465
+ // viewport 坐标是基于 viewport.width 的,所以需要转换为 canvas 坐标
466
+ // 注意:outputScale viewport.scale 是相同的值,所以这里只需要乘以 outputScale
467
+ // 但实际上 viewport.scale 已经应用了,所以这里应该直接使用 viewport 坐标
468
+ // 但 canvas 的实际尺寸是 viewport.width * outputScale,所以需要缩放
469
+ let canvasX1 = viewportX1 * outputScale;
470
+ let canvasX2 = viewportX2 * outputScale;
471
+ let canvasY1 = viewportY1 * outputScale;
472
+ let canvasY2 = viewportY2 * outputScale;
492
473
 
493
- // 检查坐标是否在 canvas 范围内
494
- if (minX < 0 || minY < 0 || minX + width > viewport.width || minY + height > viewport.height) {
495
- // 如果超出范围,进行裁剪
496
- const clippedX = Math.max(0, minX);
497
- const clippedY = Math.max(0, minY);
498
- const clippedWidth = Math.min(width, viewport.width - clippedX);
499
- const clippedHeight = Math.min(height, viewport.height - clippedY);
500
-
501
- if (clippedWidth > 0 && clippedHeight > 0) {
502
- context.beginPath();
503
- context.fillStyle = fillStyle;
504
- context.fillRect(clippedX, clippedY, clippedWidth, clippedHeight);
505
- }
506
- } else {
507
- // 正常绘制
508
- context.beginPath();
509
- context.fillStyle = fillStyle;
510
- context.fillRect(minX, minY, width, height);
511
- }
474
+ // 清除当前路径
475
+ context.beginPath();
476
+
477
+ context.fillStyle = fillStyle;
478
+ context.fillRect(
479
+ Math.min(canvasX1, canvasX2),
480
+ Math.min(canvasY1, canvasY2),
481
+ Math.abs(canvasX2 - canvasX1),
482
+ Math.abs(canvasY2 - canvasY1)
483
+ );
512
484
  },
513
485
  handleFileUpload(event) {
514
486
  const file = event.target.files[0];
@@ -519,27 +491,26 @@ export default {
519
491
  }
520
492
  },
521
493
  async setCanvasRef() {
522
- // 使用 $nextTick 确保 DOM 已更新
494
+ // 等待 DOM 完全更新
523
495
  await this.$nextTick();
524
-
525
- // 如果 refs 还没有准备好,等待一段时间后重试
526
- if (!this.$refs.canvases || this.$refs.canvases.length === 0) {
527
- return new Promise((resolve) => {
528
- setTimeout(async () => {
529
- await this.setCanvasRef();
530
- resolve();
531
- }, 100);
532
- });
496
+
497
+ if (!this.$refs.canvases || !Array.isArray(this.$refs.canvases)) {
498
+ console.warn('Canvas 引用未准备好,延迟重试');
499
+ // 如果 canvas 引用还没准备好,延迟重试
500
+ setTimeout(() => {
501
+ this.setCanvasRef();
502
+ }, 100);
503
+ return;
533
504
  }
534
-
535
- // 设置 canvas 引用
536
- this.pages.forEach((page, index) => {
505
+
506
+ // 确保所有 canvas 引用都已设置
507
+ for (let index = 0; index < this.pages.length; index++) {
537
508
  if (this.$refs.canvases && this.$refs.canvases[index]) {
538
509
  this.$set(this.pages[index], 'canvas', this.$refs.canvases[index]);
539
510
  } else {
540
- console.warn(`Canvas ref not found for page ${index + 1}`);
511
+ console.warn(`页面 ${index + 1} 的 canvas 引用不存在`);
541
512
  }
542
- });
513
+ }
543
514
  },
544
515
  clearPages() {
545
516
  this.pages = [];
@@ -621,8 +592,7 @@ export default {
621
592
  zoomIn() {
622
593
  this.updateCurrentPage();
623
594
  // 检查是否有页面正在加载
624
- const hasLoadingPage = this.pages.some(p => p.loading);
625
- if (hasLoadingPage) return;
595
+ if (this.pages.some(p => p.loading)) return;
626
596
  const container = this.$refs.pdfContainer;
627
597
  const currentScroll = container.scrollTop;
628
598
  this.scale += 0.1;
@@ -631,8 +601,7 @@ export default {
631
601
  zoomOut() {
632
602
  this.updateCurrentPage();
633
603
  // 检查是否有页面正在加载
634
- const hasLoadingPage = this.pages.some(p => p.loading);
635
- if (hasLoadingPage) return;
604
+ if (this.pages.some(p => p.loading)) return;
636
605
  const container = this.$refs.pdfContainer;
637
606
  const currentScroll = container.scrollTop;
638
607
  this.scale = Math.max(this.scale - 0.1, 0.1);
@@ -642,11 +611,10 @@ export default {
642
611
  const pages = Vue.observable(this.pages)
643
612
  pages.forEach((p) => {
644
613
  p.loaded = false;
645
- this.$set(p, 'loading', false);
646
- this.$set(p, 'retryCount', 0);
614
+ this.$set(p,'loading',false)
647
615
  if (p.canvas) {
648
616
  const ctx = p.canvas.getContext('2d');
649
- ctx.clearRect(0, 0, p.canvas.width, p.canvas.height);
617
+ ctx.clearRect(0,0,p.canvas.width,p.canvas.height);
650
618
  }
651
619
  });
652
620
 
@@ -679,8 +647,7 @@ export default {
679
647
  async doSearch() {
680
648
  if (!this.pdf || !this.searchQuery) return;
681
649
  // 检查是否有页面正在加载
682
- const hasLoadingPage = this.pages.some(p => p.loading);
683
- if (hasLoadingPage) return;
650
+ if (this.pages.some(p => p.loading)) return;
684
651
 
685
652
  this.searchHighlights = [];
686
653
  const numPages = this.numPages;
@@ -743,8 +710,7 @@ export default {
743
710
  const currentScroll = container.scrollTop;
744
711
  this.pages.forEach((p) => {
745
712
  p.loaded = false;
746
- this.$set(p, 'loading', false);
747
- this.$set(p, 'retryCount', 0);
713
+ this.$set(p,'loading',false)
748
714
  if (p.canvas) {
749
715
  const ctx = p.canvas.getContext("2d");
750
716
  ctx.clearRect(0, 0, p.canvas.width, p.canvas.height);
@@ -775,18 +741,16 @@ export default {
775
741
  clearTimeout(this.resizeTimeout);
776
742
  this.resizeTimeout = setTimeout(() => {
777
743
  // 检查是否有页面正在加载
778
- const hasLoadingPage = this.pages.some(p => p.loading);
779
- if (hasLoadingPage) return;
744
+ if (this.pages.some(p => p.loading)) return;
780
745
  const container = this.$refs.pdfContainer;
781
746
  const currentScroll = container.scrollTop;
782
747
  const pages = Vue.observable(this.pages)
783
748
  pages.forEach((p) => {
784
749
  p.loaded = false;
785
- this.$set(p, 'loading', false);
786
- this.$set(p, 'retryCount', 0);
750
+ this.$set(p,'loading',false)
787
751
  if (p.canvas) {
788
752
  const ctx = p.canvas.getContext('2d');
789
- ctx.clearRect(0, 0, p.canvas.width, p.canvas.height);
753
+ ctx.clearRect(0,0,p.canvas.width,p.canvas.height);
790
754
  }
791
755
  });
792
756
  this.$nextTick(() => {
@@ -874,15 +838,11 @@ export default {
874
838
  display: flex;
875
839
  justify-content: center;
876
840
  width: 100%;
877
- min-height: fit-content; /* 确保容器能容纳所有内容 */
878
- overflow: visible; /* 允许内容超出,避免裁剪 */
879
841
  }
880
842
 
881
843
  .canvas-wrapper {
882
844
  position: relative;
883
845
  width: 100%;
884
- min-height: 100%; /* 确保容器有足够高度 */
885
- overflow: visible; /* 允许内容超出,避免裁剪 */
886
846
  }
887
847
 
888
848
  /* 在loading时覆盖canvas显示加载动画 */