Skip to content

Commit 1526a35

Browse files
authored
Refresh annotations on scale change. (#153)
1 parent 75a4623 commit 1526a35

File tree

1 file changed

+52
-29
lines changed

1 file changed

+52
-29
lines changed

src/components/PdfProvider/PdfProvider.tsx

Lines changed: 52 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,11 @@ export function PdfProvider({ pdfUrl, children }: IPdfProviderProps) {
127127
saveThemeSettingToLocalStorage(theme);
128128
}, [theme]);
129129

130-
useScrolling({
130+
usePageOffsets({
131+
viewer,
132+
services,
131133
pageOffsets,
132134
setVisiblePages,
133-
viewer,
134135
});
135136

136137
const context = useMemo(
@@ -182,49 +183,56 @@ function useScaleUpdater({
182183
}, [viewer, setScale]);
183184
}
184185

185-
function useScrolling({
186+
function usePageOffsets({
186187
viewer,
188+
services,
187189
setVisiblePages,
188190
pageOffsets,
189191
}: {
190192
viewer?: pdfJsViewer.PDFViewer;
193+
services: IPdfServices;
191194
setVisiblePages: Dispatch<SetStateAction<number[]>>;
192195
pageOffsets: MutableRefObject<DOMRect[]>;
193196
}) {
194-
const handleViewChanged = useCallback(() => {
195-
// TODO [ToDr] throttle?
196-
if (!viewer) return;
197+
const handleViewChanged = useCallback(
198+
(forceUpdate: boolean) => {
199+
// TODO [ToDr] throttle?
200+
if (!viewer) return;
197201

198-
const visiblePagesAfterEvent: number[] = [];
202+
const visiblePagesAfterEvent: number[] = [];
199203

200-
for (let i = 0; i < viewer.pagesCount; i++) {
201-
if (isPartlyInViewport(viewer.getPageView(i).div.getBoundingClientRect())) {
202-
visiblePagesAfterEvent.push(i + 1); // using page numbers instead of indices
204+
for (let i = 0; i < viewer.pagesCount; i++) {
205+
if (isPartlyInViewport(viewer.getPageView(i).div.getBoundingClientRect())) {
206+
visiblePagesAfterEvent.push(i + 1); // using page numbers instead of indices
207+
}
203208
}
204-
}
205209

206-
setVisiblePages((visiblePages) => {
207-
if (visiblePages.join(";") !== visiblePagesAfterEvent.join(";")) {
208-
return visiblePagesAfterEvent;
209-
}
210-
return visiblePages;
211-
});
210+
setVisiblePages((visiblePages) => {
211+
if (forceUpdate || visiblePages.join(";") !== visiblePagesAfterEvent.join(";")) {
212+
return visiblePagesAfterEvent;
213+
}
214+
return visiblePages;
215+
});
212216

213-
for (let page = 1; page <= viewer.pagesCount; page++) {
214-
const pageElement = viewer.getPageView(page - 1)?.div;
217+
for (let page = 1; page <= viewer.pagesCount; page++) {
218+
const pageElement = viewer.getPageView(page - 1)?.div;
215219

216-
pageOffsets.current[page] = subtractBorder(
217-
new DOMRect(pageElement.offsetLeft, pageElement.offsetTop, pageElement.offsetWidth, pageElement.offsetHeight),
218-
pageElement,
219-
);
220-
}
221-
}, [viewer, setVisiblePages, pageOffsets]);
220+
pageOffsets.current[page] = subtractBorder(
221+
new DOMRect(pageElement.offsetLeft, pageElement.offsetTop, pageElement.offsetWidth, pageElement.offsetHeight),
222+
pageElement,
223+
);
224+
}
225+
},
226+
[viewer, setVisiblePages, pageOffsets],
227+
);
222228

223229
// update page offsets on scroll or resize
224230
useEffect(() => {
225231
if (!viewer?.container) return;
226232

227-
const handler = handleViewChanged;
233+
// in case of scroll we don't want to force the update.
234+
// the page offsets do not really changed.
235+
const handler = () => handleViewChanged(false);
228236
const resizeObserver = new ResizeObserver(handler);
229237

230238
viewer.container.addEventListener("scroll", handler);
@@ -236,8 +244,23 @@ function useScrolling({
236244
};
237245
}, [viewer, handleViewChanged]);
238246

247+
// update page offsets when scale is changing
239248
useEffect(() => {
240-
if (!viewer) return;
241-
viewer.container.dispatchEvent(new CustomEvent("scroll"));
242-
}, [viewer]);
249+
if (!services.eventBus || !viewer) return;
250+
251+
const { eventBus } = services;
252+
// in case the scale is changed, we want to force
253+
// new page offsets to be calculated and components
254+
// depending on that re-rendered.
255+
// This happens through `visiblePages` changing, otherwise
256+
// since `pageOffsets` are a ref, we won't see any
257+
// components noticing the change in page offsets, hence
258+
// no rendering would occur.
259+
const handler = () => handleViewChanged(true);
260+
eventBus.on("scalechanging", handler);
261+
262+
return () => {
263+
eventBus.off("scalechanging", handler);
264+
};
265+
}, [services, viewer, handleViewChanged]);
243266
}

0 commit comments

Comments
 (0)