interactivity-best-practices

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Interactivity Best Practices

交互性最佳实践

Use these guidelines when creating or reviewing Remotion animations, especially if the animation should be editable in Remotion Studio Visual Mode.
在创建或审核Remotion动画时,请遵循这些指南,尤其是当动画需要在Remotion Studio可视化模式下可编辑时。

Prefer
interpolate()
over standalone
spring()

优先使用
interpolate()
而非独立的
spring()

Prefer
interpolate()
for most animation values.
  • It is easier for humans and agents to reason about.
  • Bezier easings are familiar from CSS and can express snappy or jumpy motion.
  • Studio Visual Mode can edit
    interpolate()
    keyframes.
When an animation should feel like a spring, keep the editable value in
interpolate()
and pass
Easing.spring()
as the easing function.
Prefer:
tsx
style={{
  scale: interpolate(frame, [0, 30], [0, 1], {
    easing: Easing.spring({
      damping: 200,
    }),
  }),
}}
❌ Avoid using
spring()
as a separate driver when the same motion can be expressed as
interpolate()
easing:
tsx
const scale = spring({
  frame,
  fps,
  config: {
    damping: 200,
  },
});

style={{
  scale,
}}
Easing.spring()
supports
damping
,
mass
,
stiffness
, and
overshootClamping
. It is normalized to the interpolation progress, so it does not take
frame
,
fps
,
from
,
to
,
delay
,
reverse
,
durationInFrames
, or
durationRestThreshold
.
Use standalone
spring()
only when the animation specifically needs a frame-driven physical spring simulation that cannot be represented as an easing on
interpolate()
.
大多数动画值优先使用
interpolate()
  • 人类和Agent更容易理解其逻辑。
  • 贝塞尔缓动在CSS中很常见,可以表达活泼或跳跃的运动效果。
  • Studio可视化模式可编辑
    interpolate()
    的关键帧。
当动画需要弹簧效果时,将可编辑值放在
interpolate()
中,并传入
Easing.spring()
作为缓动函数。
推荐写法:
tsx
style={{
  scale: interpolate(frame, [0, 30], [0, 1], {
    easing: Easing.spring({
      damping: 200,
    }),
  }),
}}
❌ 避免在可以用
interpolate()
缓动实现相同运动时,使用独立的
spring()
作为驱动:
tsx
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()

Prefer individual CSS transform properties

优先使用独立的CSS变换属性

Use individual CSS transform properties such as
scale
,
rotate
, and
translate
instead of composing a
transform
string.
Prefer:
tsx
style={{
  scale: interpolate(frame, [0, 100], [0, 2]),
}}
❌ Avoid:
tsx
style={{
  transform: `scale(${interpolate(frame, [0, 100], [0, 2])})`,
}}
Individual transform properties are editable in Studio Visual Mode. Values hidden inside a
transform
string are not.
使用
scale
rotate
translate
等独立的CSS变换属性,而非组合
transform
字符串。
推荐写法:
tsx
style={{
  scale: interpolate(frame, [0, 100], [0, 2]),
}}
❌ 避免写法:
tsx
style={{
  transform: `scale(${interpolate(frame, [0, 100], [0, 2])})`,
}}
独立的变换属性可在Studio可视化模式下编辑。隐藏在
transform
字符串中的值则无法编辑。

Keep editable values inline

将可编辑值内联

Put the interpolation directly in the JSX style object when the value should be visually editable.
Prefer:
tsx
style={{
  scale: interpolate(frame, [0, 100], [0, 2]),
}}
❌ Avoid:
tsx
const scale = interpolate(frame, [0, 100], [0, 2]);

style={{
  scale,
}}
Inline computations and literal values let Studio Visual Mode discover and edit the keyframes and props.
This also applies to effect parameters. Keep editable effect values inline in the effect call.
Prefer:
tsx
effects={[
  radialProgressiveBlur({
    center: [0.5, 0.5],
    point1: [0.86, 0.36],
    point2: [0.68, 0.84],
  }),
]}
❌ Avoid hiding editable values behind constants:
tsx
const center = [0.5, 0.5] as const;

effects={[
  radialProgressiveBlur({
    center,
  }),
]}
当值需要可视化编辑时,直接将插值放在JSX样式对象中。
推荐写法:
tsx
style={{
  scale: interpolate(frame, [0, 100], [0, 2]),
}}
❌ 避免写法:
tsx
const scale = interpolate(frame, [0, 100], [0, 2]);

