学习Remotion:用HTML, CSS和React创建动画视频

克里斯·劳克林
分享

制作一个带有文本、动画、颜色和形状的视频通常需要专业软件和多年的运动图形训练。如果你可以使用现有的工具集、培训和web开发背景来做同样的事情呢?

出发允许JavaScript开发人员重用他们已经建立的技能和知识,使用HTML、CSS和React JS创建复杂的动画视频。如果你可以用React渲染文本,用CSS样式制作动画,或者组织HTML内容,你现在就可以只使用代码创建和编辑自己的视频,而不需要视频编辑应用程序或软件。

在本文中,我将介绍使用Remotion的过程,并在此过程中向您介绍我的发现。

您可以在上面找到本文的完整代码GitHub

Remotion:什么?为什么?

Remotion是一个用于React的视频创建工具包乔尼汉堡.这个工具包允许任何对React、HTML或CSS有基本了解的人使用代码创建动画视频。

在视频创作领域,由于使用和掌握这些工具所需的软件和培训,目前进入门槛很高。通过利用JavaScript开发人员现有的工具包,这为更广泛的用户群打开了视频创作空间。随着视频变成代码,我们可以利用现有的模式来实现更有效的视频创建——比如基于参数的自动生成或构建管道。

开始

值得庆幸的是,通过Yarn和npm启动套件,Remotion有一个快速简单的设置过程。在这个例子中,我们将坚持使用npm作为构建和运行工具。在我们开始之前,你需要安装Node和npm。(如需帮助,请跟随本指南安装Node和npm。)同时查看拆卸安装指南如果你在Linux上,因为你可能需要安装额外的工具。设置好Node和npm后,让我们通过运行下面的代码创建一个新项目:

npm初始化视频

这将提示您输入一个项目名称,该名称也用作目录名称。对我们来说,就是这样我的视频.一旦进入,我们就可以进入我的视频目录并运行启动脚本启动默认的视频项目,如下所示:

cd我的视频<跨度class="token function">npm开始

执行start命令后,浏览器会自动打开。如果没有,打开浏览器并导航到http://localhost:3000/.此功能允许您观看和调试您正在创建的视频。播放器的控制包括播放按钮,允许您预览视频内容。从查看演示示例的代码开始可能也是有用的,Remotion提供了如何构建自己的视频的指南。

你好,世界!

我们将创建自己的视频动画文本“Hello, World!”,以掌握Remotion中提供的组件和过程。

首先,让我们删除现有的示例代码(src文件夹),因为我们想重新开始。然后,让我们创建一个演示目录下src目录,它将持有和管理我们所有的视频工作为这个项目。在演示目录,创建一个Demo.js文件:

进口<跨度class="token imports"><跨度class="token maybe-class-name">作文<跨度class="token punctuation">,插入<跨度class="token punctuation">,<跨度class="token maybe-class-name">序列<跨度class="token punctuation">,useCurrentFrame<跨度class="token punctuation">,useVideoConfig<跨度class="token punctuation">}<跨度class="token keyword module">从<跨度class="token string">“移动”<跨度class="token punctuation">;<跨度class="token keyword module">进口<跨度class="token imports">标题<跨度class="token keyword module">从<跨度class="token string">”。/标题”<跨度class="token punctuation">;<跨度class="token keyword module">进口<跨度class="token imports">你好<跨度class="token keyword module">从<跨度class="token string">”。/你好'<跨度class="token punctuation">;<跨度class="token keyword module">进口<跨度class="token string">”。/ demo.css”<跨度class="token punctuation">;<跨度class="token keyword">常量<跨度class="token function-variable function">演示<跨度class="token operator">=<跨度class="token punctuation">(<跨度class="token punctuation">)<跨度class="token arrow operator">= ><跨度class="token punctuation">{<跨度class="token keyword control-flow">返回<跨度class="token punctuation">(<跨度class="token operator"><div类名<跨度class="token operator">=<跨度class="token string">“集装箱”<跨度class="token operator">><跨度class="token punctuation">{<跨度class="token comment">/* TODO:添加视频内容*/<跨度class="token punctuation">}<跨度class="token operator"><<跨度class="token operator">/div<跨度class="token operator">><跨度class="token punctuation">)<跨度class="token punctuation">;<跨度class="token punctuation">}<跨度class="token punctuation">;<跨度class="token keyword module">出口<跨度class="token keyword">常量<跨度class="token function-variable function">DemoVideo<跨度class="token operator">=<跨度class="token punctuation">(<跨度class="token punctuation">)<跨度class="token arrow operator">= ><跨度class="token punctuation">{<跨度class="token keyword control-flow">返回<跨度class="token punctuation">(<跨度class="token operator"><<跨度class="token maybe-class-name">作文我d<跨度class="token operator">=<跨度class="token string">“演示”组件<跨度class="token operator">=<跨度class="token punctuation">{<跨度class="token maybe-class-name">演示<跨度class="token punctuation">}durationInFrames<跨度class="token operator">=<跨度class="token punctuation">{<跨度class="token number">150<跨度class="token punctuation">}帧/秒<跨度class="token operator">=<跨度class="token punctuation">{<跨度class="token number">30.<跨度class="token punctuation">}宽度<跨度class="token operator">=<跨度class="token punctuation">{<跨度class="token number">1920<跨度class="token punctuation">}高度<跨度class="token operator">=<跨度class="token punctuation">{<跨度class="token number">1080<跨度class="token punctuation">}defaultProps<跨度class="token operator">=<跨度class="token punctuation">{<跨度class="token punctuation">{t我tleText<跨度class="token operator">:<跨度class="token string">“这是我的第一个Remotion视频”<跨度class="token punctuation">,t我tleColor<跨度class="token operator">:<跨度class="token string">“蓝”<跨度class="token punctuation">,<跨度class="token punctuation">}<跨度class="token punctuation">}<跨度class="token operator">/<跨度class="token operator">><跨度class="token punctuation">)<跨度class="token punctuation">}

