Starry Night

2018-02-27 10:58:49来源:http://www.ui.cn/detail/163736.html作者:UI中国人点击

分享

手写动画了解一下?



设计场景


无缝衔接演化的星空


目 标


定义全局参数接口,只用一个图层快速调整。 让参数驱动场景和随机动画的生成。 粒子自然随机地分布于界定范围。 实现周期随机,并且无缝连接。 可按需调整形态。


一、实现


1、星星单体定义


1.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];


1.2. 角度偏移


形状的「变换/旋转」属性上,定义:


id = thisProperty.propertyGroup(2).propertyIndex;


value + 360*noise(id);//临近角度随机偏移


解决思路:


生成 360° 的临近随机偏移。


noise(id); 生成 [0,1] 的临近偏移量,再乘与 360。


value为初始角度 0 ,加上偏移量 [0,360]:


value + 360*noise(id);


1.3. 随机分布


形状的「变换/位置」属性上,定义:


id = thisProperty.propertyGroup(2).propertyIndex;


seedRandom(id,true);


a = width/2;


b = height/2;


gaussRandom([-a,-b],[a,b]);//在画布区域高斯分布,10%在画布外


只用 random( ); 也是可以实现的,不过高斯(正态)分布更加自然,试试无妨。


至于范围为何在 [-width/2,-height/2],[width/2,height/2]?


画布中心锚点是 [0,0],换算如上。


如果用于不同图层上,只需要换成:


a = width;


b = height;


gaussRandom([0,0],[a,b]);


1.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 秒一个周期。


1.5. 形态


对形状层添加一个全局的「收缩与膨胀」效果


在「数量」上添加表达式:


a = 1.8*layerStyle.outerGlow.opacity;//光芒长度和闪烁亮度关联


clamp(a,0,100);//限制范围


思路:


用「表达式关联器」,将星星尖角的数值 a 关联到下文添加的「外发光」属性上,达到亮度和发光度的正确匹配。


星星越亮,突出的尖角就会越大。


clamp( ); 把最大值限制到 100,可按需调整。


1.6.无缝连接的周期闪烁


对父级图层添加「外发光」样式,定义如下:


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% 的外发光闪烁。


二、场景生成


单颗星星的定义完成,接下来就要实现设计师的终极愿望了:


一 劳 永 逸!


完整的星空图层结构如下图:


「收缩和膨胀」效果、「外发光」样式,都是全局控制。


每颗星星 (Star) 的 id 会对自身的各子级属性产生不同的随机量。



按住 CMD+D 复制 Star!一片完全由参数驱动的星空扑面而来。


大繁归简,神奇的复制操作


( •̀∀•́ )」✧ヽ(•̀ω•́ )ゝ


三、小结


StarryNight 动画是对 近期所学 r andom 系列 表达式的一个应用总结。


案例中剥离了 核心参数 和 全局控制 来提升调整的灵活度和效率。


整个场景的设计都是 从本质规律出发 的,这么一来就可以根据不同的需求写出想象中的动画拉~


星空实际上是一种基础的粒子形态。同样的方法还可以生成「云团」、「烟花」、「撒花」、「爆破」等等常见的动态元素或场景。


各位可以在此基础上举一反三。


至于实现环节,目前业界的 Lottie 方案对移动端的表达式解析还很不完善,对此我还是保留一点期待的。


掌握了核心参数法构建动画绝对不亏,视觉和开发 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);//关联线性变化


最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台