”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 效果:Modulo操作员(%)

效果:Modulo操作员(%)

发布于2025-02-25
浏览:571

深入浅出After Effects表达式中的取模运算符(%)

取模运算符(%),也称为余数运算符,是表达式构建中一个非常有用的工具,但初学者可能不太容易理解。本文将解释其功能和用途。

% 用于计算一个等式的余数。例如:

10 % 3

此表达式返回 1,因为 10 除以 3 商为 3,余数为 1。

在处理时间变量时,这对于创建循环非常有用。

循环表达式

大多数刚接触 After Effects 表达式的设计师都熟悉 loopOut() 表达式。它允许我们使用 "cycle"(从开始循环到结束)、"pingpong"(从开始到结束再反向回到开始)、"offset"(重复关键帧但每次偏移值以构建动画)或 "continue"(使用最后一个关键帧的速度来继续运动)来循环关键帧属性。这非常全面,涵盖了关键帧动画所需的一切。

但是,如果要循环一个表达式,loopOut 就不是一个可行的解决方案。可能有很多原因不想使用关键帧,但主要原因是如果一个值需要动态更新,并且不断更新。更新附加到滑块的表达式比更新一组关键帧要容易得多。

如果运动是连续的,那么 Linear 或 Ease 就足够了。但对于需要循环的复杂动画,我们可以使用时间对取模运算符来实现该循环。

要了解其工作原理,请将以下表达式复制并粘贴到文本图层的“源文本”属性中:

Math.floor(time % 5)

您将看到图层每秒计数从 0 到 4,每隔 5 秒循环回 0。这是因为随着时间的推移,表达式的余数会每秒改变:

随时间变化的余数
1 % 5 = 1
2 % 5 = 2
3 % 5 = 3
4 % 5 = 4
5 % 5 = 0
Math.floor 函数将参数舍入为整数。

After Effects: The Modulo Operator (%)

由此,很容易看出如何在需要在特定参数之间设置动画数字时使用它。

示例:数字时钟

让我们使用 % 来制作一个数字时钟。

秒数需要在 0 到 60 之间计数,而分钟需要在每 60 个间隔递增。让我们再次将此粘贴到文本图层的“源文本”属性中:

sec = Math.floor(time % 60);
minute = Math.floor(time / 60);

