Skip to content

Commit c42a34f

Browse files
authored
Merge pull request #8 from LibreSign/feat/auto-fit-zoom
feat: auto fit zoom
2 parents 33fe410 + a1aaa2e commit c42a34f

4 files changed

Lines changed: 49 additions & 14 deletions

File tree

.github/workflows/node.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ jobs:
4646
env:
4747
CYPRESS_INSTALL_BINARY: 0
4848
PUPPETEER_SKIP_DOWNLOAD: true
49-
run: npm ci
49+
run: npm i
5050

5151
- name: Lint
5252
run: npm run lint

README.md

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,19 @@ A Vue 2 component for rendering PDFs with draggable and resizable element overla
1313

1414
### Props
1515

16-
| Prop | Type | Default |
17-
|------|------|---------|
18-
| `width` | String | `'100%'` |
19-
| `height` | String | `'100%'` |
20-
| `initFiles` | Array | `[]` |
21-
| `initFileNames` | Array | `[]` |
22-
| `initialScale` | Number | `1` |
23-
| `showPageFooter` | Boolean | `true` |
24-
| `hideSelectionUI` | Boolean | `false` |
25-
| `showSelectionHandles` | Boolean | `true` |
26-
| `showElementActions` | Boolean | `true` |
27-
| `pageCountFormat` | String | `'{currentPage} of {totalPages}'` |
16+
| Prop | Type | Default | Description |
17+
|------|------|---------|-------------|
18+
| `width` | String | `'100%'` | Container width |
19+
| `height` | String | `'100%'` | Container height |
20+
| `initFiles` | Array | `[]` | PDF files to load |
21+
| `initFileNames` | Array | `[]` | Names for the PDF files |
22+
| `initialScale` | Number | `1` | Initial zoom scale |
23+
| `showPageFooter` | Boolean | `true` | Show page footer with document name and page number |
24+
| `hideSelectionUI` | Boolean | `false` | Hide selection handles and actions UI |
25+
| `showSelectionHandles` | Boolean | `true` | Show resize/move handles on selected elements |
26+
| `showElementActions` | Boolean | `true` | Show action buttons on selected elements |
27+
| `pageCountFormat` | String | `'{currentPage} of {totalPages}'` | Format string for page counter |
28+
| `autoFitZoom` | Boolean | `false` | Automatically adjust zoom to fit viewport on window resize |
2829

2930
### Events
3031

@@ -35,3 +36,4 @@ A Vue 2 component for rendering PDFs with draggable and resizable element overla
3536
- `element-{type}` - Custom element rendering (e.g., `element-signature`)
3637
- `custom` - Fallback for elements without specific type
3738
- `actions` - Custom action buttons
39+

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@libresign/pdf-elements",
33
"description": "PDF viewer with draggable and resizable element overlays for Vue 2",
4-
"version": "0.1.2",
4+
"version": "0.2.0",
55
"author": "LibreCode <contact@librecode.coop>",
66
"private": false,
77
"main": "dist/pdf-elements.umd.js",

src/components/PDFElements.vue

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,10 @@ export default {
179179
type: String,
180180
default: '{currentPage} of {totalPages}',
181181
},
182+
autoFitZoom: {
183+
type: Boolean,
184+
default: false,
185+
},
182186
},
183187
data() {
184188
return {
@@ -224,6 +228,9 @@ export default {
224228
window.addEventListener('resize', this.onViewportScroll)
225229
this.$el?.addEventListener('scroll', this.onViewportScroll, { passive: true })
226230
this.$el?.addEventListener('wheel', this.boundHandleWheel, { passive: false })
231+
if (this.autoFitZoom) {
232+
window.addEventListener('resize', this.adjustZoomToFit)
233+
}
227234
},
228235
beforeUnmount() {
229236
if (this.zoomRafId) {
@@ -241,6 +248,9 @@ export default {
241248
window.removeEventListener('scroll', this.onViewportScroll)
242249
window.removeEventListener('resize', this.onViewportScroll)
243250
this.$el?.removeEventListener('scroll', this.onViewportScroll)
251+
if (this.autoFitZoom) {
252+
window.removeEventListener('resize', this.adjustZoomToFit)
253+
}
244254
if (this.viewportRafId) {
245255
window.cancelAnimationFrame(this.viewportRafId)
246256
this.viewportRafId = 0
@@ -804,6 +814,29 @@ export default {
804814
const pagesScale = doc.pagesScale[pageIndex] || 1
805815
return pageRef.getCanvasMeasurement().canvasHeight / pagesScale
806816
},
817+
calculateOptimalScale(maxPageWidth) {
818+
const containerWidth = this.$el?.clientWidth || 0
819+
if (!containerWidth || !maxPageWidth) return 1
820+
821+
const availableWidth = containerWidth - 40
822+
return Math.max(0.1, Math.min(2, availableWidth / maxPageWidth))
823+
},
824+
adjustZoomToFit() {
825+
if (!this.autoFitZoom || !this.pdfDocuments.length) return
826+
827+
const canvases = this.$el?.querySelectorAll('canvas')
828+
if (!canvases?.length) return
829+
830+
const maxCanvasWidth = Math.max(...Array.from(canvases).map(canvas =>
831+
canvas.width / (this.scale || 1),
832+
))
833+
834+
const optimalScale = this.calculateOptimalScale(maxCanvasWidth)
835+
if (Math.abs(optimalScale - this.scale) > 0.01) {
836+
this.scale = optimalScale
837+
this.visualScale = optimalScale
838+
}
839+
},
807840
},
808841
}
809842
</script>

0 commit comments

Comments
 (0)