讲故事的手艺人 讲故事的手艺人
  • 创作向
    • 写作
      • 非虚构
      • 剧本
      • 小说
      • 文言
      • 读书
      • 随笔
    • 拍摄
      • 纪录片
      • 设计
      • 视频
      • 摄影
  • 策划向
    • 策划资料
    • 创意之道
    • 短视频研究
  • 技术向
    • AI
    • 前期拍摄
    • 后期制作
    • 原创教程
    • 影像实验
    • 影像设备
    • 穿越机
  • 艺术向
    • 研究学习
    • 大师镜头
    • 电影赏析
    • 视频论文
    • 经验总结
  • 注册
  • 登录
首页 › 技术向 › 原创教程 › AE表达式|38、如何用表达式选择器制作随机排序?

AE表达式|38、如何用表达式选择器制作随机排序?

向安宇
2018-11-13 22:13:08原创教程阅读 2,960

AE表达式|38、如何用表达式选择器制作随机排序?-讲故事的手艺人
接上一篇内容,新建文字层,输入“text”,添加Expression Selector,添加Position

AE表达式|38、如何用表达式选择器制作随机排序?-讲故事的手艺人

给Expression Selector下的Amount添加表达式:

starValue = 100;
endValue = 0;

v = ease(time, textIndex - 1, textIndex, starValue, endValue);
v

得到效果为:
AE表达式|38、如何用表达式选择器制作随机排序?-讲故事的手艺人

添加随机值

上面的效果,每个字母动画是按照从左到右的顺序的,我们希望给每个字母动画的时间随机值,让字母随机开始动画

starValue = 100;
endValue = 0;

r = (Math.floor(random(0,textTotal-1))+1)/textTotal;
v = ease(time, textIndex-1+r, textIndex + r, starValue, endValue) 

我们让random()在“0 ~ 字母总数减1”的范围内取随机值,比如这个例子里“text”只有4个字母,所以会在0~3之间取随机值,然后向下取整,也就是会得到0~3之间的整数,然后加1,得到1~4之间的整数,再除以textTotal。

直接用Math.ceil()效果是一样的:

starValue = 100;
endValue = 0;

r = Math.ceil(random(0,textTotal))/textTotal;
v = ease(time, textIndex-1+r, textIndex + r, starValue, endValue) 

AE表达式|38、如何用表达式选择器制作随机排序?-讲故事的手艺人

这是一个很奇怪的效果,因为每一帧random都会随机取一次值,所以运动并不是连续的。

将随机数限定为一个字母计算一次

表达式写为:

starValue = 100;
endValue = 0;
seed = 1;
i=0;
v=starValue;
last = 60;

arr=[];
for (n=0;n<textTotal;n++){ arr.push(n+1); } 

rf=timeToFrames(time-inPoint); 
while(rf>=i){
	l=arr.length;
	i++;
	if (l>0){
		seedRandom(seed++,true);
		r = Math.floor(random(0, l - 1));
		a=arr[r];
		if (a==textIndex){
			rt=framesToTime(rf-i-6);
			v = ease(rf, i, i + last, starValue, endValue)
			}
		arr.splice(r,1);
		}
	}
v

计数数组的建立与随机取值

这里计数数组的建立是如下代码

arr=[];
for (n=0;n < textTotal;n++){
arr.push(n+1);
}

arr = []声明一个数组,也可以写作:arr = Array();

然后利用for循环往里面添加元素:

  温习下for循环:

for(初始化语句;条件1;增量语句){ 
//代码块1
}

  for语句解释:先执行初始语句,接着条件1的判断为true,在执行代码块1,然后执行增量语句,然后条件1的判断,如此循环直到条件1为false。

 

    push方法:
    push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度。

 