if (sec 

分解表达式,我们的 sec 变量将从 0 到 60 计数,而 minute 变量将在每 60 的倍数时递增(同样,我们使用 Math.floor 来舍入数字)。其后的 if 语句在 sec 变量小于 10 时在其前面添加一个 0,确保我们的秒变量始终具有两位数字(如果需要,也可以对分钟重复此操作)。然后,只需使用时间分隔符将其组合在一起即可。

After Effects: The Modulo Operator (%)

如果您需要计数器独立于时间工作,可以通过将时间替换为滑块并设置其值来实现相同的效果。

您还可以使用取模运算符和 After Effects 文本表达式选择器使时间分隔符闪烁。

转到文本图层,并向文本图层添加不透明度动画选项(如果您不确定如何操作,可以查看本文中关于此的所有内容)。然后添加表达式选择器,并删除范围选择器。

After Effects: The Modulo Operator (%)

将动画器中的不透明度设置为 0,然后将此表达式添加到“数量”属性:

//数字时钟分隔符闪烁 //添加到表达式选择器

minute = Math.floor(time / 60);

minute = 10 && textIndex == 3 ? Math.floor(time2 % 1.5) 100 : 0;

我编写了一个条件语句,基于分钟变量中的位数不固定。首先,我从源文本属性复制分钟变量。然后,我用它来计算时间分隔符的 textIndex 值。当分钟显示中只有一位数字时,它将等于 2。当分钟显示超过 10 时,它将为 3。条件语句也可以写成 if 语句,如下所示,以进一步解释它在做什么:

if (minute = 10 && textIndex == 3) Math.floor(time2 % 1.5) 100 else 0

如果分钟小于 10 且 textIndex 等于 2,则 Math.floor(time2 % 1.5) 100 会影响文本图层中的第二个字符。这将使字母闪烁(开/关比例为 2:1),这要归功于取模运算符。Math.floor 函数舍入数字,而整个表达式最后乘以 100 以在 0 和 100 之间切换,这是表达式选择器的范围。

但是,如果分钟等于或大于 10 且 textIndex 等于 3,则该效果将应用于文本图层中的第三个字符。这解释了分钟显示中的额外数字。如果您的分钟显示需要超过 99,则需要添加另一个参数来影响时间分隔符在第四个位置时的显示。

但是,如果您的分钟显示设置为恒定的位数,则该语句将变得简单得多:

dividerIndex = 3; textIndex == dividerIndex ? Math.floor(time2 % 1.5) 100 : 0

After Effects: The Modulo Operator (%)

就这样,你得到了一个数字时钟!

在显示取模运算符如何帮助创建循环之后,我们现在可以考虑如何将其应用于其他属性。

示例:模拟时钟

现在让我们制作一个模拟时钟。当指针滴答作响时,它通常不是一个连续的运动,而是一个突然停止和启动的运动。这就是取模运算符可以帮助解决的循环类型。

让我们来看一下可以粘贴到时钟指针图层旋转属性中的以下表达式:

//秒针旋转 frames = thisComp.frameDuration;

loopTime = 1; dur = frames * 6; strength = 6;

counter = Math.floor(time/loopTime); t = time % loopTime;

ease(t, 0, dur, strength counter, strength (counter 1))

首先,我们设置一些变量。frames 是合成中一帧的持续时间,使其能够跨多个帧速率工作。

将 loopTime 设置为您想要循环的时间。我希望循环持续一秒钟,所以我将其设置为 1。dur 是循环内动画的持续时间,所以我将其设置为 frames * 6,使其持续 6 帧。strength 是动画值的改变,因为我正在设置时钟指针动画,所以我将其设置为 6,因此时钟指针将在 60 次滴答声中完成一次旋转。

接下来,我创建一个 counter 变量,它将帮助偏移我的值。我使用 Math.floor(time/loopTime) 创建它,使用 Math.floor 舍入数字并将计数器的速度设置为与循环匹配。最后,t 是我们可以用来为表达式驱动的动画计时的一个变量。这是 time % loopTime,因此当时间达到 loopTime 中存储的数字时,时间就会循环。

之后,我们可以制作动画。在此示例中,我使用 ease 表达式。通过将第一个参数设置为 t,我们将旋转值重新映射到我们的循环时间变量。接下来的两个参数是 0 和 dur,即动画的起点和终点。最后两个参数是 strength counter 和 strength (counter 1),即旋转属性的值。通过将 strength 乘以 counter,我们可以偏移每个循环的值,在 strength * (counter 1) 结束,准备下一个循环。

After Effects: The Modulo Operator (%)

在这种情况下,通过表达式而不是关键帧来驱动运动的优点是,如果您需要为不断变化的时间构建时钟模板。表达式的静态值可以连接到滑块,从而更容易不断更新。

您可以使用更高级的表达式或构建自己的函数来制作更定制的动画:

//秒针旋转 frames = thisComp.frameDuration;

loopTime = 1; dur = frames * 6; change = 6;

counter = Math.floor(time/loopTime); t = time % loopTime;

function easeInOutBack (t, b, c, d, s) { if (s == undefined) s = 1.70158; if ((t/=d/2) (tt(((s=(1.525)) 1)t - s)) b; return c/2((t-=2)t(((s=(1.525)) 1)t s) 2) b; }

easeInOutBack(t, 0, change, dur, 1.70158)

After Effects: The Modulo Operator (%)

最后,您可以创建一个变量来设置起始值,并使用 if 语句跳过分针(可能还有时针)动画的第一次迭代:

//分针旋转 frames = thisComp.frameDuration;

loopTime = 60; dur = frames * 6; strength = 6; startValue = 180;

counter = Math.floor(time/loopTime); t = time % loopTime;

function easeInOutBack (t, b, c, d, s) { if (s == undefined) s = 1.70158; if ((t/=d/2) (tt(((s=(1.525)) 1)t - s)) b; return c/2((t-=2)t(((s=(1.525)) 1)t s) 2) b; }

if (counter > 0) { easeInOutBack(t, startValue strength * counter, strength, dur, 1.70158) } else { startValue }

After Effects: The Modulo Operator (%)

从这里开始,只需将滑块连接到我们的 startValue 变量即可。这样,您就拥有了一个可以通过简单更改滑块中的值来更新的模拟时钟。

结论

取模运算符对于创建循环以辅助动态表达式非常有用,而其他方法不适合项目的需要。

尝试在您自己的项目中测试它!

有任何意见?有什么不清楚的地方?请在下方留言。

最新教程 更多>
  • 如何使用Python理解有效地创建字典?
    如何使用Python理解有效地创建字典?
    在python中,词典综合提供了一种生成新词典的简洁方法。尽管它们与列表综合相似,但存在一些显着差异。与问题所暗示的不同,您无法为钥匙创建字典理解。您必须明确指定键和值。 For example:d = {n: n**2 for n in range(5)}This creates a dicti...
    编程 发布于2025-04-06
  • 如何使用PHP从XML文件中有效地检索属性值?
    如何使用PHP从XML文件中有效地检索属性值?
    从php $xml = simplexml_load_file($file); foreach ($xml->Var[0]->attributes() as $attributeName => $attributeValue) { echo $attributeName,...
    编程 发布于2025-04-06
  • 如何使用FormData()处理多个文件上传?
    如何使用FormData()处理多个文件上传?
    )处理多个文件输入时,通常需要处理多个文件上传时,通常是必要的。 The fd.append("fileToUpload[]", files[x]); method can be used for this purpose, allowing you to send multi...
    编程 发布于2025-04-06
  • 如何将来自三个MySQL表的数据组合到新表中?
    如何将来自三个MySQL表的数据组合到新表中?
    mysql:从三个表和列的新表创建新表 答案:为了实现这一目标,您可以利用一个3-way Join。 选择p。*,d.content作为年龄 来自人为p的人 加入d.person_id = p.id上的d的详细信息 加入T.Id = d.detail_id的分类法 其中t.taxonomy =...
    编程 发布于2025-04-06
  • 如何将PANDAS DataFrame列转换为DateTime格式并按日期过滤?
    如何将PANDAS DataFrame列转换为DateTime格式并按日期过滤?
    将pandas dataframe列转换为dateTime格式示例:使用column(mycol)包含以下格式的以下dataframe,以自定义格式:})指定的格式参数匹配给定的字符串格式。转换后,MyCol列现在将包含DateTime对象。 date date filtering > = p...
    编程 发布于2025-04-06
  • 如何在GO编译器中自定义编译优化?
    如何在GO编译器中自定义编译优化?
    在GO编译器中自定义编译优化 GO中的默认编译过程遵循特定的优化策略。 However, users may need to adjust these optimizations for specific requirements.Optimization Control in Go Compi...
    编程 发布于2025-04-06
  • 如何使用不同数量列的联合数据库表?
    如何使用不同数量列的联合数据库表?
    合并列数不同的表 当尝试合并列数不同的数据库表时,可能会遇到挑战。一种直接的方法是在列数较少的表中,为缺失的列追加空值。 例如,考虑两个表,表 A 和表 B,其中表 A 的列数多于表 B。为了合并这些表,同时处理表 B 中缺失的列,请按照以下步骤操作: 确定表 B 中缺失的列,并将它们添加到表的末...
    编程 发布于2025-04-06
  • 为什么PYTZ最初显示出意外的时区偏移?
    为什么PYTZ最初显示出意外的时区偏移?
    与pytz 最初从pytz获得特定的偏移。例如,亚洲/hong_kong最初显示一个七个小时37分钟的偏移: 差异源利用本地化将时区分配给日期,使用了适当的时区名称和偏移量。但是,直接使用DateTime构造器分配时区不允许进行正确的调整。 example pytz.timezone(...
    编程 发布于2025-04-06
  • 如何在Java中正确显示“ DD/MM/YYYY HH:MM:SS.SS”格式的当前日期和时间?
    如何在Java中正确显示“ DD/MM/YYYY HH:MM:SS.SS”格式的当前日期和时间?
    如何在“ dd/mm/yyyy hh:mm:mm:ss.ss”格式“ gormat 解决方案:的,请访问量很大,并应为procectiquiestate的,并在整个代码上正确格式不多: java.text.simpledateformat; 导入java.util.calendar; 导入java...
    编程 发布于2025-04-06
  • 我可以将加密从McRypt迁移到OpenSSL,并使用OpenSSL迁移MCRYPT加密数据?
    我可以将加密从McRypt迁移到OpenSSL,并使用OpenSSL迁移MCRYPT加密数据?
    将我的加密库从mcrypt升级到openssl 问题:是否可以将我的加密库从McRypt升级到OpenSSL?如果是这样,如何?答案:是的,可以将您的Encryption库从McRypt升级到OpenSSL。可以使用openssl。附加说明: [openssl_decrypt()函数要求iv参...
    编程 发布于2025-04-06
  • 如何在JavaScript对象中动态设置键?
    如何在JavaScript对象中动态设置键?
    在尝试为JavaScript对象创建动态键时,如何使用此Syntax jsObj['key' i] = 'example' 1;不工作。正确的方法采用方括号: jsobj ['key''i] ='example'1; 在JavaScript中,数组是一...
    编程 发布于2025-04-06
  • 如何使用PHP将斑点(图像)正确插入MySQL?
    如何使用PHP将斑点(图像)正确插入MySQL?
    essue VALUES('$this->image_id','file_get_contents($tmp_image)')";This code builds a string in PHP, but the function call ...
    编程 发布于2025-04-06
  • 如何在php中使用卷发发送原始帖子请求?
    如何在php中使用卷发发送原始帖子请求?
    如何使用php 创建请求来发送原始帖子请求,开始使用curl_init()开始初始化curl session。然后,配置以下选项: curlopt_url:请求 [要发送的原始数据指定内容类型,为原始的帖子请求指定身体的内容类型很重要。在这种情况下,它是文本/平原。要执行此操作,请使用包含以下标头...
    编程 发布于2025-04-06
  • 如何实时捕获和流媒体以进行聊天机器人命令执行?
    如何实时捕获和流媒体以进行聊天机器人命令执行?
    在开发能够执行命令的chatbots的领域中,实时从命令执行实时捕获Stdout,一个常见的需求是能够检索和显示标准输出(stdout)在cath cath cant cant cant cant cant cant cant cant interfaces in Chate cant inter...
    编程 发布于2025-04-06
  • 如何使用替换指令在GO MOD中解析模块路径差异?
    如何使用替换指令在GO MOD中解析模块路径差异?
    在使用GO MOD时,在GO MOD 中克服模块路径差异时,可能会遇到冲突,其中可能会遇到一个冲突,其中3派对软件包将另一个带有导入套件的path package the Imptioned package the Imptioned package the Imported tocted pac...
    编程 发布于2025-04-06

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3