关于 interactivity-best-practices
面向 Remotion 动画创作者的交互性实践指南,介绍如何组织动画和效果参数,以便在 Remotion Studio Visual Mode 中发现并编辑。
主要功能
- 01优先使用 interpolate()
- 02采用独立 CSS 变换属性
- 03将可编辑值内联
- 04保持效果数组无条件
- 05使用 Interactive.* 元素
适用场景
- 01制作可在 Visual Mode 调整的动画
- 02配置可编辑的弹簧式缓动
- 03让效果参数可视化编辑
- 04创建可交互调整的文本元素
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ shadcn-labs/ snapcn --skill interactivity-best-practices安装后在 Claude Code 中输入/interactivity-best-practices确认已加载。
详细介绍
交互最佳实践
创建或审查 Remotion 动画时,请遵循以下指南,尤其是在动画需要支持 Remotion Studio 可视化模式编辑时。
优先使用 interpolate(),而非独立的 spring()
大多数动画值优先使用 interpolate()。
- 人和 Agent 都更容易理解。
- 贝塞尔缓动在 CSS 中很常见,可实现利落或跳跃的运动。
- Studio 可视化模式可以编辑
interpolate()关键帧。
如果动画需要呈现弹簧效果,请将可编辑值保留在 interpolate() 中,并将 Easing.spring() 作为缓动函数传入。
优先使用:
style={{
scale: interpolate(frame, [0, 30], [0, 1], {
easing: Easing.spring({
damping: 200,
}),
}),
}}
❌ 避免将 spring() 用作独立驱动器,尤其是在相同运动可以通过 interpolate() 缓动实现时:
const scale = spring({
frame,
fps,
config: {
damping: 200,
},
});
style={{
scale,
}}
Easing.spring() 支持 damping、mass、stiffness 和 overshootClamping。它会归一化为插值进度,因此不接受 frame、fps、from、to、delay、reverse、durationInFrames 或 durationRestThreshold。
只有当动画确实需要无法通过 interpolate() 的缓动表示的、由帧驱动的物理弹簧模拟时,才使用独立的 spring()。
优先使用独立的 CSS transform 属性
使用 scale、rotate 和 translate 等独立的 CSS transform 属性,而不是拼接 transform 字符串。
优先使用:
style={{
scale: interpolate(frame, [0, 100], [0, 2]),
}}
❌ 避免:
style={{
transform: `scale(${interpolate(frame, [0, 100], [0, 2])})`,
}}
独立的 transform 属性可以在 Studio 可视化模式中编辑。隐藏在 transform 字符串中的值则无法编辑。
将可编辑值直接写在行内
如果某个值需要支持可视化编辑,请直接在 JSX 样式对象中进行插值。
优先使用:
style={{
scale: interpolate(frame, [0, 100], [0, 2]),
}}
❌ 避免:
const scale = interpolate(frame, [0, 100], [0, 2]);
style={{
scale,
}}
行内计算和字面值可让 Studio 可视化模式发现并编辑关键帧和属性。
这也适用于效果参数。请将可编辑的效果值直接写在效果调用中。
优先使用:
effects={[
radialProgressiveBlur({
center: [0.5, 0.5],
point1: [0.86, 0.36],
point2: [0.68, 0.84],
}),
]}
❌ 避免将可编辑值隐藏在常量中:
const center = [0.5, 0.5] as const;
effects={[
radialProgressiveBlur({
center,
}),
]}
保持效果无条件
使用 effects 属性时,请保持效果数组结构为无条件形式。Studio 可视化模式无法可靠地编辑仅存在于条件表达式中的效果。
如果某个版本需要效果而另一个版本不需要,请优先分别渲染不同元素:
<CanvasImage src={src} width={1280} height={720} />
<CanvasImage
src={src}
width={1280}
height={720}
effects={[
blur({
radius: interpolate(frame, [0, 100], [0, 40]),
}),
]}
/>
❌ 避免有条件地包含效果:
<CanvasImage
src={src}
width={1280}
height={720}
effects={enabled ? [blur({radius: 40})] : []}
/>
请在无条件的效果调用中直接写入可编辑的效果参数。不要为坐标、颜色、数值控件或插值等可编辑值传入变量。
直接插值旋转和位移
直接对 rotate 和 translate 插值 CSS 单位字符串。
优先使用:
style={{
rotate: interpolate(frame, [0, 100], ["20deg", "90deg"]),
translate: interpolate(frame, [0, 100], ["0px 0px", "100px 100px"]),
}}
❌ 如果属性本身可以直接插值,请避免先分别对数字进行插值,再手动拼接字符串。
直接插值这些属性受到支持,并且在 Studio 中进行可视化编辑时效果更好。
使用 Interactive.* 表示可调整元素
对于可能需要在 Studio 中调整的元素,请使用 remotion 中的 Interactive 命名空间。
import {Interactive} from "remotion";
例如:
<Interactive.Div
style={{
color: "red",
fontSize: 80,
}}
>
Hello
</Interactive.Div>
<Interactive.Div>、<Interactive.Span> 和其他 Interactive.* 组件的行为与对应的常规 HTML 元素相同,但支持在 Studio 中进行交互。
这些元素上的行内样式(例如文本颜色和字号)可以通过交互方式统一调整。