在这个例子里,n的初始值是0,满足n < textTotal 的条件,执行arr.push(n+1),也就是给数组arr[]添加元素“n + 1”,即“1”。
此时数组arr[]为[1]。
然后执行增量语句 n++ 得到结果为: n = 1
继续判断条件:n < textTotal
执行push,为arr[]添加元素“ 2 ”
继续执行增量语句 n++ 得到结果为: n = 2
再次判断条件:n < textTotal
执行push,为arr[]添加元素“ 3 ”
继续执行增量语句 n++ 得到结果为: n = 3
继续判断条件:n < textTotal
执行push,为arr[]添加元素“ 4 ”
继续执行增量语句 n++ 得到结果为: n = 4
继续判断条件:n < textTotal (这个例子里textTotal为 4 )
条件判断false,不再继续执行条件语句,循环结束
得到数组[1,2,3,4]

接着,利用random到数组[1,2,3,4]里去取随机值,如下语句:

seedRandom(seed++,true);
r = Math.floor(random(0, arr.length - 1));
a = arr[r];

因为数组的索引index是从0开始计算的,本例中arr[0]为“1”,arr[2]为“3”,index最大值为3,也就是arr.length - 1

random()取值的时候,只能取0~3 ,也就是( 0 ~ arr.length - 1)的范围,然后括起来,在前面添加Math.floor()向下取整,本例中也就是返回0~3范围内的随机整数。

a = arr[r] 得到的就是[1,2,3,4]数组中的一个随机位置的值。

seedRandom则是让random()每一次计算取一次值,而不是每帧都去取一次值。

取完一次之后,就把取出来的这个数在arr中删去,利用aplice()方法,这里表达式写为:arr.splice(r,1);

    splice方法:
    splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目。
    其语法为:
        arrayObject.splice(index,howmany,item1,.....,itemX)
    index 必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。
    howmany 必需。要删除的项目数量。如果设置为 0,则不会删除项目。
    item1, ..., itemX 可选。向数组添加的新项目。

  
这样就能够保证下个”字母”取值完全不会重复。

这时候表达式写作:

starValue = 100;
endValue = 0;
seed = 1;

arr = Array();
for (n = 0; n < textTotal; n++){//需将全角<改为半角
arr.push(n + 1);
}

seedRandom(seed++,true);
r = Math.floor(random(0, arr.length - 1));
a = arr[r];
v = ease(time, textIndex, textIndex + 1, starValue, endValue);
arr.splice(r,1);

v

这时候的表达式并不会报错,但是并没有随机效果。

我的理解是,这个表达式只取出来一个随机值,需要添加一个循环语句,让表达式不断循环运算。

在此之前,利用timeToFrames将单位从秒改为帧。

添加whlie循环,将随机数限定为一个字母计算一次

starValue = 100;
endValue = 0;
seed = 1;
i = 0;
v = starValue;
last = 60;

arr = Array();
for (n = 0; n < textTotal; n++){
arr.push(n + 1);
}

rf=timeToFrames(time - inPoint);
while(rf >= i){
	i++;
	if (arr.length > 0){
		seedRandom(seed++,true);
		r = Math.floor(random(0, arr.length - 1));
		a = arr[r];
			if (a == textIndex){
			v = ease(rf, i, i + last, starValue, endValue)
			}
		arr.splice(r,1);
	}
}
v

我的理解是,用while循环运算,并限定a == textIndex时候,返回一次结果。

镜像曲线,添加反向动画

在rf = timeToFrames(time - inPoint)后面添加:

if (time > outPoint / 2 - inPoint / 2) {
rf=-rf+timeToFrames(outPoint-inPoint);
}

优化运动

添加一个弹性效果:

if (rf > i + 6) { 
v-= rate * Math.sin(2 * rt * 2 * Math.PI) / Math.exp(3 * rt);
}

最后写成:

starValue = 100;
endValue = 0;
seed = 1;
rate = 40;

t = text.sourceText;

if (time < outPoint/2-inPoint/2) {
	arr=Array();
	for (n=0;n=i)
{
	l=arr.length;
	i++;
	if (l>0)
	{
	seedRandom(seed++,true);
	r = Math.floor(random(0, l - 1)); 
	a=arr[r];
		if (a==textIndex)
		{
		rt=framesToTime(rf-i-6);
	v = ease(rf, i, i + 6, starValue, endValue) 
		if (rf > i + 6)
			 { 
		v-= rate * Math.sin(2 * rt * 2 * Math.PI) / Math.exp(3 * rt);
			}
		}
	arr.splice(r,1);
		}
	}
}