style={{
  scale,
}}
内联计算和字面量值能让Studio可视化模式发现并编辑关键帧和属性。
这也适用于特效参数。将可编辑的特效值内联在特效调用中。
推荐写法:
tsx
effects={[
  radialProgressiveBlur({
    center: [0.5, 0.5],
    point1: [0.86, 0.36],
    point2: [0.68, 0.84],
  }),
]}
❌ 避免将可编辑值隐藏在常量后:
tsx
const center = [0.5, 0.5] as const;

effects={[
  radialProgressiveBlur({
    center,
  }),
]}

Keep effects unconditional

保持特效无条件存在

When using the
effects
prop, keep the effect array shape unconditional. Studio Visual Mode cannot reliably edit an effect that only exists behind a conditional expression.
Prefer rendering separate elements when one version should have effects and another should not:
tsx
<CanvasImage src={src} width={1280} height={720} />
<CanvasImage
  src={src}
  width={1280}
  height={720}
  effects={[
    blur({
      radius: interpolate(frame, [0, 100], [0, 40]),
    }),
  ]}
/>
❌ Avoid conditionally including an effect:
tsx
<CanvasImage
  src={src}
  width={1280}
  height={720}
  effects={enabled ? [blur({radius: 40})] : []}
/>
Keep editable effect parameters inline inside the unconditional effect call. Do not pass variables for editable values such as coordinates, colors, numeric controls, or interpolations.
使用
effects
属性时,保持特效数组的结构无条件。Studio可视化模式无法可靠编辑仅在条件表达式下存在的特效。
当一个版本需要特效而另一个不需要时,优先渲染单独的元素:
tsx
<CanvasImage src={src} width={1280} height={720} />
<CanvasImage
  src={src}
  width={1280}
  height={720}
  effects={[
    blur({
      radius: interpolate(frame, [0, 100], [0, 40]),
    }),
  ]}
/>
❌ 避免条件性添加特效:
tsx
<CanvasImage
  src={src}
  width={1280}
  height={720}
  effects={enabled ? [blur({radius: 40})] : []}
/>
将可编辑的特效参数内联在无条件的特效调用中。不要将坐标、颜色、数值控件或插值等可编辑值作为变量传递。

Interpolate rotation and translation directly

直接插值旋转和平移

Interpolate CSS unit strings directly for
rotate
and
translate
.
Prefer:
tsx
style={{
  rotate: interpolate(frame, [0, 100], ["20deg", "90deg"]),
  translate: interpolate(frame, [0, 100], ["0px 0px", "100px 100px"]),
}}
❌ Avoid manually building strings around separately interpolated numbers when the property can be interpolated directly.
Direct interpolation of these properties is supported and works better with visual editing in Studio.
rotate
translate
直接插值CSS单位字符串。
推荐写法:
tsx
style={{
  rotate: interpolate(frame, [0, 100], ["20deg", "90deg"]),
  translate: interpolate(frame, [0, 100], ["0px 0px", "100px 100px"]),
}}
❌ 避免在属性可直接插值时,手动将单独插值的数字拼接成字符串。
这些属性的直接插值已被支持,且在Studio的可视化编辑中表现更好。

Use
Interactive.*
for tweakable elements

使用
Interactive.*
组件实现可调整元素

Use the
Interactive
namespace from
remotion
when an element is likely to be tweaked in Studio.
tsx
import {Interactive} from "remotion";
For example:
tsx
<Interactive.Div
  style={{
    color: "red",
    fontSize: 80,
  }}
>
  Hello
</Interactive.Div>
<Interactive.Div>
,
<Interactive.Span>
, and the other
Interactive.*
components behave like their regular HTML equivalents, but enable interactivity in Studio.
Inline styles on these elements, such as text color and font size, can be standardized interactively.
当元素可能需要在Studio中调整时,使用
remotion
中的
Interactive
命名空间。
tsx
import {Interactive} from "remotion";
示例:
tsx
<Interactive.Div
  style={{
    color: "red",
    fontSize: 80,
  }}
>
  Hello
</Interactive.Div>
<Interactive.Div>
<Interactive.Span>
及其他
Interactive.*
组件的行为与常规HTML组件类似,但在Studio中启用了交互性。
这些元素的内联样式(如文本颜色和字体大小)可通过交互方式进行标准化调整。