演示文件导出我们的视频代码。如您所见,我们可以创建一个演示组件,它将保存视频中的所有视觉元素。然后,可以导出一个呈现作文我们的视频。的作文组件允许我们定义一些基本属性,如视频剪辑的宽度和高度,FPS(每秒帧数),以及将被渲染的特征。我们还从Remotion导入了一些utils和钩子,以及一些我们将很快创建的附加组件。

目前我们的演示组件是空的,但让我们添加一些元素到我们的视频:

常量<跨度class="token function-variable function">演示<跨度class="token operator">=<跨度class="token punctuation">(<跨度class="token parameter">t我tleText<跨度class="token punctuation">,t我tleColor<跨度class="token punctuation">}<跨度class="token punctuation">)<跨度class="token arrow operator">= ><跨度class="token punctuation">{<跨度class="token keyword">常量框架<跨度class="token operator">=<跨度class="token function">useCurrentFrame<跨度class="token punctuation">(<跨度class="token punctuation">)<跨度class="token punctuation">;<跨度class="token keyword">常量videoConfig<跨度class="token operator">=<跨度class="token function">useVideoConfig<跨度class="token punctuation">(<跨度class="token punctuation">)<跨度class="token punctuation">;<跨度class="token keyword">常量totalOpacity<跨度class="token operator">=<跨度class="token function">插入<跨度class="token punctuation">(框架<跨度class="token punctuation">,<跨度class="token punctuation">[videoConfig<跨度class="token punctuation">.<跨度class="token property-access">durationInFrames<跨度class="token operator">-<跨度class="token number">25<跨度class="token punctuation">,videoConfig<跨度class="token punctuation">.<跨度class="token property-access">durationInFrames<跨度class="token operator">-<跨度class="token number">15<跨度class="token punctuation">]<跨度class="token punctuation">,<跨度class="token punctuation">[<跨度class="token number">1<跨度class="token punctuation">,<跨度class="token number">0<跨度class="token punctuation">]<跨度class="token punctuation">,<跨度class="token punctuation">{extrapolateLeft<跨度class="token operator">:<跨度class="token string">“夹”<跨度class="token punctuation">,extrapolateRight<跨度class="token operator">:<跨度class="token string">“夹”<跨度class="token punctuation">,<跨度class="token punctuation">}<跨度class="token punctuation">)<跨度class="token punctuation">;<跨度class="token keyword control-flow">返回<跨度class="token punctuation">(<跨度class="token operator"><div类名<跨度class="token operator">=<跨度class="token string">“集装箱”<跨度class="token operator">><跨度class="token operator"><div风格<跨度class="token operator">=<跨度class="token punctuation">{<跨度class="token punctuation">{不透明度<跨度class="token operator">:totalOpacity<跨度class="token punctuation">}<跨度class="token punctuation">}<跨度class="token operator">><跨度class="token operator"><<跨度class="token maybe-class-name">序列<跨度class="token keyword module">从<跨度class="token operator">=<跨度class="token punctuation">{<跨度class="token number">0<跨度class="token punctuation">}durationInFrames<跨度class="token operator">=<跨度class="token punctuation">{videoConfig<跨度class="token punctuation">.<跨度class="token property-access">durationInFrames<跨度class="token operator">/<跨度class="token number">2<跨度class="token punctuation">}<跨度class="token operator">><跨度class="token operator"><<跨度class="token maybe-class-name">你好<跨度class="token operator">/<跨度class="token operator">><跨度class="token operator"><<跨度class="token operator">/<跨度class="token maybe-class-name">序列<跨度class="token operator">><跨度class="token operator"><<跨度class="token maybe-class-name">序列<跨度class="token keyword module">从<跨度class="token operator">=<跨度class="token punctuation">{<跨度class="token number">35<跨度class="token punctuation">}durationInFrames<跨度class="token operator">=<跨度class="token punctuation">{<跨度class="token number">∞<跨度class="token punctuation">}<跨度class="token operator">><跨度class="token operator"><<跨度class="token maybe-class-name">标题t我tleText<跨度class="token operator">=<跨度class="token punctuation">{t我tleText<跨度class="token punctuation">}t我tleColor<跨度class="token operator">=<跨度class="token punctuation">{t我tleColor<跨度class="token punctuation">}<跨度class="token operator">/<跨度class="token operator">><跨度class="token operator"><<跨度class="token operator">/<跨度class="token maybe-class-name">序列<跨度class="token operator">><跨度class="token operator"><<跨度class="token operator">/div<跨度class="token operator">><跨度class="token operator"><<跨度class="token operator">/div<跨度class="token operator">><跨度class="token punctuation">)<跨度class="token punctuation">;<跨度class="token punctuation">}<跨度class="token punctuation">;

我们已经向文件中添加了很多内容,所以让我们将其分解。

首先在我们的渲染部分,我们可以从文件中看到我们现在可以返回一个不透明度样式的div,允许我们在视频的开始和结束淡入和淡出元素。对于不透明度值,我们使用一个Remotion helper。的插入函数允许您更好地定义动画并将动画值映射到当前帧和视频持续时间。在这个例子中,我们传入当前帧。该函数将在生成的每一帧上被调用。输入范围是从视频的持续时间计算出来的,输出值范围从0到1,因为这是不透明度CSS值的范围。随着演示组件为每一帧重新呈现插入函数将返回适当的不透明度值。

接下来,我们可以开始在视频屏幕上渲染不同的视觉元素。在这个例子中,我们想要文本“Hello, World!”淡出视野,然后消失,文字“这是我的第一个Remotion视频”,然后出现之后。为此,我们可以渲染多个序列组件。

一个序列component是另一个Remotion特性,它允许我们定义一个组件如何以及何时在视频中呈现以及呈现多长时间。这对于构建复杂的视频非常有用,你想添加定时或分层的元素,比如这个例子。每一个序列也将显示在浏览器播放器中,并根据子组件名称命名。这可以让你实时监控你正在生成的视频和你添加到视频中的效果。