if (time >= outPoint/2-inPoint/2)
	{
	i = 0;
	arr=Array();
	for (n=0;n=i)
		{
		l=arr.length;
		i++;
		if (l>0){
		seedRandom(seed++,true);
		r = Math.floor(random(0, l - 1)); 
		a=arr[r];
	if (a==textIndex)
		{
		rt=framesToTime(rf-i-6);
		v = ease(rf, i, i + 6, starValue, endValue) ;
		if (rf > i + 6) 
			{ 
			v-=rate * Math.sin(2 * rt * 2 * Math.PI) / Math.exp(3 * rt);
			}
		}
	arr.splice(r,1);
		}
	}
}

v

只有上面之前添加的position,将其y轴改为300,效果为:
AE表达式|38、如何用表达式选择器制作随机排序?-讲故事的手艺人

再添加scale,将值改为0;
添加rotation,将值改为45;

AE表达式|38、如何用表达式选择器制作随机排序?-讲故事的手艺人
其效果为:
AE表达式|38、如何用表达式选择器制作随机排序?-讲故事的手艺人

该文参考了贴吧“秋风_小径”的文章“AE文字层->表达式选择器的基础及进阶”

作者在另外一个帖子里有注释:

starValue = 100; //开始值
endValue = 0; //结束值
seed = 1; //随机种子,在下面使用speed++,每用一次自加一次,保证随机性


t = text.sourceText; //t为文字层文字
arr = Array(); //定义新数组
for (n = 0; n < t.length; n++) {
arr.splice(n, 0, n + 1) //数组 删除从 n 处开始的零个元素,添加新的元素n+1,这里说白了就是往arr里面塞1 2 3 4.....一直塞到t.length...建立计数数组,这种方法很少见
}
i = 0;
v = starValue; //100
tv = 0; //0
rf = timeToFrames(time - inPoint); //获得层帧数
while (rf >= i) { //循环次数为文字个数,大于文字个数则跳出循环,为每个文字产生不同的缓入曲线
l = arr.length; 
i++;
if (l > 0) {
seedRandom(seed++, true); //设置随机种子
r = Math.floor(random(0, l - 1)); //将随机数求整
a = arr[r]; //从数组里取出随机数指定的元素
if (a == textIndex) { //若此元素与textIndex相等 textIndex取决于Based On选择的项目,比如当时Characters的时候,第一个字母的index就为0
rt = framesToTime(rf - i - 6); //则,将帧数减去i的次数减六.转换为时间,
v = ease(rf, i, i + 6, starValue, endValue) //产生缓入缓出曲线,从100到0,时间从i到i+6,共七帧
if (rf > i + 6) { //若帧数大于i+6
tv = 20 * Math.sin(2 * rt * 2 * Math.PI) / Math.exp(3 * rt) //产生震荡曲线,与v共同控制产生最后的曲线,这个曲线持续时间比较长
}
}
arr.splice(r, 1); //arr删除r处的元素
}
}//当层帧数大于循环次数,结束循环


if (time >= outPoint - 2) { //时间在层结束时间的前二秒内
i = 0;
arrend = Array();
for (n = 0; n < t.length; n++) {
arrend.splice(n, 0, n + 1) //同样建立从1到t.length的计数数组
}
rfend = timeToFrames(time - outPoint + 2); //获得时间到层结束时间的前二秒之间的帧数.,在这个时间内完成结束曲线
while (rfend >= i) { //同样,为每一个字母都产生不同的曲线,完毕则跳出循环
l = arrend.length;
i++;
if (l > 0) {
seedRandom(seed++, true);
r = Math.floor(random(0, l - 1));
a = arrend[r]; //取出随机计数
if (a == textIndex) { //若等于textIndex
rtend = framesToTime(rfend - i - 6); //则先帧数减去i减去6转换为时间
v = ease(rfend, i + 2, i + 6, endValue, starValue + 20) //产生缓入缓出曲线,时间为i+2到i+6共五帧,从0到120
tv = 20 * Math.sin(90 + 2 * rtend * Math.PI) / Math.exp(3 * rtend) //产生震荡曲线,与v共同控制产生最后的曲线

}
arrend.splice(r, 1); //删去r元素
}
}
}


