跳到主要内容

CodeBlock(已弃用)

CodeBlock 已被弃用,将在第 4 版中移除。请改用新的 Code 节点

CodeBlock 组件用于展示语法高亮的代码。它可以自动高亮许多常见语言。该代码可以就地修改以向查看者展示更改。修改后的代码将通过删除旧代码、转换剩余代码和插入新代码,从之前的代码动画过渡到新代码。您还可以"选择"代码以引起对重要代码片段的注意。

使用组件

要显示代码,请设置 codelanguage 属性。

import {CodeBlock} from '@motion-canvas/2d/lib/components/CodeBlock';

yield view.add(
<CodeBlock language="c#" code={`Console.WriteLine("Hello World!")`} />,
);

您可以在 Starry Night 仓库中找到可用语言列表,这是用于语法高亮的库。默认语言是 tsx,即 Motion Canvas 的语言,我们将在本指南的其余部分使用它。

请注意,与大多数组件不同,您必须 yield 任何包含 CodeBlockadd 调用。这会提示 Motion Canvas 准备语法高亮器。

yield view.add(<CodeBlock />);

缩进

为方便起见,每当代码以换行符开头时,代码的缩进会自动调整。

import {CodeBlock} from '@motion-canvas/2d/lib/components/CodeBlock';

yield view.add(
// 注意 ` 后面跟着一个换行符
<CodeBlock
code={`
console.log('Hello World!')
// 更多缩进
// 更少缩进`}
/>,
);
console.log('Hello World!');
// 更多缩进
// 更少缩进

然后,缩进由缩进最少的代码设置。

import {CodeBlock} from '@motion-canvas/2d/lib/components/CodeBlock';

yield view.add(
// 注意 ` 后面跟着一个换行符
<CodeBlock
code={`
console.log('Hello World!')
// 更少缩进
// 更多缩进`}
/>,
);
  console.log('Hello World!');
// 更少缩进
// 更多缩进

选择

可以对代码进行"选择"以引起注意。默认行为是使任何未选中的文本去饱和。

使用辅助函数

您可以使用三个辅助函数来定义选择——rangewordlines

import {CodeBlock} from '@motion-canvas/2d/lib/components/CodeBlock';
import {createRef} from '@motion-canvas/core';

const codeBlockRef = createRef<CodeBlock>();
yield view.add(
<CodeBlock ref={codeBlockRef} code={`...`} selection={range(0, 2, 0, 4)} />,
);
// 或
yield codeBlockRef.selection(range(0, 2, 0, 4));

range 需要 4 个参数:起始行、起始字符偏移、结束行和结束字符偏移。但请注意,所有值都是从零开始索引的。因此,如果您想在第一行选择一个 5 个字符长的单词,该行前面还有另外 4 个字符,您将使用以下调用:

range(
0, // 从第一行开始
4, // 从第 5 个字符开始
0, // 在第一行结束
8, // 在第 9 个字符结束
);

对于这个特定用例,还有另一个辅助函数 word。它需要 2-3 个参数——起始行和字符偏移,以及一个可选的单词长度。

上述 range 示例可以使用 word 辅助函数重写如下:

word(
0, // 从第一行开始
4, // 从第 5 个字符开始
5, // 选择总共 5 个字符,可以省略,将选择该行的其余部分
);

请注意,word 辅助函数只能逐行应用。

最后,您可以使用 lines 函数来选择整行代码。以下将选择第 5 行到第 10 行:

lines(
4, // 起始行
9, // 结束行,可以省略,将只选择起始行
);

您还可以使用展开运算符混合和匹配辅助函数!

您可以使用以下表达式选择第 3 行和第 5 行从第 6 个字符开始的 10 个字符长的单词:

yield * codeRef().selection([...lines(2), ...word(4, 5, 10)], 1);

如果您想撤消选择,可以选择从 0Infinity 的所有行,或者简单地传递 DEFAULT 作为选择,如下所示:

import {DEFAULT} from '@motion-canvas/core';

// 高亮显示第 1 和第 2 行
yield * codeRef().selection(lines(1, 2), 1);

// 高亮显示所有行
yield * codeRef().selection(DEFAULT, 1);

原始用法

在底层,辅助函数返回一个嵌套数组,使用两个元组定义多个选择,每个选择定义行和字符偏移。

<CodeBlock
selection={[
[
// 第一个选择
[lineFrom, characterFrom],
[lineTo, characterTo],
],
[
// 第二个选择
[lineFrom, characterFrom],
[lineTo, characterTo],
],
[
//... 等等
],
]}
/>

例如,lines(4,7) 将返回以下结构:

[
[
[4, 0],
[7, Infinity],
],
];

代码动画

您可以插入、删除或编辑显示的代码,其中任何一个都会将代码动画到其新状态。所有这些更改都是通过 CodeBlock 实例上的 edit 方法执行的。

要插入代码,首先使用 createRef 存储您的 CodeBlock 实例以供将来编辑。然后调用 edit 并嵌入 insert 调用来添加新代码。

import {CodeBlock, insert} from '@motion-canvas/2d/lib/components/CodeBlock';
import {createRef} from '@motion-canvas/core';

const codeRef = createRef<CodeBlock>();

yield view.add(<CodeBlock ref={codeRef} code={`var myBool;`} />);

// 持续时间 1.2 秒
yield * codeRef().edit(1.2)`var myBool${insert(' = true')};`;
var myBool;
// 将动画到
var myBool = true;

删除代码类似,只是在动画过程中删除提供的代码。

import {CodeBlock, remove} from '@motion-canvas/2d/lib/components/CodeBlock';

yield view.add(<CodeBlock ref={codeRef} code={`var myBool = true;`} />);

yield * codeRef().edit(1.2)`var myBool${remove(' = true')};`;
var myBool = true;
// 将动画到
var myBool;

最后,替换代码将删除和插入合并到一个调用中。

yield view.add(<CodeBlock ref={codeRef} code={`var myBool = true;`} />);

yield * codeRef().edit(1.2)`var myBool = ${edit('true', 'false')};`;
var myBool = true;
// 将动画到
var myBool = false;

编辑代码将更新您的选择以高亮显示更改。如果您想在动画中保留选择,请使用 edit(duration, false)

yield view.add(<CodeBlock ref={codeRef} code={`var myBool;`} />);

// 注意 edit 的第二个参数
yield * codeRef().edit(1.2, false)`var myBool${insert(' = true')};`;

您可以在视频过程中对代码块应用多次编辑,每次将之前的代码修改为新状态。

yield view.add(<CodeBlock ref={codeRef} code={`var myBool;`} />);

yield * codeRef().edit(1.2)`var myBool${insert(' = true')};`;
yield * waitFor(1);
yield * codeRef().edit(1.2)`var myBool = ${edit('true', 'false')};`;
yield * waitFor(1);
yield * codeRef().edit(1.2)`var myBool${remove(' = false')};`;

接下来的代码将通过以下方式动画

var myBool;
var myBool = true;
var myBool = false;
var myBool;

您还可以在一个 edit 中对代码块应用多个更改,以便同时应用所有更改。

yield view.add(<CodeBlock ref={codeRef} code={`var myBool;`} />);

yield *
codeRef().edit(1.2)`${edit('var', 'const')} myBool${insert(' = true')};`;
var myBool;
// 将动画到
const myBool = true;