@libresign/pdf-elements 0.2.3 → 0.2.5

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.
@@ -24,7 +24,8 @@ export default {
24
24
  return {
25
25
  dynamicScale: this.scale,
26
26
  isRendering: false,
27
- boundMeasure: null,
27
+ pendingRender: false,
28
+ renderTask: null,
28
29
  }
29
30
  },
30
31
  watch: {
@@ -34,13 +35,16 @@ export default {
34
35
  },
35
36
  },
36
37
  mounted() {
37
- this.boundMeasure = this.measure.bind(this)
38
- window.addEventListener('resize', this.boundMeasure)
39
38
  this.render()
40
39
  },
41
40
  beforeUnmount() {
42
- if (this.boundMeasure) {
43
- window.removeEventListener('resize', this.boundMeasure)
41
+ if (this.renderTask) {
42
+ try {
43
+ this.renderTask.cancel()
44
+ } catch (e) {
45
+ // Ignore render cancellation errors.
46
+ }
47
+ this.renderTask = null
44
48
  }
45
49
  },
46
50
  methods: {
@@ -56,24 +60,43 @@ export default {
56
60
  })
57
61
  },
58
62
  async render() {
59
- if (this.isRendering) return
63
+ if (this.isRendering) {
64
+ this.pendingRender = true
65
+ return
66
+ }
60
67
  this.isRendering = true
68
+ this.pendingRender = false
61
69
  try {
62
70
  const _page = await this.page
63
71
  const canvas = this.$refs.canvas
72
+ if (!canvas) return
73
+ if (this.renderTask) {
74
+ try {
75
+ this.renderTask.cancel()
76
+ } catch (e) {
77
+ // Ignore render cancellation errors.
78
+ }
79
+ this.renderTask = null
80
+ }
64
81
  const context = canvas.getContext('2d')
65
82
  const viewport = _page.getViewport({
66
83
  scale: this.dynamicScale,
67
84
  })
68
85
  canvas.width = viewport.width
69
86
  canvas.height = viewport.height
70
- await _page.render({
87
+ this.renderTask = _page.render({
71
88
  canvasContext: context,
72
89
  viewport,
73
- }).promise
90
+ })
91
+ await this.renderTask.promise
74
92
  this.measure()
75
93
  } finally {
76
94
  this.isRendering = false
95
+ this.renderTask = null
96
+ if (this.pendingRender) {
97
+ this.pendingRender = false
98
+ this.render()
99
+ }
77
100
  }
78
101
  },
79
102
  },
package/src/index.js CHANGED
@@ -1,11 +1,6 @@
1
1
  // SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
2
2
  // SPDX-License-Identifier: AGPL-3.0-or-later
3
3
 
4
- import { GlobalWorkerOptions } from 'pdfjs-dist'
5
- import pdfWorkerCode from 'pdfjs-dist/build/pdf.worker.min.mjs'
6
-
7
- GlobalWorkerOptions.workerSrc = pdfWorkerCode
8
-
9
4
  import PDFElements from './components/PDFElements.vue'
10
5
  export { setWorkerPath } from './utils/asyncReader.js'
11
6
 
@@ -0,0 +1,20 @@
1
+ // SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
2
+ // SPDX-License-Identifier: AGPL-3.0-or-later
3
+
4
+ export function clampPosition(x, y, width, height, pageWidth, pageHeight) {
5
+ return {
6
+ x: Math.max(0, Math.min(x, pageWidth - width)),
7
+ y: Math.max(0, Math.min(y, pageHeight - height)),
8
+ }
9
+ }
10
+
11
+ export function getVisibleArea(newX, newY, objWidth, objHeight, pageWidth, pageHeight) {
12
+ const visibleLeft = Math.max(0, newX)
13
+ const visibleTop = Math.max(0, newY)
14
+ const visibleRight = Math.min(pageWidth, newX + objWidth)
15
+ const visibleBottom = Math.min(pageHeight, newY + objHeight)
16
+ if (visibleRight <= visibleLeft || visibleBottom <= visibleTop) {
17
+ return 0
18
+ }
19
+ return (visibleRight - visibleLeft) * (visibleBottom - visibleTop)
20
+ }
@@ -0,0 +1,16 @@
1
+ // SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
2
+ // SPDX-License-Identifier: AGPL-3.0-or-later
3
+
4
+ export function getCachedMeasurement(cache, cacheKey, pageRef, pagesScale) {
5
+ const cached = cache[cacheKey]
6
+ if (cached) {
7
+ return cached
8
+ }
9
+ const measurement = pageRef.getCanvasMeasurement()
10
+ const normalized = {
11
+ width: measurement.canvasWidth / pagesScale,
12
+ height: measurement.canvasHeight / pagesScale,
13
+ }
14
+ cache[cacheKey] = normalized
15
+ return normalized
16
+ }
@@ -0,0 +1,35 @@
1
+ // SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
2
+ // SPDX-License-Identifier: AGPL-3.0-or-later
3
+
4
+ export function objectIdExistsInDoc(doc, objectId) {
5
+ if (!doc || !objectId) return false
6
+ return doc.allObjects.some((objects) => objects.some((obj) => obj.id === objectId))
7
+ }
8
+
9
+ export function findObjectPageIndex(doc, objectId) {
10
+ if (!doc || !objectId) return undefined
11
+ for (let pageIndex = 0; pageIndex < doc.allObjects.length; pageIndex++) {
12
+ if (doc.allObjects[pageIndex].some((obj) => obj.id === objectId)) {
13
+ return pageIndex
14
+ }
15
+ }
16
+ return undefined
17
+ }
18
+
19
+ export function updateObjectInDoc(doc, pageIndex, objectId, payload) {
20
+ const objects = doc?.allObjects?.[pageIndex]
21
+ if (!objects) return false
22
+ const objectIndex = objects.findIndex((obj) => obj.id === objectId)
23
+ if (objectIndex === -1) return false
24
+ objects.splice(objectIndex, 1, { ...objects[objectIndex], ...payload })
25
+ return true
26
+ }
27
+
28
+ export function removeObjectFromDoc(doc, pageIndex, objectId) {
29
+ const objects = doc?.allObjects?.[pageIndex]
30
+ if (!objects) return false
31
+ const objectIndex = objects.findIndex((obj) => obj.id === objectId)
32
+ if (objectIndex === -1) return false
33
+ objects.splice(objectIndex, 1)
34
+ return true
35
+ }
@@ -0,0 +1,13 @@
1
+ // SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
2
+ // SPDX-License-Identifier: AGPL-3.0-or-later
3
+
4
+ export function getViewportWindow(scrollTop, viewHeight, margin = 300) {
5
+ return {
6
+ minY: Math.max(0, scrollTop - margin),
7
+ maxY: scrollTop + viewHeight + margin,
8
+ }
9
+ }
10
+
11
+ export function isPageInViewport(offsetTop, offsetHeight, minY, maxY) {
12
+ return !(offsetTop + offsetHeight < minY || offsetTop > maxY)
13
+ }
@@ -0,0 +1,8 @@
1
+ // SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
2
+ // SPDX-License-Identifier: AGPL-3.0-or-later
3
+
4
+ export function applyScaleToDocs(docs, scale) {
5
+ docs.forEach((doc) => {
6
+ doc.pagesScale = doc.pagesScale.map(() => scale)
7
+ })
8
+ }