mcpField
I
interactivity-best-practices

interactivity-best-practices

github.com/shadcn-labs创意与媒体54699 次安装1 天前更新
代码仓库

关于 interactivity-best-practices

面向 Remotion 动画创作者的交互性实践指南,介绍如何组织动画和效果参数,以便在 Remotion Studio Visual Mode 中发现并编辑。

主要功能

  1. 01优先使用 interpolate()
  2. 02采用独立 CSS 变换属性
  3. 03将可编辑值内联
  4. 04保持效果数组无条件
  5. 05使用 Interactive.* 元素

适用场景

  1. 01制作可在 Visual Mode 调整的动画
  2. 02配置可编辑的弹簧式缓动
  3. 03让效果参数可视化编辑
  4. 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 中进行交互。

这些元素上的行内样式(例如文本颜色和字号)可以通过交互方式统一调整。

评论

支持 Markdown