fix repeat animation
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { forwardRef } from 'react';
|
import { forwardRef, memo } from 'react';
|
||||||
import { type PageData } from '../types';
|
import { type PageData } from '../types';
|
||||||
import type { EditorObject } from '@/pages/editor/store/editorStore';
|
import type { EditorObject } from '@/pages/editor/store/editorStore';
|
||||||
import { toCssLinearGradient, getSvgGradientEndpoints } from '@/pages/editor/utils/gradient';
|
import { toCssLinearGradient, getSvgGradientEndpoints } from '@/pages/editor/utils/gradient';
|
||||||
@@ -84,7 +84,7 @@ type BookPageProps = {
|
|||||||
* این کامپوننت به عنوان child برای HTMLFlipBook استفاده میشود
|
* این کامپوننت به عنوان child برای HTMLFlipBook استفاده میشود
|
||||||
* نیاز به forwardRef دارد تا react-pageflip بتواند ref را مدیریت کند
|
* نیاز به forwardRef دارد تا react-pageflip بتواند ref را مدیریت کند
|
||||||
*/
|
*/
|
||||||
const BookPage = forwardRef<HTMLDivElement, BookPageProps>(
|
const BookPage = memo(forwardRef<HTMLDivElement, BookPageProps>(
|
||||||
({ page, scale = 1, pageWidth, pageHeight, onLinkClick, backgroundType, backgroundColor, backgroundGradient, backgroundImageUrl, backgroundVideoUrl, entrancePhase = 'idle', disableEntranceAnimations = false, staticMedia = false, showPaperShadow = true, useHardPage = false, idSuffix = '' }, ref) => {
|
({ 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;
|
const phase: EntrancePhase = disableEntranceAnimations ? 'settled' : entrancePhase;
|
||||||
// تابع برای تبدیل opacity به رنگ (مثل editor)
|
// تابع برای تبدیل opacity به رنگ (مثل editor)
|
||||||
@@ -1037,7 +1037,8 @@ const BookPage = forwardRef<HTMLDivElement, BookPageProps>(
|
|||||||
{useHardPage && showPaperShadow && <div aria-hidden className="page-paper-shadow" />}
|
{useHardPage && showPaperShadow && <div aria-hidden className="page-paper-shadow" />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
BookPage.displayName = 'BookPage';
|
BookPage.displayName = 'BookPage';
|
||||||
|
|
||||||
|
|||||||
@@ -126,13 +126,22 @@ const BookViewer: FC<BookViewerProps> = ({ pages, catalogSize, documentSettings
|
|||||||
const bookRef = useRef<FlipBookInstance | null>(null);
|
const bookRef = useRef<FlipBookInstance | null>(null);
|
||||||
const bookAreaRef = useRef<HTMLDivElement | null>(null);
|
const bookAreaRef = useRef<HTMLDivElement | null>(null);
|
||||||
const flipbookWrapperRef = useRef<HTMLDivElement | null>(null);
|
const flipbookWrapperRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
const spineOverlayRef = useRef<HTMLDivElement | null>(null);
|
||||||
const pageFlipHandlerRef = useRef<(e: FlipEvent) => void>(() => {});
|
const pageFlipHandlerRef = useRef<(e: FlipEvent) => void>(() => {});
|
||||||
const [currentPage, setCurrentPage] = useState(0);
|
const [currentPage, setCurrentPage] = useState(0);
|
||||||
const [isAutoPlayActive, setIsAutoPlayActive] = useState(false);
|
const [isAutoPlayActive, setIsAutoPlayActive] = useState(false);
|
||||||
const [startPage, setStartPage] = useState(0);
|
const [startPage, setStartPage] = useState(0);
|
||||||
const [magnifierEnabled, setMagnifierEnabled] = useState(false);
|
const [magnifierEnabled, setMagnifierEnabled] = useState(false);
|
||||||
/** در حالت read خط وسط روی شکاف جلد دیده میشود؛ هنگام ورقزدن باید زیر ورق باشد */
|
/** ref نه state — تغییر z-index هنگام hover ورق نباید BookPage را remount/re-render کند (انیمیشن ورود دوباره اجرا میشد) */
|
||||||
const [isBookFlipping, setIsBookFlipping] = useState(false);
|
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 isDesktop = useIsDesktop();
|
||||||
const legacyIOS = useLegacyIOSSafari();
|
const legacyIOS = useLegacyIOSSafari();
|
||||||
const isBrowserFullscreen = useIsBrowserFullscreen();
|
const isBrowserFullscreen = useIsBrowserFullscreen();
|
||||||
@@ -394,14 +403,14 @@ const BookViewer: FC<BookViewerProps> = ({ pages, catalogSize, documentSettings
|
|||||||
const handleChangeState = useCallback(
|
const handleChangeState = useCallback(
|
||||||
(e: PageFlipStateEvent) => {
|
(e: PageFlipStateEvent) => {
|
||||||
if (e.data === "read") {
|
if (e.data === "read") {
|
||||||
setIsBookFlipping(false);
|
setBookFlippingVisual(false);
|
||||||
syncPageIndexFromBook();
|
syncPageIndexFromBook();
|
||||||
commitEntranceAtCurrentSpread();
|
commitEntranceAtCurrentSpread();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setIsBookFlipping(true);
|
setBookFlippingVisual(true);
|
||||||
},
|
},
|
||||||
[syncPageIndexFromBook, commitEntranceAtCurrentSpread],
|
[syncPageIndexFromBook, commitEntranceAtCurrentSpread, setBookFlippingVisual],
|
||||||
);
|
);
|
||||||
|
|
||||||
const goToNextPage = useCallback(() => {
|
const goToNextPage = useCallback(() => {
|
||||||
@@ -534,10 +543,8 @@ const BookViewer: FC<BookViewerProps> = ({ pages, catalogSize, documentSettings
|
|||||||
{/* Border و Shadow عمودی در وسط (فقط حالت دوصفحهای دسکتاپ) */}
|
{/* Border و Shadow عمودی در وسط (فقط حالت دوصفحهای دسکتاپ) */}
|
||||||
{!usePortrait && (
|
{!usePortrait && (
|
||||||
<div
|
<div
|
||||||
className={clx(
|
ref={spineOverlayRef}
|
||||||
"hidden md:block absolute inset-y-0 left-1/2 -translate-x-1/2 w-px border-r border-gray-300 pointer-events-none transition-none",
|
className="hidden md:block absolute inset-y-0 left-1/2 -translate-x-1/2 w-px border-r border-gray-300 pointer-events-none transition-none z-50"
|
||||||
isBookFlipping ? "z-0" : "z-50",
|
|
||||||
)}
|
|
||||||
style={{
|
style={{
|
||||||
boxShadow: "-5px 0 15px rgba(0, 0, 0, 0.15), 5px 0 15px rgba(0, 0, 0, 0.15)",
|
boxShadow: "-5px 0 15px rgba(0, 0, 0, 0.15), 5px 0 15px rgba(0, 0, 0, 0.15)",
|
||||||
}}
|
}}
|
||||||
@@ -550,10 +557,7 @@ const BookViewer: FC<BookViewerProps> = ({ pages, catalogSize, documentSettings
|
|||||||
<div
|
<div
|
||||||
ref={flipbookWrapperRef}
|
ref={flipbookWrapperRef}
|
||||||
dir="ltr"
|
dir="ltr"
|
||||||
className={clx(
|
className="max-w-full flex justify-center shrink-0 rounded-sm"
|
||||||
"max-w-full flex justify-center shrink-0 rounded-sm",
|
|
||||||
isBookFlipping && "relative z-10",
|
|
||||||
)}
|
|
||||||
style={{
|
style={{
|
||||||
cursor: magnifierEnabled ? "zoom-in" : undefined,
|
cursor: magnifierEnabled ? "zoom-in" : undefined,
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
|
|||||||
Reference in New Issue
Block a user