Skip to main content

interpolate()

Also available as a 6min video
如何插值()

允许您使用简洁的语法将一系列值映射到另一个值。

示例:淡入效果

在此示例中,我们通过计算某一时间点的不透明度来淡入一些内容。 在第0帧(视频的开始),我们希望不透明度为0。 在第20帧,我们希望不透明度为1。

使用以下代码段,我们可以计算任何帧的当前不透明度:

ts
import { interpolate, useCurrentFrame } from "remotion";
 
const frame = useCurrentFrame(); // 10
const opacity = interpolate(frame, [0, 20], [0, 1]); // 0.5
ts
import { interpolate, useCurrentFrame } from "remotion";
 
const frame = useCurrentFrame(); // 10
const opacity = interpolate(frame, [0, 20], [0, 1]); // 0.5

示例:淡入淡出

我们保留淡入效果,但在最后添加淡出效果。 在视频结束前的20帧,不透明度仍应为1。 最后,不透明度应为0。

我们可以一次插值多个点,并使用useVideoConfig()来确定合成的持续时间。

ts
import { interpolate, useCurrentFrame, useVideoConfig } from "remotion";
 
const frame = useCurrentFrame();
const { durationInFrames } = useVideoConfig();
const opacity = interpolate(
frame,
[0, 20, durationInFrames - 20, durationInFrames],
// v--v---v----------------------v
[0, 1, 1, 0],
);
ts
import { interpolate, useCurrentFrame, useVideoConfig } from "remotion";
 
const frame = useCurrentFrame();
const { durationInFrames } = useVideoConfig();
const opacity = interpolate(
frame,
[0, 20, durationInFrames - 20, durationInFrames],
// v--v---v----------------------v
[0, 1, 1, 0],
);

示例:插值弹簧动画

我们不一定要随时间插值 - 我们可以使用任何值来驱动动画。 假设我们要在X轴上从0到200像素动画化一个对象,并为其使用弹簧动画。

让我们创建一个弹簧:

ts
import {useCurrentFrame, interpolate, spring, useVideoConfig} from 'remotion';
 
const frame = useCurrentFrame();
const {fps} = useVideoConfig();
const driver = spring({
frame,
fps
});
ts
import {useCurrentFrame, interpolate, spring, useVideoConfig} from 'remotion';
 
const frame = useCurrentFrame();
const {fps} = useVideoConfig();
const driver = spring({
frame,
fps
});

一个带有默认设置的spring()动画将从0到1进行动画。 有了这个知识,我们可以将弹簧值插值为从0到200。

ts
const marginLeft = interpolate(driver, [0, 1], [0, 200]);
ts
const marginLeft = interpolate(driver, [0, 1], [0, 200]);

然后我们可以将其应用于一个HTML元素。

tsx
const Component: React.FC = () => <div style={{ marginLeft }}></div>;
tsx
const Component: React.FC = () => <div style={{ marginLeft }}></div>;

示例:防止输出超出输出范围

考虑以下插值,应该在20帧内动画缩放:

tsx
const scale = interpolate(frame, [0, 20], [0, 1]);
tsx
const scale = interpolate(frame, [0, 20], [0, 1]);

这个方法是有效的,但是在 20 帧之后,值会持续增长。例如,在第 40 帧时,比例将为 2。 为了防止这种情况发生,我们可以使用 extrapolateLeftextrapolateRight 选项,并将它们设置为 'clamp',以防止结果超出输出范围。

tsx
const scale = interpolate(frame, [0, 20], [0, 1], {
extrapolateRight: "clamp",
});
tsx
const scale = interpolate(frame, [0, 20], [0, 1], {
extrapolateRight: "clamp",
});

参考

参数

  1. 输入值。
  2. 你期望输入值所处的值范围。
  3. 你希望输入值映射到的输出值范围。
  4. 选项对象。

选项

extrapolateLeft

默认: extend

如果输入值在输入范围的左侧之外,应该发生什么:

  • extend: 即使超出输出范围,仍然进行插值。
  • clamp: 返回范围内最接近的值
  • wrap: 循环值的变化。
  • identity: 返回输入值。

extrapolateRight

默认: extend

extrapolateLeft 相同,只是针对超出输入范围右侧的值。

示例:

tsx
interpolate(1.5, [0, 1], [0, 2], { extrapolateRight: "extend" }); // 3
interpolate(1.5, [0, 1], [0, 2], { extrapolateRight: "clamp" }); // 2
interpolate(1.5, [0, 1], [0, 2], { extrapolateRight: "identity" }); // 1.5
interpolate(1.5, [0, 1], [0, 2], { extrapolateRight: "wrap" }); // 1
tsx
interpolate(1.5, [0, 1], [0, 2], { extrapolateRight: "extend" }); // 3
interpolate(1.5, [0, 1], [0, 2], { extrapolateRight: "clamp" }); // 2
interpolate(1.5, [0, 1], [0, 2], { extrapolateRight: "identity" }); // 1.5
interpolate(1.5, [0, 1], [0, 2], { extrapolateRight: "wrap" }); // 1

easing

默认: (x) => x

允许您自定义输入的函数,例如应用某种特定的缓动函数。 默认情况下,输入保持不变,导致纯线性插值。阅读内置缓动函数的文档

ts
import { interpolate, Easing } from "remotion";
 
interpolate(frame, [0, 100], [0, 1], {
easing: Easing.bezier(0.8, 0.22, 0.96, 0.65),
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
});
 
//this is Remotion2.0 feature
interpolate(frame, [0, 10, 40, 100], [0, 0.2, 0.6, 1], {
easing: Easing.bezier(0.8, 0.22, 0.96, 0.65),
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
});
ts
import { interpolate, Easing } from "remotion";
 
interpolate(frame, [0, 100], [0, 1], {
easing: Easing.bezier(0.8, 0.22, 0.96, 0.65),
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
});
 
//this is Remotion2.0 feature
interpolate(frame, [0, 10, 40, 100], [0, 0.2, 0.6, 1], {
easing: Easing.bezier(0.8, 0.22, 0.96, 0.65),
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
});

类型

v3.3.77 版本起,Remotion 从输出选项中导出了类型。

tsx
import { ExtrapolateType, InterpolateOptions } from "remotion";
 
const extrapolate: ExtrapolateType = "clamp";
const option: InterpolateOptions = { extrapolateLeft: extrapolate };
tsx
import { ExtrapolateType, InterpolateOptions } from "remotion";
 
const extrapolate: ExtrapolateType = "clamp";
const option: InterpolateOptions = { extrapolateLeft: extrapolate };

参见