Fix WebGL reveal pacing on spanning pages and page-reveal-on-flip

- Reveal timing is now word-proportional per page: when a block's reveal only
  covers part of the block (the continuation spread is not paginated at reveal
  time), the page reveals only its share of the TTS, offset by the words before
  it. The right page no longer absorbs the whole TTS before flipping; it flips at
  normal pace and the continuation resumes on the next spread while TTS plays. No
  effect when the regions already cover the whole block (unified plan / one page).
- Page flip start now shows the target spread's same-side page beneath the lifting
  page (revealed as it turns away) instead of a blank that pops in after the flip.
  Deferred (pending-reveal) sides stay blank so the masked reveal still lands via
  activate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-17 20:01:41 +02:00
parent 8bb18fa201
commit ab194062bb
2 changed files with 28 additions and 16 deletions
+15 -14
View File
@@ -3114,20 +3114,21 @@ function prepareStaticPageForFlip(flip, prewarm = null) {
hasBackTexture: Boolean(backTexture || getBlankPageTexture()),
sourceTextureMatchesBackTexture: sourceTexture === (backTexture || getBlankPageTexture())
};
if (flip.direction > 0) {
const blankTexture = getBlankPageTexture();
if (blankTexture && materials.rightPage.map !== blankTexture) {
clearPageReveal('right', 'page-flip-start', { preserveBaseTexture: sourceSide === 'right' });
materials.rightPage.map = blankTexture;
materials.rightPage.needsUpdate = true;
}
} else if (flip.direction < 0) {
const blankTexture = getBlankPageTexture();
if (blankTexture && materials.leftPage.map !== blankTexture) {
clearPageReveal('left', 'page-flip-start', { preserveBaseTexture: sourceSide === 'left' });
materials.leftPage.map = blankTexture;
materials.leftPage.needsUpdate = true;
}
// The page lifts from the source side, uncovering the target spread's same-side page
// beneath it. Show that target page now (hidden under the lifting page at t=0, then
// revealed as it turns away) instead of a blank that pops in at the end. If that side
// has a pending reveal (playback), keep it blank so activate lands the masked reveal.
const revealedSide = sourceSide;
const revealedMaterial = revealedSide === 'left' ? materials.leftPage : materials.rightPage;
const revealedDeferred = Array.isArray(flip.deferRevealSides) && flip.deferRevealSides.includes(revealedSide);
const revealedMeta = getPaginationPageMeta(targetPages[revealedSide]) || makeBlankPageMeta(targetPages[revealedSide]);
const revealedTexture = (revealedDeferred || revealedMeta.kind === 'blank')
? getBlankPageTexture()
: (pageTextureStore?.getResidentTextureForMeta?.(revealedMeta) || getBlankPageTexture());
clearPageReveal(revealedSide, 'page-flip-start', { preserveBaseTexture: true });
if (revealedTexture && revealedMaterial.map !== revealedTexture) {
revealedMaterial.map = revealedTexture;
revealedMaterial.needsUpdate = true;
}
markPageTextureTiming('flipTexturePreflight:ready', {
...lastFlipTexturePreflight,