Revert per-line reveal timing to area-weighting

The previous commit changed per-line reveal-duration distribution from ink-area to
word-count. That dropped a deliberate precision decision (area gives sub-line
granularity) and, verified live on a spanning paragraph, it was what made the
continuation page fail to animate. Restore area-weighting for the per-line split.

The word-share scaling of the *total* duration for partial (spanning) blocks and the
timeline-module timing snapshot/restore are kept — they only preserve existing
word-timings, they do not change the area-based per-line distribution.

Verified: on a real spanning block the right line reveals over its area share (~3.3s),
the page flips, and the continuation animates progressively across the next spread
over the full TTS (no fast-forward, no reveal-all-at-once).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-18 23:45:26 +02:00
parent dc2afcf831
commit e72594b3ff
2 changed files with 4 additions and 13 deletions
+2 -11
View File
@@ -698,18 +698,9 @@ class BookTextureRendererModule extends BaseModule {
const useWordShare = totalBlockWords > 0 && collectedWords > 0 && collectedWords < totalBlockWords;
const totalDuration = useWordShare ? baseDuration * (collectedWords / totalBlockWords) : baseDuration;
let fallbackDelay = useWordShare && Number.isFinite(wordsBefore) ? baseDuration * (wordsBefore / totalBlockWords) : 0;
// Weight each line by its word count when available, falling back to ink area.
// Word counts are reliable even for just-paginated continuation lines whose rect
// area can be ~0; area-weighting there would hand the whole duration to the one
// line on the current page and stretch it across the entire TTS.
const useWordWeights = collectedWords > 0;
const totalWeight = useWordWeights ? collectedWords : totalArea;
textRegions.forEach((region) => {
const weight = useWordWeights
? Math.max(0, Number(region.blockWordCount || 0))
: Math.max(1, region.timingArea || region.area);
const duration = totalWeight > 0
? Math.max(1, totalDuration * (weight / totalWeight))
const duration = totalArea > 0
? Math.max(1, totalDuration * (Math.max(1, region.timingArea || region.area) / totalArea))
: Math.max(1, totalDuration / Math.max(1, textRegions.length));
timedRegions.push({
...region,