fix animation

This commit is contained in:
Hamid
2026-05-16 23:22:01 -07:00
parent b3e0378af5
commit fef8099ab1
6 changed files with 195 additions and 84 deletions
+30 -6
View File
@@ -5,6 +5,7 @@ import BookPage from './BookPage';
import { ArrowLeft2, ArrowRight2, Pause, Play } from 'iconsax-react';
import { getPaperDimensions } from '@/config/paperSizes';
import type { DocumentSettings } from '@/pages/editor/store/editorStore';
import { useBookEntranceController } from '@/pages/viewer/hooks/useBookEntranceController';
/** فاصله پیش‌فرض بین هر ورق در پخش خودکار (میلی‌ثانیه) */
const AUTO_PLAY_INTERVAL_MS = 3000;
@@ -176,6 +177,30 @@ const BookViewer: FC<BookViewerProps> = ({ pages, catalogSize, documentSettings
? 'desktop'
: `mobile-${pagePixelWidth}-${pagePixelHeight}`;
const usePortrait = !isDesktop || displayStyle === 'single';
const {
scheduleEntranceForSpread,
getEntrancePhase,
reset: resetEntrance,
} = useBookEntranceController({
pages,
portrait: usePortrait,
showCover: hasMultiplePages,
});
const commitEntranceAtCurrentSpread = useCallback(() => {
const api = bookRef.current?.pageFlip();
const idx = api?.getCurrentPageIndex?.();
if (typeof idx !== 'number' || pages.length <= 0) return;
const clamped = Math.max(0, Math.min(idx, pages.length - 1));
scheduleEntranceForSpread(clamped);
}, [pages.length, scheduleEntranceForSpread]);
useEffect(() => {
resetEntrance();
}, [flipKey, pages.length, pages[0]?.id, resetEntrance]);
// اطمینان از اینکه currentPage همیشه در محدوده معتبر است
useEffect(() => {
if (currentPage < 0) {
@@ -282,16 +307,17 @@ const BookViewer: FC<BookViewerProps> = ({ pages, catalogSize, documentSettings
setCurrentPage(clamped);
lastFlipPageRef.current = clamped;
},
[pages.length]
[pages.length],
);
/** بعد از اتمام انیمیشن، ایندکس واقعی کتاب را می‌گیریم (RTL روی روت کتاب مختصات page-flip را به‌هم می‌زند) */
/** بعد از اتمام انیمیشن ورق، ایندکس واقعی کتاب را می‌گیریم و انیمیشن ورود را یک‌بار شروع می‌کنیم */
const handleChangeState = useCallback(
(e: PageFlipStateEvent) => {
if (e.data !== 'read') return;
syncPageIndexFromBook();
commitEntranceAtCurrentSpread();
},
[syncPageIndexFromBook]
[syncPageIndexFromBook, commitEntranceAtCurrentSpread],
);
const goToNextPage = useCallback(() => {
@@ -393,9 +419,6 @@ const BookViewer: FC<BookViewerProps> = ({ pages, catalogSize, documentSettings
}
}, [currentPage, pages.length, goToNextPage, goToPrevPage]);
// تک‌صفحه‌ای: موبایل یا تنظیم single، دوصفحه‌ای: دسکتاپ + تنظیم double
const usePortrait = !isDesktop || displayStyle === 'single';
const prevFlipKeyRef = useRef(flipKey);
useEffect(() => {
if (prevFlipKeyRef.current !== flipKey) {
@@ -481,6 +504,7 @@ const BookViewer: FC<BookViewerProps> = ({ pages, catalogSize, documentSettings
<BookPage
key={page.id}
page={page}
entrancePhase={getEntrancePhase(page.id)}
scale={contentScale}
pageWidth={pagePixelWidth}
pageHeight={pagePixelHeight}