深入浅出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 |
由此,很容易看出如何在需要在特定参数之间设置动画数字时使用它。
示例:数字时钟
让我们使用 % 来制作一个数字时钟。
秒数需要在 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 文本表达式选择器使时间分隔符闪烁。
转到文本图层,并向文本图层添加不透明度动画选项(如果您不确定如何操作,可以查看本文中关于此的所有内容)。然后添加表达式选择器,并删除范围选择器。
将动画器中的不透明度设置为 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
就这样,你得到了一个数字时钟!
在显示取模运算符如何帮助创建循环之后,我们现在可以考虑如何将其应用于其他属性。
示例:模拟时钟
现在让我们制作一个模拟时钟。当指针滴答作响时,它通常不是一个连续的运动,而是一个突然停止和启动的运动。这就是取模运算符可以帮助解决的循环类型。
让我们来看一下可以粘贴到时钟指针图层旋转属性中的以下表达式:
//秒针旋转 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) 结束,准备下一个循环。
在这种情况下,通过表达式而不是关键帧来驱动运动的优点是,如果您需要为不断变化的时间构建时钟模板。表达式的静态值可以连接到滑块,从而更容易不断更新。
您可以使用更高级的表达式或构建自己的函数来制作更定制的动画:
//秒针旋转 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)
最后,您可以创建一个变量来设置起始值,并使用 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 }
从这里开始,只需将滑块连接到我们的 startValue 变量即可。这样,您就拥有了一个可以通过简单更改滑块中的值来更新的模拟时钟。
结论
取模运算符对于创建循环以辅助动态表达式非常有用,而其他方法不适合项目的需要。
尝试在您自己的项目中测试它!
有任何意见?有什么不清楚的地方?请在下方留言。
अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।
Copyright© 2022 湘ICP备2022001581号-3