diff --git a/src/pages/viewer/components/BookPage.tsx b/src/pages/viewer/components/BookPage.tsx index 3938aba..b41823c 100644 --- a/src/pages/viewer/components/BookPage.tsx +++ b/src/pages/viewer/components/BookPage.tsx @@ -1,4 +1,4 @@ -import { forwardRef } from 'react'; +import { forwardRef, memo } from 'react'; import { type PageData } from '../types'; import type { EditorObject } from '@/pages/editor/store/editorStore'; import { toCssLinearGradient, getSvgGradientEndpoints } from '@/pages/editor/utils/gradient'; @@ -84,7 +84,7 @@ type BookPageProps = { * این کامپوننت به عنوان child برای HTMLFlipBook استفاده می‌شود * نیاز به forwardRef دارد تا react-pageflip بتواند ref را مدیریت کند */ -const BookPage = forwardRef( +const BookPage = memo(forwardRef( ({ page, scale = 1, pageWidth, pageHeight, onLinkClick, backgroundType, backgroundColor, backgroundGradient, backgroundImageUrl, backgroundVideoUrl, entrancePhase = 'idle', disableEntranceAnimations = false, staticMedia = false, showPaperShadow = true, useHardPage = false, idSuffix = '' }, ref) => { const phase: EntrancePhase = disableEntranceAnimations ? 'settled' : entrancePhase; // تابع برای تبدیل opacity به رنگ (مثل editor) @@ -1037,7 +1037,8 @@ const BookPage = forwardRef( {useHardPage && showPaperShadow &&
}
); - }); + }), +); BookPage.displayName = 'BookPage'; diff --git a/src/pages/viewer/components/BookViewer.tsx b/src/pages/viewer/components/BookViewer.tsx index 9ca119d..b28356e 100644 --- a/src/pages/viewer/components/BookViewer.tsx +++ b/src/pages/viewer/components/BookViewer.tsx @@ -126,13 +126,22 @@ const BookViewer: FC = ({ pages, catalogSize, documentSettings const bookRef = useRef(null); const bookAreaRef = useRef(null); const flipbookWrapperRef = useRef(null); + const spineOverlayRef = useRef(null); const pageFlipHandlerRef = useRef<(e: FlipEvent) => void>(() => {}); const [currentPage, setCurrentPage] = useState(0); const [isAutoPlayActive, setIsAutoPlayActive] = useState(false); const [startPage, setStartPage] = useState(0); const [magnifierEnabled, setMagnifierEnabled] = useState(false); - /** در حالت read خط وسط روی شکاف جلد دیده می‌شود؛ هنگام ورق‌زدن باید زیر ورق باشد */ - const [isBookFlipping, setIsBookFlipping] = useState(false); + /** ref نه state — تغییر z-index هنگام hover ورق نباید BookPage را remount/re-render کند (انیمیشن ورود دوباره اجرا می‌شد) */ + const isBookFlippingRef = useRef(false); + const setBookFlippingVisual = useCallback((flipping: boolean) => { + if (isBookFlippingRef.current === flipping) return; + isBookFlippingRef.current = flipping; + flipbookWrapperRef.current?.classList.toggle("relative", flipping); + flipbookWrapperRef.current?.classList.toggle("z-10", flipping); + spineOverlayRef.current?.classList.toggle("z-50", !flipping); + spineOverlayRef.current?.classList.toggle("z-0", flipping); + }, []); const isDesktop = useIsDesktop(); const legacyIOS = useLegacyIOSSafari(); const isBrowserFullscreen = useIsBrowserFullscreen(); @@ -394,14 +403,14 @@ const BookViewer: FC = ({ pages, catalogSize, documentSettings const handleChangeState = useCallback( (e: PageFlipStateEvent) => { if (e.data === "read") { - setIsBookFlipping(false); + setBookFlippingVisual(false); syncPageIndexFromBook(); commitEntranceAtCurrentSpread(); return; } - setIsBookFlipping(true); + setBookFlippingVisual(true); }, - [syncPageIndexFromBook, commitEntranceAtCurrentSpread], + [syncPageIndexFromBook, commitEntranceAtCurrentSpread, setBookFlippingVisual], ); const goToNextPage = useCallback(() => { @@ -534,10 +543,8 @@ const BookViewer: FC = ({ pages, catalogSize, documentSettings {/* Border و Shadow عمودی در وسط (فقط حالت دوصفحه‌ای دسکتاپ) */} {!usePortrait && (
= ({ pages, catalogSize, documentSettings