Auto scroll update (#7)

* updated auto-scroll logic for EPUB and PDF

* Refactored auto-scroll to use temporary debounced pauses instead of hard stops on manual interaction.
* Updated tap handling to allow toggling bars without interrupting scroll.
* Added a 2-second orientation pause on EPUB chapter transitions.
* Enhanced AutoScrollControls UI with circular progress overlay to indicate the "temporarily paused" state.

* Refactored auto-scroll controls

This commit refactors the auto-scroll controls for both EPUB and PDF readers, introducing a more advanced and user-friendly interface.

Key changes:
- Redesigned the auto-scroll controls UI into a collapsible and lockable card.
- Added a "lock" feature to hide controls during scrolling.
- Introduced an alternative slider-based input for speed adjustment, which can be toggled.
- Persisted the lock and input mode states in SharedPreferences.
- Improved the EPUB auto-scroll mechanism using `translate3d` for smoother sub-pixel scrolling.
This commit is contained in:
Aryan 2026-02-26 17:16:01 +05:30 committed by GitHub
parent 1f111034f1
commit de376e2ace
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 410 additions and 238 deletions

View file

@ -30,6 +30,12 @@
word-break: break-word; -webkit-text-size-adjust: 100%;
text-rendering: optimizeLegibility; -webkit-user-select: none;
-moz-user-select: none; -ms-user-select: none; user-select: none;
scroll-behavior: auto !important;
}
#content-container {
will-change: transform;
transition: none !important;
}
p, div, li, td, th, span {
@ -2649,7 +2655,7 @@ window.findFirstVisibleCfi=function (cfiArray) {
})();
(function () {
const TAG_AUTO_SCROLL="AutoScrollDiagnosis"; // Define the tag
const TAG_AUTO_SCROLL="AutoScrollDiagnosis";
window.autoScroll= {
active: false,
@ -2672,27 +2678,21 @@ window.findFirstVisibleCfi=function (cfiArray) {
this.accumulator=0.0;
if (this.animationId) cancelAnimationFrame(this.animationId);
this.loop();
}
,
},
stop: function () {
console.log(`$ {
TAG_AUTO_SCROLL
}
: Stopping auto-scroll.`);
this.active=false;
const container=document.getElementById('content-container') || document.body;
if (container) container.style.transform='none';
this.active = false;
if (this.animationId) {
cancelAnimationFrame(this.animationId);
this.animationId=null;
this.animationId = null;
}
}
,
const container = document.getElementById('content-container') || document.body;
if (container) {
container.style.transform = 'none';
window.scrollBy(0, 0);
}
},
updateSpeed: function (newSpeed) {
console.log(`$ {
@ -2710,109 +2710,39 @@ window.findFirstVisibleCfi=function (cfiArray) {
,
loop: function () {
if ( !this.active) return;
if (!this.active) return;
this.accumulator +=this.speed;
this.accumulator += this.speed;
const pixelsToScroll=Math.floor(this.accumulator);
const subPixelRemainder=this.accumulator - pixelsToScroll;
const totalPixelsToScroll = Math.floor(this.accumulator);
if (pixelsToScroll >=1) {
const prevScrollY=window.scrollY;
window.scrollBy(0, pixelsToScroll);
this.accumulator -=pixelsToScroll;
if (totalPixelsToScroll >= 1) {
const prevScrollY = window.scrollY;
window.scrollBy(0, totalPixelsToScroll);
// Calculation logic
const innerH=window.innerHeight;
const scrollY=window.scrollY;
const docHeight=document.documentElement.scrollHeight; // Usually more reliable than body.scrollHeight
this.accumulator -= totalPixelsToScroll;
const currentScrollPos=scrollY + innerH;
// Relaxed threshold slightly (from 2 to 3) to account for sub-pixel rendering differences
const isAtBottom=currentScrollPos >=(docHeight - 3);
const isStuck=(scrollY===prevScrollY);
// Log only when we are very close to the bottom or stuck, to avoid spamming
if (isAtBottom || isStuck || (docHeight - currentScrollPos < 50)) {
console.log(`$ {
TAG_AUTO_SCROLL
}
: Loop Status -> ScrollY: $ {
Math.round(scrollY)
}
, InnerH: $ {
innerH
}
, Pos: $ {
Math.round(currentScrollPos)
}
, DocH: $ {
docHeight
}
`);
console.log(`$ {
TAG_AUTO_SCROLL
}
: Check -> AtBottom: $ {
isAtBottom
}
, Stuck: $ {
isStuck
}
`);
}
const scrollY = window.scrollY;
const docHeight = document.documentElement.scrollHeight;
const innerH = window.innerHeight;
const isAtBottom = (scrollY + innerH) >= (docHeight - 3);
const isStuck = (totalPixelsToScroll > 0 && scrollY === prevScrollY && prevScrollY > 0);
if (isAtBottom || isStuck) {
console.log(`$ {
TAG_AUTO_SCROLL
}
: End of chapter detected. Calling Bridge.`);
this.stop();
const container=document.getElementById('content-container') || document.body;
container.style.transform='none';
if (window.AutoScrollBridge && window.AutoScrollBridge.onChapterEnd) {
window.AutoScrollBridge.onChapterEnd();
}
else {
console.log(`$ {
TAG_AUTO_SCROLL
}
: AutoScrollBridge not found !`);
}
return;
}
}
const container=document.getElementById('content-container') || document.body;
const container = document.getElementById('content-container') || document.body;
if (container) {
container.style.transform=`translateY(-$ {
subPixelRemainder
}
px)`;
container.style.transform = `translate3d(0, -${this.accumulator}px, 0)`;
}
this.animationId=requestAnimationFrame(this.loop.bind(this));
}
,
}
;
this.animationId = requestAnimationFrame(this.loop.bind(this));
},
};
})();