Skip to main content

测量 DOM 节点

如果你想测量一个 DOM 节点,你可以给它分配一个 React Ref,然后使用 getBoundingClientRect() 浏览器 API 来获取该节点的位置和大小。

🌐 If you want to measure a DOM node, you can assign a React Ref to it and then use the getBoundingClientRect() browser API to get the position and size of the node.

在 Remotion 中,这并不容易,因为渲染视频的 <div> 元素应用了 scale() 变换,这会影响你从 getBoundingClientRect() 获取的值。

🌐 In Remotion, it is not that easy because the <div> element in which the video is rendered into has a scale() transform applied to it, which affects the value that you get from getBoundingClientRect().

使用 useCurrentScale() 钩进行测量

🌐 Measure using the useCurrentScale() hook

从 v4.0.111 开始,你可以使用 useCurrentScale() 钩子来纠正元素的尺寸。

🌐 From v4.0.111 on, you can use the useCurrentScale() hook to correct the dimensions of the element.

MyComponent.tsx
import { useCallback, useEffect, useState, useRef } from "react"; import { useCurrentScale } from "remotion"; export const MyComponent = () => { const ref = useRef<HTMLDivElement>(null); const [dimensions, setDimensions] = useState<{ correctedHeight: number; correctedWidth: number; } | null>(null); const scale = useCurrentScale(); useEffect(() => { if (!ref.current) { return; } const rect = ref.current.getBoundingClientRect(); setDimensions({ correctedHeight: rect.height / scale, correctedWidth: rect.width / scale, }); }, [scale]); return ( <div> <div ref={ref}>Hello World!</div> </div> ); };

v4.0.110 之前的版本

🌐 Versions prior to v4.0.110

为了获得准确的测量,你可以渲染一个具有固定宽度的额外元素(比如 10px)并也对其进行测量。然后,你可以用元素的宽度除以 10 来得到缩放因子。

🌐 To get an accurate measurement, you can render an additional element with a fixed width (say 10px) and measure it too. Then, you can divide the width of the element by 10 to get the scale factor.

MyComponent.tsx
import { useCallback, useEffect, useState, useRef } from "react"; const MEASURER_SIZE = 10; export const MyComponent = () => { const ref = useRef<HTMLDivElement>(null); const measurer = useRef<HTMLDivElement>(null); const [dimensions, setDimensions] = useState<{ correctedHeight: number; correctedWidth: number; } | null>(null); useEffect(() => { if (!ref.current || !measurer.current) { return; } const rect = ref.current.getBoundingClientRect(); const measurerRect = measurer.current.getBoundingClientRect(); const scale = measurerRect.width / MEASURER_SIZE; setDimensions({ correctedHeight: rect.height * scale, correctedWidth: rect.width * scale, }); }, []); return ( <div> <div ref={ref}>Hello World!</div> <div ref={measurer} style={{ width: MEASURER_SIZE, position: "fixed", top: -99999, }} /> </div> ); };

示例项目

🌐 Example project

v4.0.103 之前的版本

🌐 Versions prior to v4.0.103

在以前的 Remotion 版本中,getBoundingClientRect() 可能会在前 useEffect() 中返回所有值都是 0 的尺寸,这是由于挂载组件但未显示它造成的。

🌐 In previous versions of Remotion, getBoundingClientRect() could return dimensions with all values being 0 in the first useEffect() due to mounting your component but not showing it.

今后,你可以依赖这些尺寸非零。

🌐 Going forward, you can rely on the dimensions being non-zero.

另请参阅

🌐 See also