Callout Positioning
Debug grids and coordinate systems for accurate arrow/annotation placement in Remotion video compositions. Essential for precise callout placement across different resolutions and aspect ratios.
Overview
-
Positioning callouts, arrows, and annotations in video compositions
-
Debugging coordinate misalignment in Remotion renders
-
Calibrating element positions using screenshot-based workflow
-
Creating responsive annotations for multi-resolution exports
-
Building reusable callout components with precise positioning
Quick Start
// 1. Enable debug grid during development import { DebugGrid } from './components/DebugGrid';
<AbsoluteFill> <YourScene /> <DebugGrid enabled={process.env.NODE_ENV === 'development'} /> </AbsoluteFill>
// 2. Position callouts using grid coordinates <Callout x={960} // Center horizontal (1920/2) y={540} // Center vertical (1080/2) type="pointer" label="Click here" />
Coordinate Systems
1920x1080 (Horizontal/Landscape)
Standard YouTube/Twitter format. Origin at top-left.
Region X Range Y Range Description
Top-Left 0-640 0-360 Logo/watermark
Top-Center 640-1280 0-360 Titles
Top-Right 1280-1920 0-360 Controls/badges
Center 640-1280 360-720 Main content
Bottom 0-1920 720-1080 CTAs/captions
1080x1920 (Vertical/Portrait)
TikTok/Reels/Shorts format. Origin at top-left.
Region X Range Y Range Description
Safe-Top 0-1080 200-400 Below platform UI
Center 0-1080 640-1280 Main content
Safe-Bottom 0-1080 1520-1720 Above controls
1080x1080 (Square)
Instagram/LinkedIn format.
Region X Range Y Range Description
Center 270-810 270-810 Safe content zone
Margins 0-270 0-1080 Decorative only
Debug Grid Component
Enable during development to visualize coordinates.
import { DebugGrid } from './components/DebugGrid';
// In your composition <AbsoluteFill> <YourSceneContent />
{/* Toggle with prop or env var */} <DebugGrid enabled={showDebug} gridSize={100} // Grid cell size in pixels showCoordinates // Show X,Y at cursor position showRulers // Show pixel rulers on edges highlightCenter // Crosshair at center opacity={0.5} /> </AbsoluteFill>
See: references/debug-grid-component.md for full component implementation.
Callout Types
- Pointer Callout
Arrow pointing to a specific location with label.
<PointerCallout targetX={400} targetY={300} labelX={600} labelY={200} label="Important feature" arrowColor="#8b5cf6" animate // Fade in with arrow draw />
- Bracket Callout
Brackets around a region to highlight an area.
<BracketCallout x={300} y={200} width={400} height={150} label="This section" position="right" // Label position: top, right, bottom, left bracketColor="#22c55e" />
- Highlight Callout
Colored overlay to emphasize a region.
<HighlightCallout x={500} y={400} width={200} height={100} color="rgba(139, 92, 246, 0.3)" pulse // Pulsing animation />
- Number Badge
Numbered circle for step-by-step annotations.
<NumberBadge number={1} x={300} y={250} size={40} color="#f59e0b" />
Calibration Workflow
Step 1: Enable Debug Grid
// In your composition root const showDebug = true; // Toggle manually or via env
<DebugGrid enabled={showDebug} showCoordinates showRulers />
Step 2: Take Screenshot
Render single frame with debug grid
npx remotion still MyComposition --frame=30 --output=debug-frame.png
Step 3: Measure Coordinates
Open screenshot in image editor. Note pixel coordinates of target elements.
Step 4: Apply Coordinates
// Use measured coordinates <PointerCallout targetX={847} // Measured from screenshot targetY={312} // Measured from screenshot labelX={1000} labelY={200} label="Feature name" />
Step 5: Verify and Iterate
Re-render and compare. Adjust as needed.
See: references/calibration-workflow.md for detailed step-by-step guide.
Responsive Positioning
Scale-Based Positioning
function ResponsiveCallout({ baseWidth = 1920, baseHeight = 1080, x, y, ...props }) { const { width, height } = useVideoConfig();
// Scale coordinates proportionally const scaledX = (x / baseWidth) * width; const scaledY = (y / baseHeight) * height;
return <Callout x={scaledX} y={scaledY} {...props} />; }
Anchor-Based Positioning
// Position relative to anchors type Anchor = 'top-left' | 'top-center' | 'top-right' | 'center-left' | 'center' | 'center-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
function AnchoredCallout({ anchor, offsetX = 0, offsetY = 0, ...props }) { const { width, height } = useVideoConfig();
const anchors = { 'top-left': { x: 0, y: 0 }, 'center': { x: width / 2, y: height / 2 }, 'bottom-right': { x: width, y: height }, // ... other anchors };
const base = anchors[anchor]; return <Callout x={base.x + offsetX} y={base.y + offsetY} {...props} />; }
Format-Specific Presets
// Presets for common positions per format const CALLOUT_PRESETS = { '1920x1080': { title: { x: 960, y: 100 }, centerContent: { x: 960, y: 540 }, bottomCTA: { x: 960, y: 950 }, topRightBadge: { x: 1800, y: 100 }, }, '1080x1920': { title: { x: 540, y: 300 }, centerContent: { x: 540, y: 960 }, bottomCTA: { x: 540, y: 1700 }, }, '1080x1080': { title: { x: 540, y: 150 }, centerContent: { x: 540, y: 540 }, bottomCTA: { x: 540, y: 930 }, }, };
function useCalloutPreset(position: string) {
const { width, height } = useVideoConfig();
const format = ${width}x${height};
return CALLOUT_PRESETS[format]?.[position] ?? { x: width/2, y: height/2 };
}
Arrow Styling
Arrow Variants
// Solid arrow <Arrow fromX={100} fromY={100} toX={300} toY={200} strokeColor="#8b5cf6" strokeWidth={3} headSize={12} />
// Curved arrow <CurvedArrow fromX={100} fromY={100} toX={300} toY={200} curve={0.3} // Curve amount (0 = straight, 1 = max curve) strokeColor="#22c55e" />
// Dashed arrow <Arrow fromX={100} fromY={100} toX={300} toY={200} strokeDasharray="5,5" strokeColor="#f59e0b" />
Animated Arrows
<AnimatedArrow fromX={100} fromY={100} toX={300} toY={200} startFrame={30} drawDuration={15} // Frames to draw arrow strokeColor="#8b5cf6" />
Best Practices
- Use Debug Grid During Development
Always enable debug grid when positioning callouts. Disable for final renders.
const DEBUG = process.env.DEBUG_GRID === 'true'; <DebugGrid enabled={DEBUG} />
- Document Coordinates
Comment coordinates with context.
<Callout x={847} // Terminal window top-left corner y={312} // First line of output label="Result" />
- Test All Formats
Verify callout positions in all target formats before finalizing.
Render test frames for each format
npx remotion still MyComposition-Horizontal --frame=60 --output=test-h.png npx remotion still MyComposition-Vertical --frame=60 --output=test-v.png npx remotion still MyComposition-Square --frame=60 --output=test-s.png
- Use Relative Positioning When Possible
Prefer anchor-based or percentage positioning over hardcoded pixels for reusability.
- Layer Callouts Properly
Ensure callouts appear above content but below UI overlays.
Layer order (top to bottom):
- UI Overlays (watermark, progress)
- Callouts/Annotations
- Main Content
- Background
Common Pitfalls
Pitfall Problem Solution
Hardcoded coordinates Breaks on format change Use responsive positioning
No debug grid Guessing coordinates Enable DebugGrid during dev
Wrong layer order Callouts hidden Check z-index/layer stack
Missing safe zones Content cut off on mobile Use safe zone margins
No calibration Misaligned annotations Follow calibration workflow
References
-
references/debug-grid-component.md
-
Full React/Remotion debug grid component
-
references/coordinate-systems.md
-
Grid systems for different resolutions
-
references/calibration-workflow.md
-
Step-by-step positioning workflow
Related Skills
-
remotion-composer
-
Core Remotion composition patterns
-
video-storyboarding
-
Scene planning and structure
-
video-pacing
-
Timing and rhythm for animations
Key Decisions
Decision Choice Rationale
Coordinate origin Top-left (0,0) Standard screen coordinate convention
Debug grid default Disabled Performance in production
Position units Pixels Direct mapping to render resolution
Responsive method Scale-based Works across all formats consistently
Skill Version: 1.0.0 Last Updated: 2026-01-25
Capability Details
debug-grid
Keywords: debug, grid, overlay, coordinates, ruler, measurement Solves:
-
How do I see coordinates in my Remotion composition?
-
Debug grid for video positioning
-
Visualize pixel coordinates during development
callout-placement
Keywords: callout, annotation, arrow, pointer, label, highlight Solves:
-
How do I add callouts to my video?
-
Position arrows and labels in Remotion
-
Annotate video content with pointers
coordinate-calibration
Keywords: calibrate, measure, screenshot, position, align Solves:
-
How do I find exact coordinates for elements?
-
Screenshot-based coordinate calibration
-
Measure pixel positions in video frames
responsive-positioning
Keywords: responsive, scale, anchor, format, resolution Solves:
-
How do I make callouts work across formats?
-
Responsive positioning for 1080p and 4K
-
Anchor-based positioning in Remotion