Change PDF rendering
This commit is contained in:
72
src-tauri/assets/viewer/viewport-tracker.js
Normal file
72
src-tauri/assets/viewer/viewport-tracker.js
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* ViewportTracker — dual IntersectionObserver for page visibility detection.
|
||||
*
|
||||
* - visibleSet: pages currently on screen (rootMargin "0px")
|
||||
* - bufferSet: pages within ~2 viewport heights above/below (rootMargin "200% 0px")
|
||||
*
|
||||
* Calls onVisibilityChange(bufferSet, visibleSet) whenever either set changes.
|
||||
*/
|
||||
export class ViewportTracker {
|
||||
/**
|
||||
* @param {HTMLElement} root - scroll container (#canvas-container)
|
||||
* @param {HTMLElement[]} pageWrappers - array of .page-wrapper elements
|
||||
* @param {Function} onVisibilityChange - (bufferSet: Set<number>, visibleSet: Set<number>) => void
|
||||
*/
|
||||
constructor(root, pageWrappers, onVisibilityChange) {
|
||||
this._onVisibilityChange = onVisibilityChange;
|
||||
this._visibleSet = new Set();
|
||||
this._bufferSet = new Set();
|
||||
this._visibleObserver = null;
|
||||
this._bufferObserver = null;
|
||||
|
||||
this._observe(root, pageWrappers);
|
||||
}
|
||||
|
||||
_observe(root, pageWrappers) {
|
||||
const notify = () => {
|
||||
this._onVisibilityChange(new Set(this._bufferSet), new Set(this._visibleSet));
|
||||
};
|
||||
|
||||
this._visibleObserver = new IntersectionObserver(
|
||||
entries => {
|
||||
for (const e of entries) {
|
||||
const page = parseInt(e.target.dataset.page, 10);
|
||||
if (e.isIntersecting) this._visibleSet.add(page);
|
||||
else this._visibleSet.delete(page);
|
||||
}
|
||||
notify();
|
||||
},
|
||||
{ root, rootMargin: "0px", threshold: 0 }
|
||||
);
|
||||
|
||||
this._bufferObserver = new IntersectionObserver(
|
||||
entries => {
|
||||
for (const e of entries) {
|
||||
const page = parseInt(e.target.dataset.page, 10);
|
||||
if (e.isIntersecting) this._bufferSet.add(page);
|
||||
else this._bufferSet.delete(page);
|
||||
}
|
||||
notify();
|
||||
},
|
||||
{ root, rootMargin: "200% 0px", threshold: 0 }
|
||||
);
|
||||
|
||||
for (const wrap of pageWrappers) {
|
||||
this._visibleObserver.observe(wrap);
|
||||
this._bufferObserver.observe(wrap);
|
||||
}
|
||||
}
|
||||
|
||||
/** Observe a newly-added page wrapper. */
|
||||
observe(wrap) {
|
||||
this._visibleObserver?.observe(wrap);
|
||||
this._bufferObserver?.observe(wrap);
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
this._visibleObserver?.disconnect();
|
||||
this._bufferObserver?.disconnect();
|
||||
this._visibleSet.clear();
|
||||
this._bufferSet.clear();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user