看似简单的几个动效,在APP中实现过程并不简单
adinnet/2017-09-21 10:18/APP开发
想要让产品能够像呼吸一样自然,动效的处理很关键。但是,对于远离设计和开发的普通用户而言,很难想象这些看起来无比简单的动效和交互是如此的耗费时间和精力。显而易见的设计背后,是技术和艺术通力协作。
在Tubik Studio 的设计实战案例当中,动效是很重要的组成部分,它们和整个UX 设计紧密关联,分割不开。今天的文章,我们来看看它的动效都是怎么实现的。
时间选择器动效
闹钟应用当中,闹钟自然是APP当中交互和功能的核心,动效能够很好地调和界面和功能之间的关系。想要将设计落实到真实的功能和交互上去,这就要看开发的功力了。
动画所有相关的内容都被放在自定义的子类 UIView 当中,在这个案例当中,我们将其命名为 AnimatedDayView。
底部的一层是可以无限滚动的 UIScrollView (1),这一层包含了下面的图片副本。
在实现无限滚动的效果上,有许多不同的方法。在这个滚动试图当中,需要重新计算滚动控件的大小,并且将不可见的预览替换成新的图像。
在设计 Toonie 的时间选择器的时候,我们将默认起点设置为上午6点,中点为下午6点,终点为第二天上午6点。
接下来的一层是 Stars UIImageView (2)。这个 UIImageView 曾会随着时间的选择,也就是滚动控件而变化。它在白天是透明的,随着夜晚降临而逐步出现。
再向上一层,则是用来承载太阳和月亮的 CALayer,SunMoonBackgroundLayer,虽然它和 AnimatedDayView 有着相同的尺寸,但是在运作时间周期上并不相同。这一层会围绕着一个中心点周期性转动,从而保证太阳和月亮会次第出现。太阳(4)和月亮(5)位于 SunMoonBackgroundLayer 之上,也是两个独立的图层。月亮在旋转方向上和这一层是一样的,但是太阳则会从相反的位置旋转出项。值得一提的是,月亮和太阳出现的角度尺寸并不一样。
在这个环节,更重要的问题是要算清楚每一层的旋转角度和程度,滚动的距离有多远,等等等等。滚动距离其实是更容易计算的,变量始终是时间,也即是用户在 UIDataPicker 上所选择的时间。现在,计时器的默认初始时间是上午6点整,如果用户选择上午9:10的闹钟,那么我们需要计算时间差(190分钟),然后将其换算成各个组件需要运动的位移大小(滚动多少像素,旋转角度等)。当经过24小时,背景向下滚动的距离相当于它本身的长度,由此可以计算出一分钟背景向下滚动的距离:每分钟运动距离=背景图片高度/每天的分钟数,这样也就知道这个时间差内(190分钟),背景要运动的距离了。
接下来,另外一件事情就是用Alpha 通道来控制星星的变化。我们可以根据时间节点来控制特定位置的Alpha 通道值来控制星星的显示。在早上6点的时候,这些位置的Alpha 值为0,因为白天开始了。直到下午6点之后,繁星初现,Alpha 值从0开始,到晚上12点到达1。控制这一切的核心参数同样可以是背景图像的移动距离,或者当前位置,因为这一参数和当前时间是紧密关联的,可以轻松计算出来。开发可以通过控制 Alpha 值的相关函数来影响显示效果。
旋转角度也同样可以通过简单的计算来确定。6点的时候为0度,24小时旋转360度,简单的除法就可以算出每分钟旋转的角度。
另外一个需要控制的视觉元素是云。它的出现时间是由NSTimer 所影响的,系统内置了3种不同样式的云朵,当它出现的时候,会随机赋予一个Alpha 通道值,并且从屏幕右方出现,向左缓慢运动。定时器会随机生成云朵,当它运动到屏幕之外就完全消失。
闹钟开关
在日常使用过程中,闹钟的开关也是一个非常常用的控件。为了贴合应用的主题,闹钟开关的样式设计成为一个小太阳。
闹钟开关的运作方式,你可以通过代码来了解它的运行方式。设计上,整个闹钟按钮分为4个不同的图层。
圆角矩形的背景框(4)是用来承载按钮的元素,在它上方靠近右边缘的小太阳(2)是开关主体,它可以在底部的槽(1)的范围内左右运动,同时,为了具备装饰性,加入了不断旋转的太阳光晕(3),光晕被设计为单独的图层,它会不断的旋转,不会和其他的因素产生交叉关联。
不过,当开关关闭的时候,光晕(3)的Alpha 值会变为0,动画停止。这几个图层当中,更大的图层是背景(4),这个图层当中包含一个蒙板CAShapeLayer。
let switcherBackgroundMask = [[CAShapeLayer alloc] init];
switcherBackgroundMask.fillRule = kCAFillRuleEvenOdd;
UIBezierPath* viewPath =[UIBezierPathbezierPathWithRoundedRect:self.boundscornerRadius:cornerValue];
UIBezierPath* switcherBackgroundPath = [UIBezierPath bezierPathWithRoundedRect:switcherRect cornerRadius:switcherHeight/2.0];
[viewPath appendPath:switcherBackgroundPath];
switcherBackgroundMask.path = viewPath.CGPath;蒙板塑造了整个圆角矩形的外轮廓。在交互的控制上,还添加了两个手势识别器:UITapGestureRecognizer 是用来识别打开的动作,而UIPanGestureRecognized 是用来识别关闭的动作。
在这个动效设计过程中,想要做到自然可用的动效,动效设计师需要仔细地推敲和分割元素,在整个方案上深思熟虑,才能更终实现正确的效果。
本文转自:http://www.uisdc.com/case-study-toonie-coding-animation