提交需求
赛事与广告咨询合作,请填写需求表单,我们会在第一时间与您联系!
手写动画了解一下?
设计场景
无缝衔接演化的星空
目标
1. 定义全局参数接口,快速调整。只用一个图层
2. 让参数驱动场景和随机动画的生成
3. 粒子自然随机地分布于界定范围
4. 实现周期随机,并且,达到无缝连接
5. 可按需调整形态
一、星星单体定义
1. 随机纵深
添加一个圆形基本形状,在形状的「路径/大小」属性上定义:
id = thisProperty.propertyGroup(2).propertyIndex;
seedRandom(id,true);
x = random(.001,4);//随机尺寸
y = x;//等宽高
[x,y]
解决思路:
random( ); 可实现数值上的随机,但会导致需要复制多个图层,不够灵活。
祭出进阶随机表达式,用形状层的独立索引 id 来产生随机种子,由一个图层管理:
id = thisProperty.propertyGroup(2).propertyIndex;//2代表返回第二级父级属性索引,此处为形状本身。
seedRandom(id,true);//true 使随机值固定,不随时间跳跃。
random( );
每复制一个星星(形状 Star),它的独立 id 就会产生差异化。
纵深用尺寸差异来体现,定义 [a,b] 限定合适范围即可。
惯用套路,使用一个小数值让最小的粒子都有存在感,范围限制在 (.001,4)。
同样的方法,我们可以添加一个匹配尺寸的随机「模糊」属性,让表现更加真实。
对象大小是一个包含宽、高的二维属性,随机必然产生偏差。
定义其中一个属性(宽度 x),再把其赋值给另一个属性( 高度 y)即可解决:
x = a;
y = x;
[x,y];
2. 角度偏移
形状的「变换/旋转」属性上,定义:
id = thisProperty.propertyGroup(2).propertyIndex;
value + 360*noise(id);//临近角度随机偏移
解决思路:
生成 360° 的临近随机偏移。
noise(id); 生成 [0,1] 的临近偏移量,再乘与 360。
value 为初始角度 0 ,加上偏移量 [0,360]:
value + 360*noise(id);
3. 随机分布
形状的「变换/位置」属性上,定义:
id = thisProperty.propertyGroup(2).propertyIndex;
seedRandom(id,true);
a = width/2;
b = height/2;
gaussRandom([-a,-b],[a,b]);//在画布区域高斯分布,10%在画布外
只用 random( ); 也是可以实现的,不过高斯(正态)分布更加自然,试试无妨。
画布中心是锚点是 [0,0],换算后星空的范围落于 [[-width/2,-height/2],[width/2,height/2]]
如果用于不同图层,只需要换成:
a = width;
b = height;
gaussRandom([0,0],[a,b]);
4. 无缝连接的周期随机亮度
形状的「变换/不透明度」属性上,定义:
freq = .2;//频率,每 0.2s 一次不透明度变化
amp = 100;//不透明度的偏移幅度
loopTime = 4;//定义周期
t = time % loopTime;//取余,周期重置
wiggle1 = wiggle(freq, amp, 1, .5, t);//抖动
wiggle2 = wiggle(freq, amp, 1, .5, t - loopTime);//反向偏移
value - linear(t, 0, loopTime, wiggle1, wiggle2);//首尾相接
学习了 Dan Ebberts 的 Looping Wiggle 方法,思路:
定义两个随机抖动 wiggle1,wiggle2。利用 linear 表达式将其首尾的随机数值连接,实现循环。
loopTime 和 t,则利用「取余」方法定义了动画周期,此处随着时间 (time) 的变化,每隔 4 秒一个周期。
其中,freq, amp 以及 loopTime 是三个核心参数,按需调整即可改变设计。
5. 形态
对形状层添加一个全局的「收缩与膨胀」效果
在「数量」上添加表达式:
a = 1.8 * layerStyle.outerGlow.opacity;//光芒长度和闪烁亮度关联
clamp(a,0,100);//限制范围
思路:
用「表达式关联器」,将星星尖角的数值 a 关联到下文添加的「外发光」属性上,达到亮度和发光度的正确匹配。
星星越亮,突出的尖角就会越大。
clamp( ); 把最大值限制到 100,可按需调整。
6. 无缝连接的周期闪烁
对父级图层 Starry 添加「外发光」样式,定义如下:
freq = .8;//频率,每 0.8s 一次不透明度变化
amp =30;//发光闪烁幅度
loopTime = 4;//定义周期
t = time % loopTime;//取余,周期重置
wiggle1 = wiggle(freq, amp, 1, .5, t);//抖动
wiggle2 = wiggle(freq, amp, 1, .5, t - loopTime);//反向偏移
linear(t, 0, loopTime, wiggle1, wiggle2);//首尾相接
思路:
同 4,应用 looping wiggle 方法。
初始外发光不透明度数值设为 50%,这个场景中,我不希望动画太过跳跃,幅度只用了 ±30%。
每个完整的 4s 周期里面,会有 5 次 每隔 0.8s ,从 20% 到 80% 的外发光闪烁。
调整核心参数 freq, amp 以及 loopTime,即可改变设计。
二、场景生成
单颗星星的定义完成,接下来就要实现设计师的终极愿望了:
一 劳 永 逸!
完整的星空图层结构如下图:
两个全局控制参数决定星星的形态和整体的循环闪烁表现。分别是「收缩和膨胀」效果、「外发光」样式。
每颗星星 (Star) 的 id 会对自身的各子级属性产生不同的随机量。
按住 CMD+D 复制 Star!一片完全由参数驱动的星空扑面而来。
大繁归简,神奇的复制操作~~~
( •̀∀•́ )」✧ ヽ(•̀ω•́ )ゝ
三、小结
StarryNight 动画是对 近期所学 random 系列表达式的一个应用总结。案例中剥离了核心参数和全局控制来提升调整的灵活度和效率。完全可以傻瓜式地,直接使用「复制」快捷键来创造完整的场景。
整个场景的设计都是从本质规律出发的,这么一来就可以根据不同的需求逐步拆解,写出想象中的动画拉~
星空实际上是一种基础的粒子形态。同样的方法还可以生成「云团」、「烟花」、「撒花」、「爆破」等等常见的动态元素或场景。各位可以在此基础上举一反三。
用一根直线路径生成烟花:
星轨
至于研发实现环节,目前业界的 Lottie 方案对移动端的表达式解析还很不完善,对此我还是保留一点期待的。
当前可以使用视频和 apng 等特定的格式来做快速的设计验证。
掌握了核心参数法,视觉和开发 GG 的沟通也会更加的顺滑。
毕竟,他们也是用算法来写的,万变不离其宗——规律。
aep 源文件见文末附件。
附、应用的表达式
noise();//临近随机
random();//随机
id = thisProperty.propertyGroup(2).propertyIndex;//读取第二级父级索引
seedRandom(id,true);//生成随机量,使用 true 让随机值固定,不随时间变化
random();//输出
gaussRandom();//正态分布,10% 随机落于区域外
time*a;//随时间变化,月亮内部加了个湍流置换,效果随时间演化
wiggle(freq,amp);//抖动
clamp(a,aMin,Max);//限制参数a的范围
linear(x, xMin, xMax, output1, output2);//关联线性变化
大牛,别默默的看了,快登录帮我点评一下吧!:)
登录 立即注册