@libresign/pdf-elements 0.2.4 → 0.3.0
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.
- package/README.md +1 -1
- package/dist/pdf-elements.common.js +25126 -24680
- package/dist/pdf-elements.common.js.map +1 -1
- package/dist/pdf-elements.css +1 -1
- package/dist/pdf-elements.umd.js +25126 -24680
- package/dist/pdf-elements.umd.js.map +1 -1
- package/dist/pdf-elements.umd.min.js +2 -2
- package/dist/pdf-elements.umd.min.js.map +1 -1
- package/package.json +1 -2
- package/src/components/DraggableElement.vue +29 -5
- package/src/components/PDFElements.vue +389 -173
- package/src/components/PDFPage.vue +31 -8
- package/src/index.js +0 -5
- package/src/utils/geometry.js +20 -0
- package/src/utils/measurements.js +16 -0
- package/src/utils/objectStore.js +35 -0
- package/src/utils/pageBounds.js +13 -0
- package/src/utils/zoom.js +8 -0
|
@@ -24,7 +24,8 @@ export default {
|
|
|
24
24
|
return {
|
|
25
25
|
dynamicScale: this.scale,
|
|
26
26
|
isRendering: false,
|
|
27
|
-
|
|
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.
|
|
43
|
-
|
|
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)
|
|
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
|
-
|
|
87
|
+
this.renderTask = _page.render({
|
|
71
88
|
canvasContext: context,
|
|
72
89
|
viewport,
|
|
73
|
-
})
|
|
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
|
+
}
|