v - tv //v-tv产生最终缓入缓出曲线,在层结尾有很大毛病

另外作者给了一个改良版,

改良版

starValue = 100;
endValue = 0;
seed = 1;


t = text.sourceText;
arr=Array();
for (n=0;n=i)
{
l=arr.length;
i++;
if (l>0){
seedRandom(seed++,true);
r = Math.floor(random(0, l - 1)); 
a=arr[r];
if (a==textIndex)
{
rt=framesToTime(rf-i-6);
v = ease(rf, i, i + 6, starValue, endValue) 
if (rf > i + 6) { 
tv = 20 * Math.sin(2 * rt * 2 * Math.PI) / Math.exp(3 * rt);
}
}
arr.splice(r,1);
}
}


if (time >= outPoint/2-inPoint/2) {
i = 0;
arr=Array();
for (n=0;n=i)
{
l=arr.length;
i++;
if (l>0){
seedRandom(seed++,true);
r = Math.floor(random(0, l - 1)); 
a=arr[r];
if (a==textIndex)
{
rt=framesToTime(rf-i-6);
v = ease(rf, i, i + 6, starValue, endValue) ;
if (rf > i + 6) { 
tv = 20 * Math.sin(2 * rt * 2 * Math.PI) / Math.exp(3 * rt);
}
}
arr.splice(r,1);
}
}
}


v-tv;

< 返回目录

AE表达式
赞赏 赞(4) 收藏(0)
本文系作者 @向安宇 原创发布在 讲故事的手艺人。未经许可,禁止转载。
AE表达式|37、怎样单独控制文字层的每一个文字?-表达式选择器Expression Selector基础
上一篇
多年前收藏的土家语歌曲两首
下一篇

请登录以参与评论

现在登录
暂无评论
标签
720全景 ACES AE AE案例 AE表达式 Anyu翻译 CSC电影学院 fusion Hackintosh MG动画 ps教程 vlog wordpress 创意方法 剪辑 字幕 帧影帧画 抖音 摄影 文案 混剪 混音 灯光 看电影 磨皮 穿越机 纪录片 编剧 美术 美食 論語 调度 调色 达芬奇 重讀文學史 青玉记
室内360全景图的简单修图
2020-10-13 21:51:45
2,691 0 0
达芬奇:高频锐化
2020-03-21 22:41:26
3,878 0 3
3、ISO
2019-11-06 21:54:32
1,754 0 0
2、光圈和景深
2019-11-03 17:10:31
1,756 0 2
4
  • 4
  • 0
关于我:

想要读万卷书,行万里路,看万部电影。当过人民教师,做过策划师,入行影视做剪辑、导演。艺术是目的,技术是支撑,不断钻研,积聚梦想,同时分享干货。

推荐栏目:
视频论文 原创教程 后期制作 非虚构 照片 视频
特色专题:
专题汇总 宜看一侃 帧影帧画 美食摄影 重读文学史 青玉记
Copyright © 2016-2025 讲故事的手艺人. 鄂ICP备16005400号-1 鄂公网安备42050602000017号
  • 创作向
    • 写作
    • 拍摄
  • 策划向
    • 策划资料
    • 创意之道
    • 短视频研究
  • 技术向
    • AI
    • 前期拍摄
    • 后期制作
    • 原创教程
    • 影像实验
    • 影像设备
    • 穿越机
  • 艺术向
    • 研究学习
    • 大师镜头
    • 电影赏析
    • 视频论文
    • 经验总结
# 剪辑 # # 转场 # # 纪录片 #
向安宇
痴迷文字,醉心影像
420
文章
5
评论
325
喜欢