Measuring DOM nodes
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.
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().
Measure using the useCurrentScale() hook
From v4.0.111 on, you can use the useCurrentScale() hook to correct the dimensions of the element.
MyComponent.tsxtsximport {useCallback ,useEffect ,useState ,useRef } from "react";import {useCurrentScale } from "remotion";export constMyComponent = () => {constref =useRef <HTMLDivElement >(null);const [dimensions ,setDimensions ] =useState <{correctedHeight : number;correctedWidth : number;} | null>(null);constscale =useCurrentScale ();useEffect (() => {if (!ref .current ) {return;}constrect =ref .current .getBoundingClientRect ();setDimensions ({correctedHeight :rect .height /scale ,correctedWidth :rect .width /scale ,});}, [scale ]);return (<div ><div ref ={ref }>Hello World!</div ></div >);};
MyComponent.tsxtsximport {useCallback ,useEffect ,useState ,useRef } from "react";import {useCurrentScale } from "remotion";export constMyComponent = () => {constref =useRef <HTMLDivElement >(null);const [dimensions ,setDimensions ] =useState <{correctedHeight : number;correctedWidth : number;} | null>(null);constscale =useCurrentScale ();useEffect (() => {if (!ref .current ) {return;}constrect =ref .current .getBoundingClientRect ();setDimensions ({correctedHeight :rect .height /scale ,correctedWidth :rect .width /scale ,});}, [scale ]);return (<div ><div ref ={ref }>Hello World!</div ></div >);};
Versions prior to v4.0.110
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.tsxtsximport {useCallback ,useEffect ,useState ,useRef } from "react";constMEASURER_SIZE = 10;export constMyComponent = () => {constref =useRef <HTMLDivElement >(null);constmeasurer =useRef <HTMLDivElement >(null);const [dimensions ,setDimensions ] =useState <{correctedHeight : number;correctedWidth : number;} | null>(null);useEffect (() => {if (!ref .current || !measurer .current ) {return;}constrect =ref .current .getBoundingClientRect ();constmeasurerRect =measurer .current .getBoundingClientRect ();constscale =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 >);};
MyComponent.tsxtsximport {useCallback ,useEffect ,useState ,useRef } from "react";constMEASURER_SIZE = 10;export constMyComponent = () => {constref =useRef <HTMLDivElement >(null);constmeasurer =useRef <HTMLDivElement >(null);const [dimensions ,setDimensions ] =useState <{correctedHeight : number;correctedWidth : number;} | null>(null);useEffect (() => {if (!ref .current || !measurer .current ) {return;}constrect =ref .current .getBoundingClientRect ();constmeasurerRect =measurer .current .getBoundingClientRect ();constscale =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
Versions prior to v4.0.103
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
- react-use-measure - Measure elements correctly inside a scroll container