返回 reveal.js
slide.tsx
根目录 / react / src / components / slide.tsx
1 import { useContext, useLayoutEffect, useRef } from 'react';
2 import type { RevealApi } from 'reveal.js';
3 import { RevealContext } from '../reveal-context';
4 import type { SlideProps } from '../types';
5 import {
6 EMPTY_DATA_ATTRIBUTES_SIGNATURE,
7 getDataAttributesSignature,
8 getSlideAttributes,
9 } from '../utils/slide-attributes';
10
11 export function Slide({
12 children,
13 background,
14 backgroundImage,
15 backgroundVideo,
16 backgroundVideoLoop,
17 backgroundVideoMuted,
18 backgroundIframe,
19 backgroundColor,
20 backgroundGradient,
21 backgroundSize,
22 backgroundPosition,
23 backgroundRepeat,
24 backgroundOpacity,
25 backgroundTransition,
26 visibility,
27 autoAnimate,
28 autoAnimateId,
29 autoAnimateRestart,
30 autoAnimateUnmatched,
31 autoAnimateEasing,
32 autoAnimateDuration,
33 autoAnimateDelay,
34 transition,
35 transitionSpeed,
36 autoSlide,
37 notes,
38 backgroundInteractive,
39 preload,
40 ...rest
41 }: SlideProps) {
42 const deck = useContext(RevealContext);
43 const slideRef = useRef<HTMLElement>(null);
44 const lastSyncedDeckRef = useRef<RevealApi | null>(null);
45 const lastSyncedSignatureRef = useRef<string | null>(null);
46 const slideAttributes = getSlideAttributes(rest, {
47 background,
48 backgroundImage,
49 backgroundVideo,
50 backgroundVideoLoop,
51 backgroundVideoMuted,
52 backgroundIframe,
53 backgroundColor,
54 backgroundGradient,
55 backgroundSize,
56 backgroundPosition,
57 backgroundRepeat,
58 backgroundOpacity,
59 backgroundTransition,
60 visibility,
61 autoAnimate,
62 autoAnimateId,
63 autoAnimateRestart,
64 autoAnimateUnmatched,
65 autoAnimateEasing,
66 autoAnimateDuration,
67 autoAnimateDelay,
68 transition,
69 transitionSpeed,
70 autoSlide,
71 notes,
72 backgroundInteractive,
73 preload,
74 });
75 const dataAttributesSignature = getDataAttributesSignature(slideAttributes);
76
77 useLayoutEffect(() => {
78 const slide = slideRef.current;
79 if (!deck || !slide || typeof deck.syncSlide !== 'function') return;
80
81 // The first render for a given deck instance is handled by the parent Deck.sync() pass.
82 // syncSlide() is only safe once Reveal is aware of this slide.
83 if (lastSyncedDeckRef.current !== deck) {
84 lastSyncedDeckRef.current = deck;
85 lastSyncedSignatureRef.current = dataAttributesSignature;
86 return;
87 }
88
89 if (dataAttributesSignature === EMPTY_DATA_ATTRIBUTES_SIGNATURE) return;
90
91 const sameDeck = lastSyncedDeckRef.current === deck;
92 const sameDataAttributes = lastSyncedSignatureRef.current === dataAttributesSignature;
93 if (sameDeck && sameDataAttributes) return;
94
95 deck.syncSlide(slide);
96 lastSyncedDeckRef.current = deck;
97 lastSyncedSignatureRef.current = dataAttributesSignature;
98 }, [deck, dataAttributesSignature]);
99
100 return (
101 <section ref={slideRef} {...slideAttributes}>
102 {children}
103 </section>
104 );
105 }
106
106 lines Plain Text