@@ -138,6 +138,11 @@ SPDX-License-Identifier: AGPL-3.0-or-later
138138import PDFPage from ' ./PDFPage.vue'
139139import DraggableElement from ' ./DraggableElement.vue'
140140import { readAsPDF , readAsArrayBuffer } from ' ../utils/asyncReader.js'
141+ import { clampPosition , getVisibleArea } from ' ../utils/geometry.js'
142+ import { getViewportWindow , isPageInViewport } from ' ../utils/pageBounds.js'
143+ import { applyScaleToDocs } from ' ../utils/zoom.js'
144+ import { objectIdExistsInDoc , findObjectPageIndex , updateObjectInDoc , removeObjectFromDoc } from ' ../utils/objectStore.js'
145+ import { getCachedMeasurement } from ' ../utils/measurements.js'
141146
142147export default {
143148 name: ' PDFElements' ,
@@ -238,9 +243,11 @@ export default {
238243 }
239244 },
240245 created () {
241- this ._pagesBoundingRects = {}
242- this ._pagesBoundingRectsList = []
243- this ._pageMeasurementCache = {}
246+ this ._pagesBoundingRects = {}
247+ this ._pagesBoundingRectsList = []
248+ this ._pageMeasurementCache = {}
249+ this ._lastPageBoundsScrollTop = 0
250+ this ._lastPageBoundsClientHeight = 0
244251 },
245252 mounted () {
246253 this .boundHandleWheel = this .handleWheel .bind (this )
@@ -436,8 +443,14 @@ export default {
436443 const container = this .$el
437444 const scrollTop = container? .scrollTop || 0
438445 const viewHeight = container? .clientHeight || 0
439- const minY = Math .max (0 , scrollTop - 300 )
440- const maxY = scrollTop + viewHeight + 300
446+ if (! this .isAddingMode && ! this .isDraggingElement &&
447+ scrollTop === this ._lastPageBoundsScrollTop &&
448+ viewHeight === this ._lastPageBoundsClientHeight ) {
449+ return
450+ }
451+ this ._lastPageBoundsScrollTop = scrollTop
452+ this ._lastPageBoundsClientHeight = viewHeight
453+ const { minY , maxY } = getViewportWindow (scrollTop, viewHeight)
441454 for (let docIdx = 0 ; docIdx < this .pdfDocuments .length ; docIdx++ ) {
442455 for (let pageIdx = 0 ; pageIdx < this .pdfDocuments [docIdx].pages .length ; pageIdx++ ) {
443456 const canvas = this .getPageCanvasElement (docIdx, pageIdx)
@@ -446,7 +459,7 @@ export default {
446459 const wrapper = canvas .closest (' .page-wrapper' ) || canvas
447460 const offsetTop = wrapper .offsetTop || 0
448461 const offsetHeight = wrapper .offsetHeight || 0
449- if (offsetTop + offsetHeight < minY || offsetTop > maxY) {
462+ if (! isPageInViewport ( offsetTop, offsetHeight, minY, maxY) ) {
450463 continue
451464 }
452465 }
@@ -657,9 +670,7 @@ export default {
657670
658671 this .scale = newScale
659672
660- this .pdfDocuments .forEach ((doc ) => {
661- doc .pagesScale = doc .pagesScale .map (() => this .scale )
662- })
673+ applyScaleToDocs (this .pdfDocuments , this .scale )
663674
664675 this ._pageMeasurementCache = {}
665676 this .cachePageBounds ()
@@ -765,24 +776,15 @@ export default {
765776 const cacheKey = ` ${ docIndex} -${ objectId} `
766777 if (this .objectIndexCache [cacheKey] !== undefined ) return true
767778 const doc = this .pdfDocuments [docIndex]
768- if (! doc) return false
769- return doc .allObjects .some (objects => objects .some (obj => obj .id === objectId))
779+ return objectIdExistsInDoc (doc, objectId)
770780 },
771781 updateObjectInPage (docIndex , pageIndex , objectId , payload ) {
772782 const doc = this .pdfDocuments [docIndex]
773- const objects = doc? .allObjects ? .[pageIndex]
774- if (! objects) return
775- const objectIndex = objects .findIndex (object => object .id === objectId)
776- if (objectIndex === - 1 ) return
777- objects .splice (objectIndex, 1 , { ... objects[objectIndex], ... payload })
783+ updateObjectInDoc (doc, pageIndex, objectId, payload)
778784 },
779785 removeObjectFromPage (docIndex , pageIndex , objectId ) {
780786 const doc = this .pdfDocuments [docIndex]
781- const objects = doc? .allObjects ? .[pageIndex]
782- if (! objects) return
783- const objectIndex = objects .findIndex (object => object .id === objectId)
784- if (objectIndex === - 1 ) return
785- objects .splice (objectIndex, 1 )
787+ removeObjectFromDoc (doc, pageIndex, objectId)
786788 },
787789
788790 getAllObjects (docIndex = this .selectedDocIndex ) {
@@ -826,12 +828,10 @@ export default {
826828 let currentPageIndex = this .objectIndexCache [cacheKey]
827829
828830 if (currentPageIndex === undefined ) {
829- doc .allObjects .forEach ((objects , pIndex ) => {
830- if (objects .find (o => o .id === objectId)) {
831- currentPageIndex = pIndex
832- this .objectIndexCache [cacheKey] = pIndex
833- }
834- })
831+ currentPageIndex = findObjectPageIndex (doc, objectId)
832+ if (currentPageIndex !== undefined ) {
833+ this .objectIndexCache [cacheKey] = currentPageIndex
834+ }
835835 }
836836
837837 if (currentPageIndex === undefined ) return
@@ -880,7 +880,7 @@ export default {
880880 const pageWidth = this .getPageWidth (docIndex, pIndex)
881881 const pageHeight = this .getPageHeight (docIndex, pIndex)
882882
883- const visibleArea = this . getVisibleArea (newX, newY, objWidth, objHeight, pageWidth, pageHeight)
883+ const visibleArea = getVisibleArea (newX, newY, objWidth, objHeight, pageWidth, pageHeight)
884884 if (visibleArea > maxVisibleArea) {
885885 maxVisibleArea = visibleArea
886886 bestPageIndex = pIndex
@@ -889,7 +889,7 @@ export default {
889889
890890 if (bestPageIndex !== currentPageIndex) {
891891 const { width: pageWidth , height: pageHeight } = this .getPageSize (docIndex, bestPageIndex)
892- const { x: adjustedX , y: adjustedY } = this . clampPosition (newX, newY, objWidth, objHeight, pageWidth, pageHeight)
892+ const { x: adjustedX , y: adjustedY } = clampPosition (newX, newY, objWidth, objHeight, pageWidth, pageHeight)
893893
894894 this .removeObjectFromPage (docIndex, currentPageIndex, objectId)
895895 const updatedObject = {
@@ -949,12 +949,10 @@ export default {
949949 let currentPageIndex = this .objectIndexCache [cacheKey]
950950
951951 if (currentPageIndex === undefined ) {
952- doc .allObjects .forEach ((objects , pIndex ) => {
953- if (objects .find (o => o .id === objectId)) {
954- currentPageIndex = pIndex
955- this .objectIndexCache [cacheKey] = pIndex
956- }
957- })
952+ currentPageIndex = findObjectPageIndex (doc, objectId)
953+ if (currentPageIndex !== undefined ) {
954+ this .objectIndexCache [cacheKey] = currentPageIndex
955+ }
958956 }
959957
960958 if (currentPageIndex === undefined ) return undefined
@@ -982,7 +980,7 @@ export default {
982980 const relY = (mouseY - targetPageRect .top - this .draggingElementShift .y ) / pagesScale - (this .draggingInitialMouseOffset .y / pagesScale)
983981
984982 const { width: pageWidth , height: pageHeight } = this .getPageSize (docIndex, targetPageIndex)
985- const { x: clampedX , y: clampedY } = this . clampPosition (
983+ const { x: clampedX , y: clampedY } = clampPosition (
986984 relX,
987985 relY,
988986 targetObject .width ,
@@ -1039,37 +1037,11 @@ export default {
10391037 height: this .getPageHeight (docIndex, pageIndex),
10401038 }
10411039 },
1042- clampPosition (x , y , width , height , pageWidth , pageHeight ) {
1043- return {
1044- x: Math .max (0 , Math .min (x, pageWidth - width)),
1045- y: Math .max (0 , Math .min (y, pageHeight - height)),
1046- }
1047- },
1048- getVisibleArea (newX , newY , objWidth , objHeight , pageWidth , pageHeight ) {
1049- const visibleLeft = Math .max (0 , newX)
1050- const visibleTop = Math .max (0 , newY)
1051- const visibleRight = Math .min (pageWidth, newX + objWidth)
1052- const visibleBottom = Math .min (pageHeight, newY + objHeight)
1053- if (visibleRight <= visibleLeft || visibleBottom <= visibleTop) {
1054- return 0
1055- }
1056- return (visibleRight - visibleLeft) * (visibleBottom - visibleTop)
1057- },
10581040 getCachedMeasurement (docIndex , pageIndex , pageRef ) {
10591041 const cacheKey = ` ${ docIndex} -${ pageIndex} `
1060- const cached = this ._pageMeasurementCache [cacheKey]
1061- if (cached) {
1062- return cached
1063- }
10641042 const doc = this .pdfDocuments [docIndex]
10651043 const pagesScale = doc .pagesScale [pageIndex] || 1
1066- const measurement = pageRef .getCanvasMeasurement ()
1067- const normalized = {
1068- width: measurement .canvasWidth / pagesScale,
1069- height: measurement .canvasHeight / pagesScale,
1070- }
1071- this ._pageMeasurementCache [cacheKey] = normalized
1072- return normalized
1044+ return getCachedMeasurement (this ._pageMeasurementCache , cacheKey, pageRef, pagesScale)
10731045 },
10741046 calculateOptimalScale (maxPageWidth ) {
10751047 const containerWidth = this .$el ? .clientWidth || 0
@@ -1113,9 +1085,7 @@ export default {
11131085 if (Math .abs (optimalScale - this .scale ) > 0.01 ) {
11141086 this .scale = optimalScale
11151087 this .visualScale = optimalScale
1116- this .pdfDocuments .forEach ((doc ) => {
1117- doc .pagesScale = doc .pagesScale .map (() => this .scale )
1118- })
1088+ applyScaleToDocs (this .pdfDocuments , this .scale )
11191089 this ._pageMeasurementCache = {}
11201090 this .cachePageBounds ()
11211091 }
0 commit comments