出发还提供了一些有用的React钩子,在本例中我们使用useCurrentFrame而且useVideoConfig钩子。useCurrentFrame将返回视频所在的当前帧,这对于动画和基于视频播放的当前位置实现操作非常有用。useVideoConfig将返回一个具有不同值的对象,例如:

  • 宽度:视频的宽度-用于定位视频中的元素
  • 高度:视频的高度-用于定位视频中的元素
  • 帧/秒:每秒帧数-可用于确定动画或元素移动的速度
  • durationInFrames:以帧为单位的视频总长度-可用于计算动画或时间序列显示和隐藏。

在我们的例子中,如前所述,首先我们想要你好组件,文本“Hello, World!”,在视频开始时出现,并在屏幕上显示一半的时间。我们通过使用videoConfig.duration值,我们从useVideoConfigHook

第二点序列,我们想要标题组件文本,“这是我的第一个Remotion视频”,在35帧后出现,并在视频的整个持续时间内保持在屏幕上。要做到这一点,为我们进入35,以及durationInFrames我们进入

为了给我们的演示组件设置样式,我们可以使用CSS和内联样式。在使用CSS时,我们希望对整个视频应用样式,因此让我们创建一个demo.css文件,该文件将保存覆盖整个视频区域的任何样式。在我们的例子中,我们想让背景是白色的,并与Flexbox对齐:

.main-container<跨度class="token punctuation">{<跨度class="token property">flex<跨度class="token punctuation">:<跨度class="token number">1<跨度class="token punctuation">;<跨度class="token property">背景颜色<跨度class="token punctuation">:<跨度class="token color">白色<跨度class="token punctuation">;<跨度class="token punctuation">}

现在让我们更深入地研究我们渲染的这些元素。

在动画中渲染React组件

你好component将是一个基本的React组件,它渲染一个H1标签,应用了一些内联样式和文本“Hello, World!”这是我们可以呈现的组件的最简单形式。为了简单起见,我们可以使用内联样式。但因为这是React,你也可以从CSS文件中导入样式,并使用类名、样式组件、CSS模块或任何你已经熟悉的样式模式作为替代。让我们创建你好组件。在演示文件夹,创建一个新文件Hello.js

常量<跨度class="token function-variable function">你好<跨度class="token operator">=<跨度class="token punctuation">(<跨度class="token punctuation">)<跨度class="token arrow operator">= ><跨度class="token punctuation">{<跨度class="token keyword control-flow">返回<跨度class="token punctuation">(<跨度class="token operator"><h1风格<跨度class="token operator">=<跨度class="token punctuation">{<跨度class="token punctuation">{fontFamily<跨度class="token operator">:<跨度class="token string">“SF Pro Text, Helvetica, Arial”<跨度class="token punctuation">,fontWeight<跨度class="token operator">:<跨度class="token string">“大胆”<跨度class="token punctuation">,字形大小<跨度class="token operator">:<跨度class="token number">One hundred.<跨度class="token punctuation">,textAlign<跨度class="token operator">:<跨度class="token string">“中心”<跨度class="token punctuation">,位置<跨度class="token operator">:<跨度class="token string">“绝对”<跨度class="token punctuation">,底<跨度class="token operator">:<跨度class="token number">500<跨度class="token punctuation">,宽度<跨度class="token operator">:<跨度class="token string">“100%”<跨度class="token punctuation">}<跨度class="token punctuation">}<跨度class="token operator">><跨度class="token maybe-class-name">你好<跨度class="token punctuation">,<跨度class="token maybe-class-name">世界<跨度class="token operator">!<跨度class="token operator"><<跨度class="token operator">/h1<跨度class="token operator">><跨度class="token punctuation">)<跨度class="token punctuation">;<跨度class="token punctuation">}<跨度class="token punctuation">;<跨度class="token keyword module">出口<跨度class="token keyword module">默认的<跨度class="token maybe-class-name">你好<跨度class="token punctuation">;

现在,让我们看一个更复杂的例子。在演示文件夹,创建一个名为Title.js并添加下面的组件代码:

