专栏名称: 程序员大咖
为程序员提供最优质的博文、最精彩的讨论、最实用的开发资源;提供最新最全的编程学习资料:PHP、Objective-C、Java、Swift、C/C++函数库、.NET Framework类库、J2SE API等等。并不定期奉送各种福利。
目录
相关文章推荐
阿里技术  ·  别再手搓测试数据了!AE测试数据智造系统揭秘 ·  19 小时前  
阿里云云栖号  ·  2025阿里云中企出海峰会·深圳,6月24日见! ·  昨天  
玉伯  ·  感谢使用 ... ·  昨天  
51好读  ›  专栏  ›  程序员大咖

iOS特效之仿Mac窗口最小化的神奇效果

程序员大咖  · 公众号  · 程序员  · 2017-09-18 10:24

正文

请到「今天看啥」查看全文



在上图的基础上加入一个坐标轴,这样便于观察规律。


在动画执行过程中,网格上的点会沿着一个方向缩放,我们称缩放的轴为缩放轴,图中的缩放轴是y轴。同时还需要在缩放轴上指定一个缩放中心点。在动画的第二个阶段,所有点会沿着一个方向移动,我们称这个轴为移动轴,图中的移动轴是x轴。



动画第一阶段



在动画的第一个阶段中,网格上的点只在缩放轴上移动。我们假设一个点在移动轴上的位置为movLoc,那么我们可以使用公式0.5 * 0.98 * cos(3.14 * movLoc + 3.14) + 0.5 + 0.01;计算出第一阶段结束时,该点需要向缩放中心点缩放的量。为什么是这个公式呢,我给大家贴一张图就清楚了。是不是和上面的边缘曲线有点像。图我是用Mac自带的Grapher绘制的。在调试曲线的过程中Grapher的确非常好用。公式里的0.98和0.01是相关的两个量,控制左边窄口的大小。0.01 = (1 - 0.98) / 2。动画第一阶段主要的工作就是根据当前动画的进度百分比,控制点到达最终缩放量的进度即可。




动画第二阶段



第二阶段主要就是移动轴上的移动,我们可以根据最远移动距离和当前的动画进度计算出当前点在移动轴上的位置。然后根据当前的位置计算出缩放轴上需要的缩放量。最远距离可以通过吸入点和另一侧的边界计算出来。



Shader



了解完原理我们来看Shader代码吧。Swift代码比较简单,只是生成了一个撑满屏幕的nxm网格,稍候再说。



传入Shader的数据



VertexIn和VertexOut很普通,包含顶点位置和纹理坐标。Uniforms里包含了动画相关的信息,当前动画经过的时间animationElapsedTime,动画总时间animationTotalTime,吸入点gatherPoint。

struct VertexIn
{
    packed_float3  position;
    packed_float2  texcoord;
};

struct VertexOut
{
    float4  position [[position]];
    float2  texcoord;
};

struct Uniforms
{
    float animationElapsedTime;
    float animationTotalTime;
    packed_float3 gatherPoint;
};




动画实现



动画的实现都在Vertex Shader里。步骤如下。


  • 计算并规范动画进度,得到动画进度animationPercent。

  • VertexOut outVertex;
    VertexIn inVertex = vertexIn[vid];
    float animationPercent = uniforms.animationElapsedTime / uniforms.animationTotalTime;
    animationPercent = animationPercent > 1.0






请到「今天看啥」查看全文