iOS进阶之编写弹性动画
前言
之前在iOS开发干货 第1期中提到过一个挺有意思的数字转变动画NumberMorphView , 如下图:
![](https://raw.githubusercontent.com/me-abhinav/NumberMorphView/dev/sample.gif)
我将通过几篇文章对这个开源库做一些分析,当然,这篇文章不会对它做全面的解析,而是利用这个库的一些技术概念来做一些简单的示例,也算是一个引子,后面会抽时间再写一篇对这个库的代码分析,敬请期待。
要做些什么
我们将会使用CADisplayLink + CAShapeLayer + UIBezierPath结合制作一个毫秒级的画圆动画,不同的是,这个动画具有弹性效果,下面先来看看制作的效果:
![](http://upload-images.jianshu.io/upload_images/416851-dfdecdd4c73e4280.gif?imageMogr2/auto-orient/strip)
开始
准备工作
- 先新建一个Single View Application项目,在项目中添加类RRCircleAnimationView,继承于UIView。
- 打开Main.storyboard,将唯一的一个ViewController的view custom class修改为RRCircleAnimationView。
至此,准备工作已经完成。
动手来画个圆
先来个简单任务,我们来实现画圆动画。
第一步,为RRCircleAnimationView添加属性:
@implementation RRCircleAnimationView
{CADisplayLink *_displayLink; // CADisplayLink可以确保系统渲染每一帧的时候我们的方法都被调用, 从而保证了动画的流畅性,毫秒级动画就靠他。UIBezierPath *_path; // 用于创建基于矢量的路径CGPoint _beginPoint; // 开始触摸位置CGPoint _endPoint; // 触摸结束的位置CAShapeLayer *_shapeLayer; // 可以结合UIBezierPath进行绘画}
接着初始化实例变量,由于我们用的是storyboard进行加载,所以可以在awakeFromNib方法里面初始化
// 注意这里我们是直接从xib加载当前view。
- (void)awakeFromNib
{_shapeLayer = [CAShapeLayer layer];[self.layer addSublayer:_shapeLayer];_shapeLayer.fillColor = [UIColor colorWithRed:0.400 green:0.400 blue:1.000 alpha:1.000].CGColor;_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateFrame)];[_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}
接下来实现上面CADisplayLink要不停调用的updateFrame
方法,我们在此方法内不断地画圆。
- (void)updateFrame {// 画圆_path = [UIBezierPath bezierPathWithArcCenter:_beginPoint radius:[self getRadius] startAngle:0 endAngle:M_PI*2 clockwise:YES];_shapeLayer.path = _path.CGPath;}
上面我们用开始触摸的点的位置作为圆心的位置,再根据特定的半径进行绘制一个圆,这个半径是根据我们触摸的开始点和结束点进行计算出来的,开始触摸点到结束点的距离就是这个圆的半径。
我们先把触摸的起始和结束点给找到:
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{UITouch *touch = [touches anyObject];CGPoint point = [touch locationInView:self];_beginPoint = point;_endPoint = point;
}- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{UITouch *touch = [touches anyObject];CGPoint point = [touch locationInView:self];_endPoint = point;
}
最后计算用上我们中学的数学知识,根据两点坐标距离公式
![](http://upload-images.jianshu.io/upload_images/416851-b2f319ff4c58c8f4.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
可以得到我们起始和结束两点的距离,也就是圆的半径是:
- (CGFloat)getRadius
{CGFloat result = sqrt(pow(_endPoint.x - _beginPoint.x, 2) + pow(_endPoint.y - _beginPoint.y, 2));return result;
}
到这里画圆动画完成。
加入弹性效果
上面只是的画圆动画看起来是没什么问题了,不过总感觉缺少动感,接下来我们来帮他加入些活力!
添加一下成员变量到RRCircleAnimationView类中。
BOOL _isTouchEnd; // 触摸结束标志int _currentFrame; // 当前的帧数
在
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
方法内添加以下代码:_isTouchEnd = NO; //重置触摸状态_currentFrame = 1; //重置当前的帧数
添加以下方法:
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{_isTouchEnd = YES; //触摸结束,更新触摸状态}
将方法
- (CGFloat)getRadius
修改如下:- (CGFloat)getRadius{CGFloat result = sqrt(pow(_endPoint.x-_beginPoint.x, 2)+pow(_endPoint.y-_beginPoint.y, 2));if (_isTouchEnd) {CGFloat animationDuration = 1.0; // 弹簧动画持续的时间int maxFrames = animationDuration / _displayLink.duration;_currentFrame++;if (_currentFrame <= maxFrames) {CGFloat factor = [self getSpringInterpolation:(CGFloat)(_currentFrame) / (CGFloat)(maxFrames)]; //根据公式计算出弹簧因子return MAX_RADIUS + (result - MAX_RADIUS) * factor; // 根据弹簧因子计算当前帧的圆半径}else {return MAX_RADIUS;}}return result;}
最后加入神奇的公式:
- (CGFloat)getSpringInterpolation:(CGFloat)x{CGFloat tension = 0.3; // 张力系数return pow(2, -10 * x) * sin((x - tension / 4) * (2 * M_PI) / tension);}
这个公式用数学符号表达出来是:
![](http://upload-images.jianshu.io/upload_images/416851-ee60369469a6c045.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
可以用Mac OS X自带的软件叫Grapher
画出此函数的的图像,如下图:
![](http://upload-images.jianshu.io/upload_images/416851-4a9971912fa51c85.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
这个函数的作用其实就是通过x值,也就是当前帧数除以允许的最大帧数。
(CGFloat)(_currentFrame) / (CGFloat)(maxFrames)
因此,x的值的范围也就是(0, 1]。
我们所要的动画效果是把圆拉大到超过或者小于设定的目标半径MAX_RADIUS
时,需要一个弹性动画逐渐回到设定好的目标半径。
回头再看一下实时计算动画半径的公式:
MAX_RADIUS + (result - MAX_RADIUS) * factor
为了让x = 1的时候,半径 = MAX_RADIUS,所以这时factor就应该为0,也就是f(1) = 0。
再看看刚才的函数图像,在x = 0到1之前振动,随着x的增加振幅逐渐减少,当x = 1的时候,y值为0。
最后
这篇文章讲述了如何自己实现具有弹性的帧动画,如果能理解好这种动画制作原理,对动画效果开发是很有帮助的,后面有时间会继续写其他的一些动画制作的方法,实现更多的动画效果。
差点忘了说了,目前这个动画已经放到github上面,传送门:RRongAnimation
![](https://raw.github.com/MellongLau/RRongAnimation/master/Screenshots/screenshot.gif)
The End
原文链接:http://www.jianshu.com/p/cf9f600a5342
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
iOS进阶之编写弹性动画相关推荐
- android 仿ios动画效果代码,Android仿IOS上拉下拉弹性效果的实例代码
用过iphone的朋友相信都体验过页面上拉下拉有一个弹性的效果,使用起来用户体验很好:Android并没有给我们封装这样一个效果,我们来看下在Android里如何实现这个效果.先看效果,感觉有些时候还 ...
- BasicAnimation:纯Swift的基础动画库,支持 iOS 属性动画:缩放、旋转、平移、背景颜色、透明度、阴影等和弹性动画
BasicAnimation https://github.com/ZuopanYao/BasicAnimation iOS 属性动画:缩放.旋转.平移.背景颜色.透明度.阴影等,一句代码的事 支持以 ...
- iOS - 个人中心果冻弹性下拉动画
先上图,看效果 这是之前App里买呢一个功能,当初没有写完,今天想起来,把这个功能给完善了,首先来讲讲这个功能的原理: 1.上面浅绿色那一部分是利用贝塞尔曲线画出来的,这个问题不大: 2.下面的那条弧 ...
- Swift 弹性动画教程
原文:How To Create an Elastic Animation with Swift 作者:Daniel Tavares 译者:kmyhy 每个优雅的 iOS app 都会有一些定制的元素 ...
- 如何用Swift实现一个好玩的弹性动画
本文由CocoaChina译者浅夏@旧时光翻译自Raywenderlich 原文:How To Create an Elastic Animation with Swift 每个像样的iOS应用程序一 ...
- js进阶 13-5 jquery队列动画如何实现
js进阶 13-5 jquery队列动画如何实现 一.总结 一句话总结:同一个jquery对象,直接写多个animate()就好. 1.什么是队列动画? 比如说先左再下,而不是左下一起走 2.怎么实现 ...
- iOS进阶之架构设计MVVM的理解(3)
iOS进阶之架构设计MVC(1) iOS进阶之架构设计MVP(2) 前言: 前两篇文章已经理解MVC.MVP的设计模式.特别是MVP,比较难以理解,不好把握.需要多多实践,对比.来优化P段,找到最适合 ...
- iOS进阶 - iOS如何监控崩溃
转载自:https://blog.csdn.net/qxuewei/article/details/90760508 iOS进阶 - iOS如何监控崩溃 几种常见的崩溃 数组越界:给数组添加 nil: ...
- IOS项目之弹出动画二
在IOS项目之弹出动画一中只是实现也功能,并没有体现面向对象的思想 ,今天就试着把它封装了一下,弹出视图的内容可以根据自定义,此处只是用UIDatePicker来演示 我把它传到了GitHub上 ...
最新文章
- dz 数据表分析!!!
- 设计模式系列-建造者模式
- 全国默哀 网站首页都要变成灰色的简单解决办法
- 源码安装python
- HOG特征检测学习笔记
- php mongodb 别名,PHP mongo与mongodb扩展 | 码路春哥
- 那些视觉上骗了你的东西,你上当了吗?
- php java memcached_php-memcached详解
- xhtml、html与html5的区别
- vs 2013 常用快捷键及常见问题的解决
- 北京理工大学语音识别技术.ppt
- Flutter之播放视频
- 小米6twrp最新第三方rec_小米5(gemini:双子座)刷机
- 表单提交复选框(checkbox)注意事项
- ps考证分数是用电脑改的吗
- Ubuntu18.04-使用wine打开CAJ文件并解决乱码问题
- C++语言课程设计——超市商品管理系统
- 三星note20u计算机功能,三星Note20Ultra隐藏功能有哪些-有哪些使用技巧
- 华为云各组件等缩写与全拼
- 《Cluster Contrast for Unsupervised Person Re-Identification》论文阅读