百度知道_浮生未歇吧 关注:230贴子:6,486
  • 9回复贴,共1

【视屏教程】表达式的应用

只看楼主收藏回复

假如你对编程有一定的了解
基本 这个就没有难度了
简单来说 表达式的诞生 就是为了更好控制和修改图片的移动、翻转等等等等
复杂来说 就看下面的




IP属地:江苏1楼2011-12-29 10:20回复
    首先 重新看下这个视频的制作方法 里面就曾用过表达式

    具体看 【视频父子跟随parent教程】第一讲:超有趣人物头像说话 教程
    在视频教程 加精关键词那里
    第8楼


    IP属地:江苏2楼2011-12-29 10:23
    回复
      1.表达式简介
      在详细讲解表达式之前,我们先总体了解一下AE中元素之间的关系,据我所知在AE中主要有五种方法建立元素之间的关系:
      关键帧:即使元素间没有必然的连接关系,你也可以通过设置关键帧来为它们建立联系。这是最普通的一种连接关系,这种方法也是最灵活的,但是很不利于修改和调试。
      合并嵌套: 你可以将几个图层一起放置于一个新合成中,这很像其他应用程序中的成组操作,一种将多层素材元素作为单独素材处理设置的方法。
      父子连接: 不用嵌套为图层建立层级关系的方法,在父子连接关系中任何应用于父层级的变化都会立即影响子层级,而针对子层级的设置不会影响到父层级。
      动力学脚本: 像表达式一样,动力学脚本是AE中内置的简单功能,动力学脚本可以为当前图层创建基于另一个图层或属性的关键帧。例如,你可以使用动力学脚本令一个图层模拟另一个图层的位置变化。美中不足的是,使用动力学脚本建立的元素间关系只是暂时的,仅当脚本执行时才会起作用,在后面的设置调整中,针对一个图层的改变不会反映在另一个图连接层上,除非重新应用动力学脚本。
      表达式: 表达式很类似于动力学脚本,不同的是表达式会保持始终使能,只要应用表达式之后,任何关键帧都会永久保持与之的连接关系。
      在这几种连接关系中,表达式的功能最强大,但是学习起来有一定的难度,需要一定的毅力。
      使用表达式的时机
      建立动态连接. 正如上面讨论的,使用表达式为图层建立动态连接是一种非常方便高效的方法。
      从父层级中仅仅复制一个参数. 有些时候,你只想从一个图层中复制一个参数,而不是一整套父子连接图层关系。 例如, 在下面的两个动画中, 上面的两个图层建立了父子联接, 在下面的动画中为黄色图层应用表达式使其只与绿色图层的位置属性建立连接关系。利用父子联接建立的图层关系中子层级会继承父层级的位置与旋转属性, 而应用表达式建立的图层关系,黄色图层只会继承绿色层级的位置属性,而其旋转属性由于未被联接到旋转属性,所以该参数不会改变。

      无关键帧动画. 通过使用表达式你不用设置任何关键帧就可以为参数设置动画。 例如, 在下面的这个动画中,图层的缩放属性就是利用表达式中数学正弦曲线来驱动的。

      为参数增加随机性. 你可以使用表达式为存在的关键帧增加随机性,这种方法非常巧妙,它保留了原始的关键帧设置。当然,AE中内置的摇摆器也可以完成增加随机性效果,但是这种方法会增加很多关键帧,使用表达式建立的随机性效果可以轻松的切换表达式的使能状态,不会影响原始关键帧。

      禁用表达式
      尽量避免使用表达式.
      通常情况下使用其他方法可以实现的效果就不要使用表达式,AE具有强大的工具和功能来实现各种各样的效果。例如,使用父子连接可以实现的效果就不需要再使用表达式。表达式功能的确很强大,但是它不是万能的,而且精心书写表达式后还要维护表达式。
      别以为受中拥有了一吧锤子后,世间万物都成了钉子, 表达式是一个功能强大的工具,单并不见得就是最好的、最便捷高效的工具。


      IP属地:江苏3楼2011-12-29 11:12
      回复

        3.拾取线
        使用拾取线可以方便的建立参数间的连接表达式:

        例如,为图层的不透明度添加表达式,然后拖动拾取线到图层旋转参数上就会为不透明度与旋转参数建立动态连接,现在再为旋转参数设置关键帧,会同步影响到不透明度属性:

        如果你将拾取线拖动到同一合成不同图层的属性参数上,那么AE就会创建一个稍微复杂一点的表达式,表明与哪一个图层的属性建立动连接:
        this_comp.layer("Solid 1").opacity
        这个表达式首先指明合成("this_comp"),然后指明该合成中的图层("solid1"),最后指明该图层被用于建立连接的属性(opacity)。AE会精确的设置建立连接的合成与图层,应该熟记AE的这种语法结构。
        顺便说一句,拾取线没有什么特别神奇的地方,可以说它仅仅起到一个打字机的作用,自动将连接的属性名称极其所属合成与图层添加到表达式文本区。你也可以亲自手写表达式,但是这种方式远远不及拾取线方便准确,特别是当需要编写较复杂的表达式时,拾取线的高效快捷更是体现的淋漓尽致。
        


        IP属地:江苏5楼2011-12-29 14:26
        回复

          4.向量、阵列、维数、索引
          有时候你会发现通过拾取线创建的表达式看上去好象在重复参数,例如,如果你将位置参数的拾取线拖动到旋转参数上,你就会得到如下表式:
          [rotation, rotation];
          因为位置属性有两个参数(X、Y坐标)而旋转属性只有一个参数,建立连接关系后,表达式自动将旋转参数应用两次分别位置属性的X、Y坐标参数。
          由两个或三个数值来描述属性的参数组叫做向量或阵列,AE中很多的属性参数是向量式的,包括位置、轴心点和缩放等属性;
          阵列对应的用单个数值来描述属性的参数叫做标量式参数。
          向量与阵列
          究竟向量和阵列之间有什么区别呢,你也许会注意到AE的帮助文件有时候互用这两个单词,简单的说向量是既有大小又有方向的数字阵列,其运算结果即要考虑到大小又要考虑到方向;阵列是一套独立元素的组合,阵列中可以包含任何元素,可以是物体阵列,词汇阵列或者是混合阵列:
          ralph=[10, this_layer, "bob"];
          也许没有人会知道上面的这种阵列会有什么用处,但是它确实是一个正确的阵列,当然在AE中我们大部分时间内遇到的是数字阵列(也叫向量),因为其他类型的阵列在AE中没有用。所以,在接下来的描述中,当谈论到通用的概念和操作应用时,我们使用阵列来描述;当涉及到特殊的数字阵列时我们用向量来描述。
          索引
          对于阵列来说,你可以使用阵列名加上包含数字的中括号从阵列中提取需要的单一元素,例如:
          position[0];
          这种表达方法叫做索引,注意在阵列中使用索引调用元素时,必须从0开始计数第一个元素,也就是说,阵列中的第一个元素必须以阵列名加上[0]来表示, 第二个元素必须以阵列名加上[1]来表示,依次类推。
          所以,上面的表达式就返回位置属性向量中的第一个参数——x坐标,那么position[1]就返回位置属性中的Y坐标,千万不要搞混淆了,在AE中虽然所的调整都是从1开始的,但是当使用索引时,必须从零开始计数
          建立阵列
          如果要建立阵列,可以将数值以逗号分隔开放入中括号中:
          my_vector=[10,20,30];
          该表达式的意思是将一个三维数组赋予变量my_vector,该数组中包含三个元素分别是10,20,30,.
          my_vector[1];
          该表达式计算得出的值是20(数组中的第二个元素)。
          维数
          阵列中的元素个数代表阵列的维数,例如上面的my_vector是一个三维数组,位置属性是一个二维数组或三维数组(转变为三维图层)。标量式的属性如旋转和不透明度属于一维参数(准确说单一数字或者是标量数值就是一维向量)。
          需要注意的是诸如位置属性这样的多维数组或者是自定义的数组变量,不需要将他们的名字写在方括号中,AE会将其识别为数组。当要索引阵列或者是描述阵列时,需要使用方括号。
          修改阵列中的一个元素
          可以用如下的方式来书写位置表达式:
          [position[0], position[1]];
          将位置阵列中的两个参数分别提出来后,再将他们放入同一个阵列中,看上去与仅仅书写positon的结果相同,优点是你可以使用这种结构来修改阵列中的一个元素而不影响另外元素,例如:
          top_of_layer=0;
          [anchor_point[0], top_of_layer];
          在这个表达式中,阵列中的第一个元素是轴心点的X坐标值,第二个元素是0,如果将该值赋予轴心点属性,那么轴心点的X值将受AE的控制调整,而轴心点的Y值将始终为0。
          当使用这种结构时要特别注意,如果将图层设置为3d图层,就需要重新书写表达式,将位置与轴心点Z轴考虑进去。
          例如,如果仍然使用上面轴心点的例子,但是这次将轴心点所在的图层设置为3D图层,AE会自动将丢失的Z轴坐标设置为0,这当然比出现程序错误要强的多,但是所得到的结果未必是我们需要的,因为表达式将忽略轴心点的Z轴坐标的变化。
          再看另外一个例子,假如你将一个图层的位置属性复制到另外一个图层上,并且将该参数的Y轴值减去100:
          


          IP属地:江苏6楼2011-12-29 14:27
          回复
            ralph=this_comp.layer(1)
            [ralph.position[0], ralph.position[1]-100];
            如果这时将图层设置为3D图层,你会发现对控制图层的Z轴所做的任何操作丝毫不会影响到受控图层的Z轴,因为表达式中没有表明Z轴的坐标值,AE会自动将其设置为0。
            阵列的重要性
            为什么用如此大量的篇幅来描述阵列呢,因为在你所书写的表达式中必须提供正确的参数维数,例如仅仅给位置属性提供一个参数就是错误的
            position=6;? // ?? 不正确
            这条语句就是错误的,因为位置属性至少需要两个参数:
            position=[320,240]; // 正确
            顺便提醒一句,你完全没有必要写成这种形式“position=”,因为在书写表达式时就已经将该值赋予了连接的属性参数。
            如果你所书写的表达式存在错误,书写完毕后AE会自动弹出一个错误对话框同时该表达式将被禁用。

            如果要避免这种错误,你需要核实正确的参数维数,, 可以通过AE自带的帮助文档或教程后面提供的参考表格来查阅表格.
            同样的如果在表达式中涉及到另外的参数,你也需要在帮助文档或者是下面的表格中查阅参数维数,你需要调整来自这些参数的值以匹配你所需要的输出维数。如果你引入了一个二维参数到一个一维数组中,你就需要调整维数以适应输出(如忽略二维数组中的一维元素)。
            下面的表格中列出了AE中大部分属性参数的维数以及这些参数值的范围:
            图层属性 维数 单位 理论范围 应用范围
            轴心点 2* [x, y, (z)] 像素 负整数~正整数 0~图层宽度,高度
            位置 2* [x, y, (z)] 像素 负整数~正整数 0~合成宽度,高度
            缩放 2*[宽度,高度,(深度)] 百分比 负整数~正整数 -100 ~+100
            旋转 1 角度 负整数~正整数 0~360(一个周期)
            不透明度 1 百分比 0–100 0–100
            朝向(3D) 3 [x, y, z] 角度 负整数~正整数 0~360(一个周期)
            音量 2 [左声道,右声道] 分贝 -192–24 -48–12
            环境光 1 百分比 0–100 0–100
            漫反射 1 百分比 0–100 0–100
            高光 1 百分比 0–100 0–100
            亮度 1 百分比 0-100 0-100
            * 表示当图层转换为3D时,该属性为3维.
            当使用拾取线时,AE会自动通过索引向量(一维——二维)或重复标量(二维——一维)的方式矫正维数的匹配。


            IP属地:江苏7楼2011-12-29 14:27
            回复

              参数值范围
              当使用表达式中的拾取线来建立参数之间的关系时,AE会自动纠正由于错误的维数匹配导致的错误,但是这种纠正之后的表达式并不意味着就是你所需要的,物理错误是避免了,但是逻辑错误仍然会影响你的创作。.
              在这里特别强调一下,有时候你需要调整当前参数值以匹配目标参数。例如,在前面的例子中我们使用图层的旋转属性来控制图层的不透明度属性,你会发现当旋转属性达到100度时,不透明度属性就达到了上限,但是我们想要的效果是当图层完成一个周期的旋转时其不透明度,我们就需要调整参数范围以达到我们的需要。
              缩放参数范围值的方法很简单,可以利用公式(当前连接参数/当前连接参数范围上限=目标连接参数/目标连接参数范围上限),还是使用上面的例子来说明,我们需要将旋转参数的范围(0~360)缩放到不透明度参数的范围(0~100),所以我们就需要为不透明度加上表达式:
              rotation / 360 * 100
              从而就达到了我们需要的效果,不透明度在0~360度范围内变化:

              使用这个简单的小技巧可以完成很多期望的效果。例如,使用一个轮胎的素材作为图层,我们就可以利用该图层的位置属性来驱动图层的旋转属性,我们只需缩放位置属性来为旋转属性建立正确的连接表达式,因为轮胎每旋转360度就会移动一个周长的距离,所以我们应该这样书写表达式:
                   rotation=distance/circumference*360:

              在这里distance代表图层的运动距离,circumference代表轮胎的周长,但是我们怎样将这个公式转化为AE能识别的表达式语句呢?与前面的旋转不透明度的例子比较这个方程式好象发生了本质的变化,但是事实不是这样的。
              开始我们提到了我们是要使用这个表达式,让图层的位置属性来控制图层的旋转属性——模拟真实的轮胎行进动画。但是位置属性真的能正确控制旋转属性么,或者说旋转属性能准确的控制位置属性么?答案当然是否定的,你可以试着使用拾取线让位置属性驱动旋转属性,为位置属性设置关键帧,再观察旋转属性,虽然有所变化但根本不是我们需要的效果。
              因为我们的轮胎只会在水平方向上滚动,位置属性中的X轴参数(还记得二维数组么),也就是position[0]来计算轮胎移动的距离;它将从合成窗口的最左(X轴方向的0点)边开始运动,随着向合成窗口的右侧移动,X值会慢慢增大。(AE的坐标原点位于合成窗口的左上角)
              前面我们提到过,轮胎行进的距离为一个周长的时候旋转的角度正好为360度,否则这个轮胎就会出现在地面上滑行的现象,所以我们使用上面提到的公式,轮胎的周长是当前连接参数范围上限,360度是目标连接参数范围上限,所以正确的方程式为:
              rotation=position[0]/circumference*360
              当然了轮胎不可能只行进一个周长的距离只完成一周旋转,换句话说周长与360度不是理论意义上的范围上限,但是不用担心,我们的表达式只是起到为范围之间的转换建立一个比例系数的作用,真正的范围要由计算得来。
              接下来我们需要定义轮胎的周长,圆的周长应该等于圆周率派乘以圆的直径(c=2*R*PI):

              我们可以使用图层的宽度作为轮胎的直径(理论上讲,轮胎的直径无限趋近于图层的宽度),而Javacript内置的PI值精确度非常的高,我们可以使用函数'Math.PI'来计算PI值,(当然,也可以直接粗略写成3.14作为PI值)这样周长的表达式为:
              


              IP属地:江苏8楼2011-12-29 15:07
              回复
                6. 插值方法:线性liner(),平滑ease()
                我们已经学习了怎样利用表达式来缩放参数值的范围,只需要简单的乘除运算就可以了---例如将旋转参数范围(0~360)缩放到不透明度参数范围(0~100),但是这不是唯一的方法,AE提供了一套内置的插值算法进行参数之间的转换:
                linear(t, t_min, t_max, value1, value2)
                ease(t, t_min, t_max, value1, value2)
                ease_in(...), ease_out(...)
                这些语句看起来很复杂,因为语句中包含很多参数:
                t 当前参数,例如旋转参数,不透明度参数或者是你所选择的其他变量,该参数必须是一维的,该参数为必选参数。
                t_min 当前参数范围的下限,该参数为可选参数,如果参数范围的下限或上限被忽略掉了,那么AE会将参数的范围定义在0~1之间。
                t_max 当前参数范围的上限,该参数为可选参数。
                value1 目标参数范围下限,当t≤t_min时,表达式返回该值,该值几可以是一维标量也可以是二维向量,与value1的维数相同,该参数为 必选参数。
                value2 目标参数范围上限,当t≥t_max时,表达式返回该值,该值几可以是一维标量也可以是二维向量,但是如果该值与value1 的维数 不同,AE会自动以value1 值为标准进行匹配,该参数为必选参数。
                通过下面的例子让我们来了解一下该语句的含义:
                linear(time, 0, 5, 0, 360);
                通过上面的学习,我们应该将这个语句理解为,时间的变化范围是0到5,目标参数的范围是0到360,整个变化过程是线性的。如果将该表达式应用到图层的旋转属性上,那么你会发现图层在前5秒内完成了一周的旋转。
                应用该表达式后,图层在第五秒停止旋转,这就是与我们前面介绍的直接手写公式time/5*360最大的区别,插值算法自动在当前参数与目标参数之间采样范围极值。
                另外一个区别就是你可以设置不同的插值算法:ease(),ease_in()和ease_out()。这些插值算法与同名的关键帧插值算法(通过关键帧助手菜单设置)的作用相同。利用这些插值算法可以为数值转换计算提供一个更自然的运算过程,从而得到更流畅的变化效果,仅仅使用前面介绍的手写公式是做不到这一点的。
                看看下面的动画,体会一下不同的插值算法(所有的图层使用相同的参数,只是插值算法不一样):

                点击这里下载:

                示例: 滚动栏
                现在让我们使用这种简单的方法来快速完成一个例子,我们将制作一个滚动栏的动画。首先我们需要建立两个图层,一个文本区域图层和一个滚动栏图层。我们要为文本图层的轴心点加入表达式,因为这样可以保证我们可以操纵图层的位置属性(当图层滚动时位置属性仍然不会改变)。
                记住一定要在一个方向上控制轴心点以得到正确的滚动效果,在这个例子中我们将对轴心点做垂直方向的运动以使文本区在合成窗口中上下滚动。为了使滚动的范围最大,也就是文本区域全部实现滚动,我们将轴心点的Y值范围设置为0到图层的高度,也就是我们的目标参数值为:
                value1=0
                value2=height
                至于当前参数范围,我们将其设置在到合成窗口的高度之间,我们需要在顶部与底部空出几行以得到更好的效果。假如合成窗口的尺寸为320×240,那么就将当前参数范围设置在25至215之间,当滚动栏在Y轴上从25运动到215时,文本区将开始滚动。
                t_min=20
                t_max=220
                当然,当前参数就是滚动栏的Y轴坐标:
                t=this_comp.layer("Scroll").position[1]
                将几条语句综合起来,加以恰当的变量名称,我们就得到了下面的表达式:
                scroll_y=this_comp.layer("Scroll").position[1];
                scrolled_amount=linear(scroll_y, 20, 220, 0, height);
                最后我们将scrolled_amount的值放到一个二维数组中,让文本图层的轴心点X轴坐标保持不变,最终的表达式为:
                scroll_y=this_comp.layer("Scroll").position[1];
                scrolled_amount=linear(scroll_y, 20, 220, 0, height);
                [anchor_point[0], scrolled_amount];
                最后效果如下 (只为滚动栏Y轴的位置属性设置关键帧):

                上面的表达式只要稍加改动就可以实现水平滚动的效果,如果将该表达式应用到3D图层的旋转属性上,就可以制作出三维滚动旋转效果:
                下载如下:

                


                IP属地:江苏10楼2011-12-29 15:24
                回复
                  少了一个9楼 补上

                  circumference=width*Math.PI;
                  最后我们可以从表达式中删除'rotation=' ,我们前面提到过,计算得出的值会自动赋予加入表达式的参数。当将这些语句组织起来的时候我们就得到了最终的表达式:
                  distance=position[0];
                  circumference=width*Math.PI;
                  distance/circumference*360;
                  留给读者一个小练习,试着使用图层的缩放属性来控制旋转属性,哈哈,其实很简单,自己动动脑筋吧!
                  下面这个特殊旋转效果你能利用所学知识完成么:


                  也许有人会问,为什么要花费这么大的经历来讲解参数范围呢,通过为旋转和位置属性设置同步关键帧不是同样可以完成这种真实的效果么。对于匀速运动的图层来说设置关键帧确实可以达到这种效果,但是如果是模拟变速运动利用这种设置关键帧的方法就会出现图层在地面上滑动的状况,手动设置变速运动非常困难,但是使用表达式就方便多了。
                  如果要得到更详细的描述讲解,
                  请看下文
                  


                  IP属地:江苏11楼2011-12-29 15:30
                  回复
                    实例应用
                    在第一部分的最后,我们将使用前面介绍的表达式基础部分的知识来完成一个简单的小例子。我们将重新使用轮胎的例子,使用移动属性来控制图层的旋转属性。
                    首先,让我们整理一下制作思路,我们要给图层的旋转属性加上表达式,并在表达式的最后以一个标量结束,所以首先要给旋转参数加上一个表达式。
                    接下来,我们需要给图层的位置属性设置关键帧,以为位置属性的变化将会驱动旋转属性的变化,在我们的例子中,我们仅仅需要轮胎在X 轴上移动,所以我们只需要:
                    position[0]
                    真实的物理世界告诉我们当轮胎移动一个周长的距离时,它将完成一个周期(360)的旋转,在开始时我们会为设置计算公式而犯愁,还需要知道,轮胎的尺寸会影响到在一个旋转周期内其移动的距离,所以我们需要了解轮胎的尺寸,图层的宽度。
                    假如轮胎的尺寸与图层的尺寸相差无几(在轮胎的周围没有空白的区域),我们可以使用图层宽度来描述轮胎的直径:
                    width;
                    但是我们不能直接使用图层宽度,我们需要使用图层宽度来计算出轮胎的周长,利用基本的几何学公式我们就可以计算出轮胎的周长,Javascript为我们提供了一个精确的PI值,所以我们就可以这样来计算轮胎的周长:
                    circumference=width*Math.PI;
                    如果轮胎的宽度是100个像素,他的周长将会是314个像素,但是如果我们改变图层缩放属性呢,再使用图层的宽度来计算轮胎的周长所得到的结果就不会准确,为了得到更准确的计算结果,我们要利用图层X轴向的缩放属性来控制轮胎的周长:
                    circumference=width*( scale[0]/100)*Math.PI;
                    我们将图层的X轴缩放属性(scale[0])除以100是因为缩放属性的返回值是百分比,
                    接下来我们就需要定义图层在X轴向移动的变量,在我们的例子中我们要使图层从X轴的零点开始移动,所以我们使用下面的表达式:
                    distance=position[0];
                    最后我们写出核心表达式:
                    (distance/circumference)*360;
                    该表达式的含义前面已经介绍过,这里就不详细说明了,综合起来,我们需要给旋转属性赋予这样的表达式:
                    circumference=width*( scale[0]/100)*Math.PI;
                    distance=position[0];
                    (distance/circumference)*360
                    这时再观看动画,会看到轮胎的移动与旋转已经非常的自然了,丝毫没有滑动的痕迹,还是那句话我们可以使用手动设置关键帧来实现同样的效果,但是如果图层作加速减速运动时,表达式的优势更是体现的淋漓尽致。
                    可以将这种方法应用到单独的文字动画中,也可以应用到非正常运动的物体中,得到真实的效果。


                    IP属地:江苏12楼2011-12-29 15:31
                    回复