返回 presentation-ai
ScaledSlide.tsx
根目录 / src / components / notebook / presentation / components / theme / ScaledSlide.tsx
1 "use client";
2
3 import { useLayoutEffect, useRef, useState } from "react";
4
5 import { type testSlides } from "@/components/notebook/presentation/components/theme/create-theme/test-slide";
6 import StaticPresentationEditor from "@/components/notebook/presentation/editor/presentation-editor-static";
7
8 interface ScaledSlideProps {
9 slide: (typeof testSlides)[number];
10 slideWidth: number;
11 scale: number;
12 }
13
14 /**
15 * Component that scales content and adjusts container height using ResizeObserver.
16 * This ensures the outer container height matches the scaled content height.
17 */
18 export function ScaledSlide({ slide, slideWidth, scale }: ScaledSlideProps) {
19 const contentRef = useRef<HTMLDivElement>(null);
20 const [scaledHeight, setScaledHeight] = useState<number | undefined>(
21 undefined,
22 );
23
24 useLayoutEffect(() => {
25 const el = contentRef.current;
26 if (!el) return;
27
28 const updateHeight = () => {
29 // Use scrollHeight to get the unscaled height, then multiply by scale
30 const height = el.scrollHeight;
31 setScaledHeight(height * scale);
32 };
33
34 const observer = new ResizeObserver(updateHeight);
35 observer.observe(el);
36 updateHeight();
37
38 return () => observer.disconnect();
39 }, [scale]);
40
41 return (
42 <div
43 style={{
44 width: `${slideWidth * scale}px`,
45 height: scaledHeight ? `${scaledHeight}px` : "auto",
46 }}
47 >
48 <div
49 ref={contentRef}
50 style={{
51 width: `${slideWidth}px`,
52 transform: `scale(${scale})`,
53 transformOrigin: "top left",
54 }}
55 >
56 <StaticPresentationEditor
57 initialContent={slide}
58 className="rounded-md"
59 id={slide.id}
60 />
61 </div>
62 </div>
63 );
64 }
65
65 lines Plain Text