进口<跨度class="token imports">春天<跨度class="token punctuation">,useCurrentFrame<跨度class="token punctuation">,useVideoConfig<跨度class="token punctuation">}<跨度class="token keyword module">从<跨度class="token string">“移动”<跨度class="token punctuation">;<跨度class="token keyword">常量<跨度class="token function-variable function">标题<跨度class="token operator">=<跨度class="token punctuation">(<跨度class="token parameter">t我tleText<跨度class="token punctuation">,t我tleColor<跨度class="token punctuation">,底<跨度class="token punctuation">}<跨度class="token punctuation">)<跨度class="token arrow operator">= ><跨度class="token punctuation">{<跨度class="token keyword">常量videoConfig<跨度class="token operator">=<跨度class="token function">useVideoConfig<跨度class="token punctuation">(<跨度class="token punctuation">)<跨度class="token punctuation">;<跨度class="token keyword">常量框架<跨度class="token operator">=<跨度class="token function">useCurrentFrame<跨度class="token punctuation">(<跨度class="token punctuation">)<跨度class="token punctuation">;<跨度class="token keyword">常量文本<跨度class="token operator">=t我tleText<跨度class="token punctuation">.<跨度class="token method function property-access">分裂<跨度class="token punctuation">(<跨度class="token string">' '<跨度class="token punctuation">)<跨度class="token punctuation">.<跨度class="token method function property-access">地图<跨度class="token punctuation">(<跨度class="token punctuation">(<跨度class="token parameter">t<跨度class="token punctuation">)<跨度class="token arrow operator">= ><跨度class="token template-string"><跨度class="token string">$ {t<跨度class="token interpolation-punctuation punctuation">}<跨度class="token string"><跨度class="token punctuation">)<跨度class="token punctuation">;<跨度class="token keyword control-flow">返回<跨度class="token punctuation">(<跨度class="token operator"><h1风格<跨度class="token operator">=<跨度class="token punctuation">{<跨度class="token punctuation">{fontFamily<跨度class="token operator">:<跨度class="token string">“SF Pro Text, Helvetica, Arial”<跨度class="token punctuation">,fontWeight<跨度class="token operator">:<跨度class="token string">“大胆”<跨度class="token punctuation">,字形大小<跨度class="token operator">:<跨度class="token number">One hundred.<跨度class="token punctuation">,textAlign<跨度class="token operator">:<跨度class="token string">“中心”<跨度class="token punctuation">,位置<跨度class="token operator">:<跨度class="token string">“绝对”<跨度class="token punctuation">,底<跨度class="token operator">:底<跨度class="token operator">||<跨度class="token number">160<跨度class="token punctuation">,宽度<跨度class="token operator">:<跨度class="token string">“100%”<跨度class="token punctuation">,<跨度class="token punctuation">}<跨度class="token punctuation">}<跨度class="token operator">><跨度class="token punctuation">{文本<跨度class="token punctuation">.<跨度class="token method function property-access">地图<跨度class="token punctuation">(<跨度class="token punctuation">(<跨度class="token parameter">t<跨度class="token punctuation">,<跨度class="token punctuation">)<跨度class="token arrow operator">= ><跨度class="token punctuation">{<跨度class="token keyword control-flow">返回<跨度class="token punctuation">(<跨度class="token operator"><跨越的关键<跨度class="token operator">=<跨度class="token punctuation">{t<跨度class="token punctuation">}风格<跨度class="token operator">=<跨度class="token punctuation">{<跨度class="token punctuation">{颜色<跨度class="token operator">:t我tleColor<跨度class="token punctuation">,marginLeft<跨度class="token operator">:<跨度class="token number">10<跨度class="token punctuation">,marginRight<跨度class="token operator">:<跨度class="token number">10<跨度class="token punctuation">,变换<跨度class="token operator">:<跨度class="token template-string"><跨度class="token string">量表(<跨度class="token interpolation">$ {<跨度class="token function">春天<跨度class="token punctuation">(<跨度class="token punctuation">{帧/秒<跨度class="token operator">:videoConfig<跨度class="token punctuation">.<跨度class="token property-access">帧/秒<跨度class="token punctuation">,框架<跨度class="token operator">:框架<跨度class="token operator">-我<跨度class="token operator">*<跨度class="token number">5<跨度class="token punctuation">,配置<跨度class="token operator">:<跨度class="token punctuation">{阻尼<跨度class="token operator">:<跨度class="token number">One hundred.<跨度class="token punctuation">,刚度<跨度class="token operator">:<跨度class="token number">200<跨度class="token punctuation">,质量<跨度class="token operator">:<跨度class="token number">0.5<跨度class="token punctuation">,<跨度class="token punctuation">}<跨度class="token punctuation">,<跨度class="token punctuation">}<跨度class="token punctuation">)<跨度class="token interpolation-punctuation punctuation">}<跨度class="token string">)<跨度class="token template-punctuation string">`<跨度class="token punctuation">,显示<跨度class="token operator">:<跨度class="token string">“inline-block”<跨度class="token punctuation">,<跨度class="token punctuation">}<跨度class="token punctuation">}<跨度class="token operator">><跨度class="token punctuation">{t<跨度class="token punctuation">}<跨度class="token operator"><<跨度class="token operator">/跨度<跨度class="token operator">><跨度class="token punctuation">)<跨度class="token punctuation">;<跨度class="token punctuation">}<跨度class="token punctuation">)<跨度class="token punctuation">}<跨度class="token operator"><<跨度class="token operator">/h1<跨度class="token operator">><跨度class="token punctuation">)<跨度class="token punctuation">;<跨度class="token punctuation">}<跨度class="token punctuation">;<跨度class="token keyword module">出口<跨度class="token keyword module">默认的<跨度class="token maybe-class-name">标题<跨度class="token punctuation">;

我们有很多事情要做,所以让我们再分析一下发生了什么。

出发对TypeScript有一流的支持。这不是必需的,但它可以使开发过程更好,因为您将在IDE中获得更详细的自动完成建议。但是,为了使这个例子对初学者更友好,我们只使用普通的JavaScript。

我们的组件包含两个道具-titleText而且titleColor-稍后将在我们的渲染方法中使用。这表明,使用React,我们仍然可以在应用程序中传递道具,因此使我们的视频元素可重用和动态。你可能注意到了,在我们的演示组件,我们从作文组件。这显示了React的强大功能。我们可以从React应用程序的顶部传入道具,使视频具有响应性,这意味着你可以改变一个文本块来制作一个新视频或改变整个视频上下文。

在我们访问了道具之后标题组件时,我们再次调用Remotion钩子来获取videoConfig和帧数据。的标题组件然后分解传递的文本道具,并使用map和CSS转换的组合一次呈现一个单词。在这里,我们有机会使用另一个内置的helper函数。春天接受值以帮助生成动画值的平滑输出。我们通过主视频配置的FPS来控制动画的速度。帧值控制动画何时开始,最后我们传入额外的配置选项来控制动画的平滑度。

在我们创建了所有的视频组件并准备就绪后,我们需要最终创建一个index.js的根目录下的文件src文件夹并添加以下内容:

进口<跨度class="token imports">registerRoot<跨度class="token punctuation">}<跨度class="token keyword module">从<跨度class="token string">“移动”<跨度class="token punctuation">;<跨度class="token keyword module">进口<跨度class="token imports"><跨度class="token maybe-class-name">DemoVideo<跨度class="token punctuation">}<跨度class="token keyword module">从<跨度class="token string">“/演示/演示。”<跨度class="token punctuation">;<跨度class="token function">registerRoot<跨度class="token punctuation">(<跨度class="token maybe-class-name">DemoVideo<跨度class="token punctuation">)<跨度class="token punctuation">;

索引文件导入registerRoot来自Remotion的函数,它允许我们渲染视频内容。把这个看做ReactDOM渲染功能,而是为了情感。然后我们传递DemoVideo组件registerRoot,它将以开发或构建模式可视化呈现的视频。

我们现在导入演示视频,将由Remotion渲染。

现在我们已经将所有这些功能结合在一起,我们有了一个完整的动画视频,它提供了一个由Remotion提供的不同组件和helper函数的示例。

我们可以使用以下命令从项目的根目录运行视频:

./node_modules/.bin/移动预览src/index.js

或者,您可以更新开始脚本。package.json文件:

-<跨度class="token line">"start": "remotion预览src/index.tsx",<跨度class="token inserted-sign inserted">+<跨度class="token line">"start": "remotion预览src/index.js",

然后运行动画使用npm开始

创建星战动画

现在我们已经对Remotion和所提供的不同组件有了基本的了解,我们可以挑战自己并获得更多乐趣。让我们构建自己版本的标志性《星球大战》标题介绍屏幕。我们希望能够渲染一个闪亮的星星背景与明亮的黄色文本滚动屏幕。我们可以利用我们从“你好,世界!”的例子作为出发点。

让我们从创建所需的文件开始。在src文件夹,创建一个starWarsIndex.js文件和StarWars文件夹中。在StarWars文件夹,再创建四个文件:starWars.jsstarWars.cssstarsBackground.jsstarsBackground.css

当你完成后,src文件夹应该是这样的:

├──Demo│├──<跨度class="token string">“你好,世界!”demo├──index.js├──starwarsbackground .css│├──starsBackground.js│├──starwarsbackground .js│├──starWarsIndex.js

创建滚动文本

首先,我们从a开始StarWarsVideo组件,该组件将呈现作文组件来定义视频属性。由于滚动文本较长,我们定义了一个较高的值durationInFrames号码。

将以下内容添加到src / starWarsIndex.js

进口<跨度class="token imports">registerRoot<跨度class="token punctuation">,<跨度class="token maybe-class-name">作文<跨度class="token punctuation">,<跨度class="token maybe-class-name">序列<跨度class="token punctuation">}<跨度class="token keyword module">从<跨度class="token string">“移动”<跨度class="token punctuation">;<跨度class="token keyword module">进口<跨度class="token imports">useEffect<跨度class="token punctuation">,useState<跨度class="token punctuation">}<跨度class="token keyword module">从<跨度class="token string">“反应”<跨度class="token keyword module">进口<跨度class="token imports"><跨度class="token maybe-class-name">LoremIpsum<跨度class="token punctuation">}<跨度class="token keyword module">从<跨度class="token string">“回车键”<跨度class="token punctuation">;<跨度class="token keyword module">进口<跨度class="token imports">星星<跨度class="token keyword module">从<跨度class="token string">”。/ StarWars starsBackground”<跨度class="token punctuation">;<跨度class="token keyword module">进口<跨度class="token imports">StarWars<跨度class="token keyword module">从<跨度class="token string">”。/ StarWars StarWars”<跨度class="token punctuation">;<跨度class="token keyword">常量<跨度class="token function-variable function">StarWarsVideo<跨度class="token operator">=<跨度class="token punctuation">(<跨度class="token punctuation">)<跨度class="token arrow operator">= ><跨度class="token punctuation">{<跨度class="token keyword">常量<跨度class="token punctuation">[版面<跨度class="token punctuation">,setTextBlocks<跨度class="token punctuation">]<跨度class="token operator">=<跨度class="token function">useState<跨度class="token punctuation">(<跨度class="token punctuation">[<跨度class="token punctuation">]<跨度class="token punctuation">)<跨度class="token punctuation">;<跨度class="token function">useEffect<跨度class="token punctuation">(<跨度class="token punctuation">(<跨度class="token punctuation">)<跨度class="token arrow operator">= ><跨度class="token punctuation">{<跨度class="token function">setTextBlocks<跨度class="token punctuation">(<跨度class="token punctuation">[lorem<跨度class="token punctuation">.<跨度class="token method function property-access">generateSentences<跨度class="token punctuation">(<跨度class="token number">5<跨度class="token punctuation">)<跨度class="token punctuation">,lorem<跨度class="token punctuation">.<跨度class="token method function property-access">generateSentences<跨度class="token punctuation">(<跨度class="token number">5<跨度class="token punctuation">)<跨度class="token punctuation">,lorem<跨度class="token punctuation">.<跨度class="token method function property-access">generateSentences<跨度class="token punctuation">(<跨度class="token number">5<跨度class="token punctuation">)<跨度class="token punctuation">,<跨度class="token punctuation">]<跨度class="token punctuation">)<跨度class="token punctuation">}<跨度class="token punctuation">,<跨度class="token punctuation">[<跨度class="token punctuation">]<跨度class="token punctuation">)<跨度class="token keyword control-flow">返回<跨度class="token punctuation">(<跨度class="token operator"><<跨度class="token operator">><跨度class="token operator"><<跨度class="token maybe-class-name">作文我d<跨度class="token operator">=<跨度class="token string">“星战”组件<跨度class="token operator">=<跨度class="token punctuation">{<跨度class="token maybe-class-name">视频<跨度class="token punctuation">}durationInFrames<跨度class="token operator">=<跨度class="token punctuation">{<跨度class="token number">580<跨度class="token punctuation">}帧/秒<跨度class="token operator">=<跨度class="token punctuation">{<跨度class="token number">30.<跨度class="token punctuation">}宽度<跨度class="token operator">=<跨度class="token punctuation">{<跨度class="token number">1920<跨度class="token punctuation">}高度<跨度class="token operator">=<跨度class="token punctuation">{<跨度class="token number">1080<跨度class="token punctuation">}defaultProps<跨度class="token operator">=<跨度class="token punctuation">{<跨度class="token punctuation">{版面<跨度class="token punctuation">}<跨度class="token punctuation">}<跨度class="token operator">/<跨度class="token operator">><跨度class="token operator"><<跨度class="token operator">/<跨度class="token operator">><跨度class="token punctuation">)<跨度class="token punctuation">;<跨度class="token punctuation">}<跨度class="token punctuation">;<跨度class="token function">registerRoot<跨度class="token punctuation">(<跨度class="token maybe-class-name">StarWarsVideo<跨度class="token punctuation">)<跨度class="token punctuation">;

我们还需要定义一些React状态。在这个星球大战的例子中,我们将在每次重载视频时使用React状态和props生成随机文本。使用lorem ipsumNPM模块,我们可以使文本响应和不同的每次它的生成。

让我们安装模块:

npm我lorem ipsum

然后,在同一个文件中添加:

//导入语句<跨度class="token keyword">常量lorem<跨度class="token operator">=<跨度class="token keyword">新<跨度class="token class-name">LoremIpsum<跨度class="token punctuation">(<跨度class="token punctuation">{sentencesPerParagraph<跨度class="token operator">:<跨度class="token punctuation">{马克斯<跨度class="token operator">:<跨度class="token number">8<跨度class="token punctuation">,最小值<跨度class="token operator">:<跨度class="token number">4<跨度class="token punctuation">}<跨度class="token punctuation">,wordsPerSentence<跨度class="token operator">:<跨度class="token punctuation">{马克斯<跨度class="token operator">:<跨度class="token number">16<跨度class="token punctuation">,最小值<跨度class="token operator">:<跨度class="token number">4<跨度class="token punctuation">}<跨度class="token punctuation">}<跨度class="token punctuation">)<跨度class="token punctuation">;<跨度class="token keyword">常量<跨度class="token function-variable function">视频<跨度class="token operator">=<跨度class="token punctuation">(<跨度class="token parameter">版面<跨度class="token punctuation">}<跨度class="token punctuation">)<跨度class="token arrow operator">= ><跨度class="token punctuation">{<跨度class="token keyword control-flow">返回<跨度class="token punctuation">(<跨度class="token operator"><div<跨度class="token operator">><跨度class="token operator"><<跨度class="token maybe-class-name">序列<跨度class="token keyword module">从<跨度class="token operator">=<跨度class="token punctuation">{<跨度class="token number">0<跨度class="token punctuation">}durationInFrames<跨度class="token operator">=<跨度class="token punctuation">{<跨度class="token number">∞<跨度class="token punctuation">}<跨度class="token operator">><跨度class="token operator"><<跨度class="token maybe-class-name">星星<跨度class="token operator">/<跨度class="token operator">><跨度class="token operator"><<跨度class="token operator">/<跨度class="token maybe-class-name">序列<跨度class="token operator">><跨度class="token operator"><<跨度class="token maybe-class-name">序列<跨度class="token keyword module">从<跨度class="token operator">=<跨度class="token punctuation">{<跨度class="token number">0<跨度class="token punctuation">}durationInFrames<跨度class="token operator">=<跨度class="token punctuation">{<跨度class="token number">∞<跨度class="token punctuation">}<跨度class="token operator">><跨度class="token operator"><<跨度class="token maybe-class-name">StarWars版面<跨度class="token operator">=<跨度class="token punctuation">{版面<跨度class="token punctuation">}<跨度class="token operator">/<跨度class="token operator">><跨度class="token operator"><<跨度class="token operator">/<跨度class="token maybe-class-name">序列<跨度class="token operator">><跨度class="token operator"><<跨度class="token operator">/div<跨度class="token operator">><跨度class="token punctuation">)<跨度class="token punctuation">}<跨度class="token keyword">常量<跨度class="token function-variable function">StarWarsVideo<跨度class="token operator">=<跨度class="token punctuation">(<跨度class="token punctuation">)<跨度class="token arrow operator">= ><跨度class="token punctuation">{<跨度class="token spread operator">...<跨度class="token punctuation">}<跨度class="token punctuation">;<跨度class="token function">registerRoot<跨度class="token punctuation">(<跨度class="token maybe-class-name">StarWarsVideo<跨度class="token punctuation">)<跨度class="token punctuation">;

序列组件,我们可以为视频叠加两个主要组件。的星星组件将渲染星空背景,而StarWars组件将呈现滚动的黄色文本。星星背景使用标准的CSS动画和转换来显示星星。的StarWars组件是我们开始回到基于动态动画的地方。我们可以用春天帮助函数来控制顶部位置,旋转和翻译CSS转换属性,以动画文本的滚动基于视频中的当前时间。

将以下内容添加到src / starWars.js

进口<跨度class="token imports">反应<跨度class="token keyword module">从<跨度class="token string">“反应”<跨度class="token punctuation">;<跨度class="token keyword module">进口<跨度class="token string">”。/ starWars.css '<跨度class="token punctuation">;<跨度class="token keyword module">进口<跨度class="token imports">春天<跨度class="token punctuation">,useCurrentFrame<跨度class="token punctuation">}<跨度class="token keyword module">从<跨度class="token string">“移动”<跨度class="token punctuation">;<跨度class="token keyword">常量<跨度class="token function-variable function">StarWars<跨度class="token operator">=<跨度class="token punctuation">(<跨度class="token parameter">版面<跨度class="token punctuation">}<跨度class="token punctuation">)<跨度class="token arrow operator">= ><跨度class="token punctuation">{<跨度class="token keyword">常量框架<跨度class="token operator">=<跨度class="token function">useCurrentFrame<跨度class="token punctuation">(<跨度class="token punctuation">)<跨度class="token keyword">常量帧/秒<跨度class="token operator">=<跨度class="token number">6000<跨度class="token punctuation">;<跨度class="token keyword">常量前<跨度class="token operator">=<跨度class="token function">春天<跨度class="token punctuation">(<跨度class="token punctuation">{框架<跨度class="token punctuation">,<跨度class="token keyword module">从<跨度class="token operator">:<跨度class="token number">0<跨度class="token punctuation">,来<跨度class="token operator">:<跨度class="token operator">-<跨度class="token number">6000<跨度class="token punctuation">,帧/秒<跨度class="token punctuation">,<跨度class="token punctuation">}<跨度class="token punctuation">)<跨度class="token keyword">常量旋转<跨度class="token operator">=<跨度class="token function">春天<跨度class="token punctuation">(<跨度class="token punctuation">{框架<跨度class="token punctuation">,<跨度class="token keyword module">从<跨度class="token operator">:<跨度class="token number">20.<跨度class="token punctuation">,来<跨度class="token operator">:<跨度class="token number">25<跨度class="token punctuation">,帧/秒<跨度class="token punctuation">,<跨度class="token punctuation">}<跨度class="token punctuation">)<跨度class="token keyword">常量translateZ<跨度class="token operator">=<跨度class="token function">春天<跨度class="token punctuation">(<跨度class="token punctuation">{框架<跨度class="token punctuation">,<跨度class="token keyword module">从<跨度class="token operator">:<跨度class="token number">0<跨度class="token punctuation">,来<跨度class="token operator">:<跨度class="token operator">-<跨度class="token number">2500<跨度class="token punctuation">,帧/秒<跨度class="token punctuation">,<跨度class="token punctuation">}<跨度class="token punctuation">)<跨度class="token keyword control-flow">返回<跨度class="token punctuation">(<跨度class="token operator"><<跨度class="token operator">><跨度class="token operator"><div类名<跨度class="token operator">=<跨度class="token string">“消失”<跨度class="token operator">/<跨度class="token operator">><跨度class="token operator"><部分名称<跨度class="token operator">=<跨度class="token string">“星战”<跨度class="token operator">><跨度class="token operator"><div类名<跨度class="token operator">=<跨度class="token string">“爬”风格<跨度class="token operator">=<跨度class="token punctuation">{<跨度class="token punctuation">{前<跨度class="token operator">:<跨度class="token template-string"><跨度class="token interpolation">$ {前<跨度class="token interpolation-punctuation punctuation">}<跨度class="token string">px<跨度class="token template-punctuation string">`<跨度class="token punctuation">,变换<跨度class="token operator">:<跨度class="token template-string"><跨度class="token string">rotateX (<跨度class="token interpolation">$ {旋转<跨度class="token interpolation-punctuation punctuation">}<跨度class="token string">度)translateZ (<跨度class="token interpolation">$ {translateZ<跨度class="token interpolation-punctuation punctuation">}<跨度class="token string">px)<跨度class="token template-punctuation string">`<跨度class="token punctuation">}<跨度class="token punctuation">}<跨度class="token operator">><跨度class="token operator"><div类名<跨度class="token operator">=<跨度class="token string">“标题”<跨度class="token operator">><跨度class="token operator"><p<跨度class="token operator">><跨度class="token maybe-class-name">集<跨度class="token constant">4<跨度class="token operator"><<跨度class="token operator">/p<跨度class="token operator">><跨度class="token operator"><h1<跨度class="token operator">><跨度class="token constant">一个<跨度class="token maybe-class-name">新<跨度class="token maybe-class-name">希望<跨度class="token operator"><<跨度class="token operator">/h1<跨度class="token operator">><跨度class="token operator"><<跨度class="token operator">/div<跨度class="token operator">><跨度class="token punctuation">{版面<跨度class="token punctuation">.<跨度class="token method function property-access">地图<跨度class="token punctuation">(<跨度class="token punctuation">(<跨度class="token parameter">块<跨度class="token punctuation">,指数<跨度class="token punctuation">)<跨度class="token arrow operator">= ><跨度class="token punctuation">{<跨度class="token keyword control-flow">返回<跨度class="token punctuation">(<跨度class="token operator"><p键<跨度class="token operator">=<跨度class="token punctuation">{指数<跨度class="token punctuation">}<跨度class="token operator">><跨度class="token punctuation">{块<跨度class="token punctuation">}<跨度class="token operator"><<跨度class="token operator">/p<跨度class="token operator">><跨度class="token punctuation">)<跨度class="token punctuation">}<跨度class="token punctuation">)<跨度class="token punctuation">}<跨度class="token operator"><<跨度class="token operator">/div<跨度class="token operator">><跨度class="token operator"><<跨度class="token operator">/部分<跨度class="token operator">><跨度class="token operator"><<跨度class="token operator">/<跨度class="token operator">><跨度class="token punctuation">)<跨度class="token punctuation">}<跨度class="token keyword module">出口<跨度class="token keyword module">默认的<跨度class="token maybe-class-name">StarWars<跨度class="token punctuation">;

注意,我们正在渲染版面Prop,也就是每次生成视频时的随机文本。

现在剩下的就是创造星星组件。将以下内容添加到src / starsBackground.js

进口<跨度class="token imports">反应<跨度class="token keyword module">从<跨度class="token string">“反应”<跨度class="token punctuation">;<跨度class="token keyword module">进口<跨度class="token string">”。/ starsBackground.css '<跨度class="token punctuation">;<跨度class="token keyword">常量<跨度class="token function-variable function">星星<跨度class="token operator">=<跨度class="token punctuation">(<跨度class="token punctuation">)<跨度class="token arrow operator">= ><跨度class="token punctuation">{<跨度class="token keyword control-flow">返回<跨度class="token punctuation">(<跨度class="token operator"><<跨度class="token operator">><跨度class="token operator"><div id<跨度class="token operator">=<跨度class="token string">“星星”<跨度class="token operator">/<跨度class="token operator">><跨度class="token operator"><div id<跨度class="token operator">=<跨度class="token string">“stars2”<跨度class="token operator">/<跨度class="token operator">><跨度class="token operator"><div id<跨度class="token operator">=<跨度class="token string">“stars3”<跨度class="token operator">/<跨度class="token operator">><跨度class="token operator"><<跨度class="token operator">/<跨度class="token operator">><跨度class="token punctuation">)<跨度class="token punctuation">;<跨度class="token punctuation">}<跨度class="token keyword module">出口<跨度class="token keyword module">默认的<跨度class="token maybe-class-name">星星<跨度class="token punctuation">;

还可以将以下样式添加到src / starsWars.css

.fade<跨度class="token punctuation">{<跨度class="token property">位置<跨度class="token punctuation">:相对<跨度class="token punctuation">;<跨度class="token property">宽度<跨度class="token punctuation">:<跨度class="token number">One hundred.<跨度class="token unit">%<跨度class="token punctuation">;<跨度class="token property">最小高度<跨度class="token punctuation">:<跨度class="token number">60<跨度class="token unit">vh<跨度class="token punctuation">;<跨度class="token property">前<跨度class="token punctuation">:<跨度class="token number">-25年<跨度class="token unit">px<跨度class="token punctuation">;<跨度class="token property">z - index<跨度class="token punctuation">:<跨度class="token number">1<跨度class="token punctuation">;<跨度class="token punctuation">}<跨度class="token selector">.star-wars<跨度class="token punctuation">{<跨度class="token property">显示<跨度class="token punctuation">:flex<跨度class="token punctuation">;<跨度class="token property">justify-content<跨度class="token punctuation">:中心<跨度class="token punctuation">;<跨度class="token property">位置<跨度class="token punctuation">:相对<跨度class="token punctuation">;<跨度class="token property">高度<跨度class="token punctuation">:<跨度class="token number">800<跨度class="token unit">px<跨度class="token punctuation">;<跨度class="token property">颜色<跨度class="token punctuation">:<跨度class="token hexcode color"># feda4a<跨度class="token punctuation">;<跨度class="token property">字体类型<跨度class="token punctuation">:<跨度class="token string">《道路哥特一号》<跨度class="token punctuation">,无衬线<跨度class="token punctuation">;<跨度class="token property">字体大小<跨度class="token punctuation">:<跨度class="token number">500<跨度class="token unit">%<跨度class="token punctuation">;<跨度class="token property">粗细<跨度class="token punctuation">:<跨度class="token number">600<跨度class="token punctuation">;<跨度class="token property">字母间距<跨度class="token punctuation">:<跨度class="token number">6<跨度class="token unit">px<跨度class="token punctuation">;<跨度class="token property">行高<跨度class="token punctuation">:<跨度class="token number">150<跨度class="token unit">%<跨度class="token punctuation">;<跨度class="token property">的角度来看<跨度class="token punctuation">:<跨度class="token number">400<跨度class="token unit">px<跨度class="token punctuation">;<跨度class="token property">text-align<跨度class="token punctuation">:证明<跨度class="token punctuation">;<跨度class="token punctuation">}<跨度class="token selector">.crawl<跨度class="token punctuation">{<跨度class="token property">位置<跨度class="token punctuation">:相对<跨度class="token punctuation">;<跨度class="token property">前<跨度class="token punctuation">:<跨度class="token number">9999<跨度class="token unit">px<跨度class="token punctuation">;<跨度class="token property">transform-origin<跨度class="token punctuation">:<跨度class="token number">50<跨度class="token unit">%<跨度class="token number">One hundred.<跨度class="token unit">%<跨度class="token punctuation">;<跨度class="token punctuation">}<跨度class="token selector">.crawl<跨度class="token combinator">><跨度class="token class">.title<跨度class="token punctuation">{<跨度class="token property">字体大小<跨度class="token punctuation">:<跨度class="token number">90<跨度class="token unit">%<跨度class="token punctuation">;<跨度class="token property">text-align<跨度class="token punctuation">:中心<跨度class="token punctuation">;<跨度class="token punctuation">}<跨度class="token selector">.crawl<跨度class="token combinator">><跨度class="token class">.titleh1<跨度class="token punctuation">{<跨度class="token property">保证金<跨度class="token punctuation">:<跨度class="token number">0<跨度class="token number">0<跨度class="token number">One hundred.<跨度class="token unit">px<跨度class="token punctuation">;<跨度class="token property">首字母<跨度class="token punctuation">:大写字母<跨度class="token punctuation">;<跨度class="token punctuation">}

src / starsBackground.css太大了,不能在这里列出。请把里面的东西从GitHub回购并将其添加到您自己的项目中。

这将产生一个功能齐全的星球大战介绍视频,只使用代码创建,不需要视频编辑软件。

运行StarWars示例的最后一步是将以下脚本添加到package.json文件:

“开始:starwars”<跨度class="token operator">:<跨度class="token string">"remotion preview src/starWarsIndex.js"<跨度class="token punctuation">,

现在我们有了——一个星战的介绍,完全用React编码。

如果你想插入实际的星战文本,从在这里并更改useEffect方法调用src / starWarsIndex.js

useEffect(() => {<跨度class="token unchanged">setTextBlocks ([<跨度class="token deleted-sign deleted">-<跨度class="token line">lorem.generateSentences (5),<跨度class="token prefix deleted">-<跨度class="token line">lorem.generateSentences (5),<跨度class="token prefix deleted">-<跨度class="token line">lorem.generateSentences (5),<跨度class="token inserted-sign inserted">+<跨度class="token line">“这是一个内战时期。叛军飞船……”<跨度class="token prefix inserted">+<跨度class="token line">“被帝国邪恶的特工追捕……”<跨度class="token unchanged">])},[])

太棒了!

结论

我们已经举了两个例子来展示Remotion的力量,每个例子的复杂度都不同。然而,这只是Remotion功能的表面。下面是我们没有提到的Remotion提供的其他一些特性。

别忘了,所有的代码都可以在GitHub

数据抓取

要向视频添加响应式元素,可以在构建时获取数据以帮助填充内容。Remotion提供钩子来处理数据的获取,例如continueRenderdelayRender还可以在某些情况下使用,以暂停视频内容的呈现,直到获取数据为止。这些功能可用于根据输入数据库的数据生成视频。或者他们可以从服务器中提取数据——例如,为博客文章创建一个介绍视频,并从服务器中提取博客的标题和英雄图像。必威滚

参数化的呈现

从我们前面使用的例子中,我们可以控制传递到视频元素中的道具流。这使得视频能够快速响应。但是,这每次都需要修改代码。使用参数化呈现,您可以将数据作为构建命令的一部分传递进来。这意味着,作为CI/CD流程的一部分,您可以根据传入的数据生成视频——例如,自动生成带有传入的人员姓名和头衔作为道具的入职视频。

资产进口

你不需要只使用CSS创建元素。您还可以将其他资产,如图像、现有视频和音频文件导入到项目中。

还有更多的附加功能,并且在Remotion中定期发布新功能。Remotion是一个完全开发的项目,在基于javascript的视频领域迈出了一大步。这是一个非常强大的工具,还有很多可能性有待发现。

如果你使用Remotion制作了一些很酷的东西,请告诉我推特

Baidu