我们已经看到了如何利用时间值,我们可以轻松快速的生成动画,当我们有一大堆动画要做的时候,这是一个节省时间的方法。另一种节省时间的方法是使用循环,循环不仅超级有用,而且可以让你创建无缝的动画。
首先,正如我们在 "时间 "一章中所看到的,我们可以使用Math.cos()或Math.sin()方法进行循环,因为Cos和Sin会随着时间的推移在-1和1之间产生一个重复的值序列。例如,如果我在圆形形状层的位置属性中应用这个表达式。
在x轴上,我们写道,我们希望圆形形状层的位置是合成宽度的一半,y轴的位置是合成高度的一半;然后我们在y的位置上加上Cos方法。在Math.cos()方法中,我们用时间作为参数,然后乘以10,这样频率就快了10倍。我们知道这个方法会产生一个介于-1和1之间的数值序列,所以我们将其乘以100,产生介于-100和100之间的数值,这样圆圈形状图层就会随着时间的推移,在-100像素和100像素之间来回走动。这就产生了一个完美的、无缝的循环,从一个点到另一个点来回走动。
我们有另一种创建循环的数学方法:模数运算符%。这个运算符是在两个正整数之间产生除法余数的运算。
正如你所看到的,这将循环分母,在我们的例子中,5是除数,所以每次分子是5的倍数时,它将返回到0,这在我们的表达式中可以非常有用。让我们在新的合成中添加一个正方形形状层,以及一个文本层,我们将在其中显示正方形形状层的旋转值,然后在源文本属性中写下这个表达式。
现在,在正方形形状层的旋转属性中,让我们添加这个表达式。
正如我们所看到的,这将导致正方形的旋转达到180时循环,将其返回到0。 如果你将时间与模数运算相结合,你可以创建一个循环,它会随着时间的推移而重复。幸运的是,我们有一个更简单的方法来产生循环,这要归功于循环方法。
首先,让我们在一个5秒的合成上创建一个圆形形状图层,并快速制作一个动画,使圆形形状图层从左到右移动。让我们在位置属性[250,540]上添加第一个关键帧,20帧后在[800,540]上添加第二个关键帧。
现在打开表达式编辑器中圆形状层的位置属性,从表达式语言菜单中,找到loopOut()方法。
这是一个很方便的菜单,可以帮助你找到建立表达式的术语。在这个菜单中,在Property属性文件夹下,让我们选择loopOut()方法:正如你所看到的,菜单助手在表达式编辑器中写下了带有完整详细参数的方法。如果你现在播放动画,你会看到在最后一个关键帧之后,它从动画中循环出来并返回到第一个关键帧。
当我们删除方法里面的参数时。
我们可以看到,动画并没有改变--同样的循环发生了。正如我前面提到的,如果在方法中写有等号的参数保持不变,或者没有插入任何值,这些参数将是默认的。所以基本上,下面的表达式将以同样的方式工作。
请注意,如果你想修改第二个参数,你也需要输入第一个参数,即使你想使用默认参数。
loopOut()方法允许你在一个属性中循环关键帧序列,在最后一个关键帧之后。
在这个方法中,你可以输入的第一个参数是一个字符串值。有4种你可以在这个方法中使用的字符串值。“cycle”, “pingpong”, “continue” , “offset”.("循环","乒乓","继续 "和 "偏移"。)
假设第一个关键帧是A,第二个关键帧是B。
loopOut(“continue”)
在到达关键帧B后,动画将以在关键帧B中的相同速度和方向继续运动。
loopOut(“cycle”)
到达关键帧B后,将从A处重新开始。
loopOut(“offset”)
当它到达关键帧B后,从B开始循环,将从B开始播放A到B;然后从前面的偏移开始播放下面的循环。
loopOut(“pingpong")
到了关键帧B之后,就会反向播放,从B到A。
当属性只有两个关键帧时,这很容易理解;但是,有些时候,属性有两个以上的关键帧,这时方法中的第二个参数numKeyframes就很有用。你输入的数值是你想在属性中最后一个关键帧之后循环的关键帧数。如果是 0,则将循环
属性中的所有关键帧;如果是1,它将只循环最后一个关键帧之前的一个关键帧;如果是2,它将循环最后一个关键帧之前的2个关键帧,以此类推。对于loopOut(),记住它是从最后一个关键帧开始循环的。
如果你想调用一个属性中的关键帧数,你可以使用numKeys。在上面的例子中,如果我们在位置属性中写下 thisProperty.numKeys,它应该会产生数值 4,因为有 4 个关键帧。
你已经准备好了
还有其他方法可用于在有关键帧的属性上创建循环--loopOutDuration()的工作方式是一样的,只是在该方法中输入的第二个参数不是最后一个关键帧后要循环的关键帧数,而是从最后一个关键帧开始的持续时间,单位为秒。loopIn()和loopInDuration()方法的应用是一样的,但都是从属性的第一个关键帧开始,在第一个关键帧之前循环动画,然后在属性的最后一个关键帧之后停止循环。
所有这些循环方法都为我们提供了快速、流畅的方法,只需要几个表达式就可以创建动画。这些都是小事,但如果你能在每天的AE项目中应用它们,你会发现它们能帮助你获得节奏感。更重要的是,你会有更多的时间对你的项目进行创造性的思考。
在本书的学习过程中,我们学习了如何使用一些内置的术语来阅读和编写表达式。表达式是一个不断扩展的宇宙,AE每一次新的更新都会增加新的内置术语,可以和表达式一起使用。例如,我们可以提到新的路径对象,在路径中输入表达式,用表达式控制路径或蒙版的点,以及其他许多功能。然而,现在你已经有了自己理解这些的工具,并且可以看懂表达式的工作原理,你可以适应任何情况,开发自己的表达方式,并理解其他人的工作了。
在本章的最后,我想回到我们之前看到的loopOut()方法。你一定还记得,方法就是函数,正如我们在洞察力一章中看到的那样。我想向你展示一下,如果我们必须编写自己的loopOut()函数,它可能会是什么样子。这个函数,正如你在接下来的几页中看到的那样,将以与loopOut()方法完全相同的方式工作。试着把它丢到任何属性上,你会发现它的行为方式是一样的。显然,loopOut()的使用速度要快得多;我只想向你展示这一点,因为,多亏了你在本书中学到的所有知识,你现在已经能够构建这个表达式,能够读懂它,并且看到,最初看起来可能是一大堆代码,其实只是由几个术语组成的,其中只有传输值的逻辑很重要。我在本书中的任务是让事情变得轻松一些--现在你可以毫不畏惧地面对它,并静心思考它如何帮助你的AE工作流程。
如果我们不得不把loopOut(type = "cycle", numKeyframes = 0)方法作为一个函数来构建,用完全相同的参数来工作呢?我已经把我们在本书中遇到的所有术语都显示得比较暗--你不需要知道其他的内容就能理解这些,你会看到:
本章完结。