Remotion 视频标注实战:3 步用框选、箭头与脉动高亮引导观众视线
【免费下载链接】remotion🎥 Make videos programmatically with React项目地址: https://gitcode.com/GitHub_Trending/re/remotion
录制屏幕教程时,最难的不是录下来,而是让观众的视线落在关键操作上。Remotion 的视频标注思路很直接:把标注写成 React 组件,用形状库框出重点区域,让箭头滑入画面,再给高亮加上脉动节奏。下面用三步搭出来。
用 Rect 和 Circle 框住重点区域
让重点"跳出来"最朴素的办法,是在画面上叠一层半透明形状。Remotion 形状组件(@remotion/shapes)直接提供了一组现成的 SVG 形状,不用自己拼路径:
Rect用width/height/cornerRadius定义矩形,fill设空、只给stroke就得到"空心框"Circle用radius定义圆,适合压住一个按钮或头像- 位置由
x/y决定,改数字即移动;换高亮颜色只需要改fill或stroke一个属性 - 全部形状组件的源码在 packages/shapes/src/components/,需要时可以直接看实现
下面这个最小组合解决"框住一块区域 + 压住一个按钮"的问题:
import {AbsoluteFill} from 'remotion'; import {Circle, Rect} from '@remotion/shapes'; export const HighlightZone = () => ( <AbsoluteFill> {/* 空心框:圈住操作区域 */} <Rect x={120} y={200} width={640} height={320} cornerRadius={16} fill="none" stroke="#2b6ef2" strokeWidth={6} /> {/* 实心圆:盖住待点击的按钮 */} <Circle x={820} y={560} radius={46} fill="rgba(255,193,7,0.35)" stroke="#ffc107" strokeWidth={4} /> </AbsoluteFill> );用 Arrow 滑入画面完成视线交接
框住了区域,箭头怎么引过来?形状库里其实有现成的Arrow组件,四个方向任选,不需要手写折线路径:
direction控制朝向(left/right/up/down),length/headWidth/shaftWidth控制粗细比例cornerRadius让箭头转角变圆润,高码率渲染下不会显得生硬- 想让它"滑进来",用
interpolate把帧号映射成位移——interpolate就是"帧 12 到 36 对应进度 0 到 1"这样的线性换算,Remotion 箭头标注的动态部分基本都靠它
下面这段解决"箭头在第 12 帧开始、第 36 帧滑到位"的问题:
import {useCurrentFrame, interpolate, Easing} from 'remotion'; import {Arrow} from '@remotion/shapes'; export const GuideArrow = () => { const frame = useCurrentFrame(); // 渲染时返回当前帧号 const slide = interpolate(frame, [12, 36], [0, 1], { easing: Easing.out(Easing.cubic), extrapolateRight: 'clamp', }); return ( <Arrow x={760 - slide * 120} y={520} direction="left" length={220} headWidth={110} headLength={90} shaftWidth={40} cornerRadius={10} fill="#e5484d" /> ); };useCurrentFrame()是 Remotion 的动画入口:组件每次渲染都能拿到"现在是第几帧",所有随时间变化的标注都从它出发。
让标注随时间脉动或沿路径走
静止的高亮大约 0.5 秒就会被观众"视而不见",加上节奏感才能持续吸住视线:
- 脉动最简单的做法是用正弦波驱动
radius,让高亮圆"呼吸" - 需要标注沿贝塞尔曲线巡航时,packages/paths/ 里的
getPointAtLength()能按长度取曲线上任意一点坐标,逐帧求位置即可 - 更多缓动与变换函数见 packages/animation-utils/,标注动画视频里常用的"缩放 + 位移"组合都能拼出来
下面这个片段解决"高亮圆如何呼吸"的问题:
import {useCurrentFrame} from 'remotion'; import {Circle} from '@remotion/shapes'; export const PulsingDot = ({x, y}: {x: number; y: number}) => { const frame = useCurrentFrame(); // 半径在 30 到 46 之间往复,形成呼吸感脉动 const radius = 38 + 8 * Math.sin(frame / 5); return ( <Circle x={x} y={y} radius={radius} fill="rgba(16,185,129,0.3)" stroke="#10b981" strokeWidth={5} /> ); };把三者合成一个完整标注片段
真实教程里的一次标注 = 区域框 + 箭头 + 脉动点,全部由同一个帧号驱动,出场时机用spring()统一控制:
spring()生成带回弹的动画曲线,标注"弹"进画面,比硬切柔和得多- 把整层标注放进一个组件,改一处坐标就能对齐到录屏里的任意位置
- 想让箭头比框晚半拍出现,给单个元素套一层
Sequence延迟即可
下面这个片段解决"一个完整标注层如何一次成型"的问题:
import {AbsoluteFill, useCurrentFrame, spring} from 'remotion'; import {Arrow, Circle, Rect} from '@remotion/shapes'; export const TutorialMarks = () => { const frame = useCurrentFrame(); // 弹簧动画让整层标注"弹"进画面 const appear = spring({frame, fps: 30}); return ( <AbsoluteFill style={{opacity: appear}}> <Rect x={80} y={140} width={720} height={360} cornerRadius={18} fill="rgba(43,110,242,0.08)" stroke="#2b6ef2" strokeWidth={4} /> <Circle x={520} y={320} radius={44} fill="rgba(255,193,7,0.35)" stroke="#ffc107" strokeWidth={4} /> <Arrow x={700} y={300} direction="left" length={200} headWidth={100} shaftWidth={36} fill="#e5484d" /> </AbsoluteFill> ); };避坑与性能调优
- ⏱坐标绑定分辨率:所有
x/y都是按 1920×1080 硬写的,换成竖屏就要整体重算。建议把标注坐标参数化,或从 composition 尺寸推导 - 别在每帧里造新对象:静态标注的常量和子组件提到组件外或用
useMemo缓存,减少不必要的重新计算 - 透明层叠加会"糊":三层
rgba高亮叠在一起颜色会脏,同一区域的高亮保持在两层以内 - 标注和视频分开渲染:标注层独立成一个 composition,最后合成进主视频,标注改色、调位都不必重渲整个片段
下一步
Star、Triangle、Heart 等更多形状组件都在 packages/shapes/src/components/,配合 packages/animation-utils/ 的缓动函数可以拼出更复杂的标注动画;完整 API 文档见 packages/docs/。把本文最后那段标注片段拷进你的下一个视频项目,改几个坐标就能用。
【免费下载链接】remotion🎥 Make videos programmatically with React项目地址: https://gitcode.com/GitHub_Trending/re/remotion
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考