iOS动画解析之圆球加载动画XLBallLoading的实现

前言

当网页的页面大小较大,用户加载可能需要较长的时间,在这些情况下,我们一般会用到(加载)loading动画,提示于用户页面在加载中,本文将详细给大家介绍关于iOS圆球加载动画XLBallLoading实现的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。

一、显示效果

二、原理分析

1、拆解动画

从效果图来看,动画可拆解成两部分:放大动画、位移动画

放大动画 比较简单,这里主要来分析一下位移动画

(1)、先去掉缩放效果:

屏蔽放大效果

(2)、去掉其中的一个圆球

现在基本可以看出主要原理就是让其中一个圆球绕另一个球做圆弧运动,只要确定一个圆球的运动轨迹,另一个圆球和它左相对运动即可。下面咱们重点说一下这个圆弧运动的原理。

2、圆弧运动

为了方便观察我们先放慢一下这个动画,然后添加辅助线:

放慢后的效果图

从图中可以看出,蓝色球主要经过了三段轨迹

  • 第一段:从左边缘逆时针运动180°到灰色球的右侧
  • 第二段:从灰色球右侧贴着灰色球逆时针运动180°到其左侧
  • 第三段:从灰色球左侧返回起始位置

既然分析出了运动轨迹,下面实现起来就方便了

第一段:蓝色球以A为起点,沿圆心O逆时针运动到B点

第二段:蓝色球以B为起点绕圆心P运动到C点

第三段:从C点返回原点

三、实现代码

1、第一段运动:

确定起始点、圆心、半径,让蓝色小球绕大圆

 //动画容器的宽度
 CGFloat width = _ballContainer.bounds.size.width;
 //小圆半径
 CGFloat r = (_ball1.bounds.size.width)*ballScale/2.0f;
 //大圆半径
 CGFloat R = (width/2 + r)/2.0;
 UIBezierPath *path1 = [UIBezierPath bezierPath];
 //设置起始位置
 [path1 moveToPoint:_ball1.center];
 //画大圆(第一段的运动轨迹)
 [path1 addArcWithCenter:CGPointMake(R + r, width/2) radius:R startAngle:M_PI endAngle:M_PI*2 clockwise:NO];

2、第二段运动

以灰色小球中心为圆心,以其直径为半径绕小圆,并拼接两段曲线

//画小圆
 UIBezierPath *path1_1 = [UIBezierPath bezierPath];
 //圆心为灰色小球的中心 半径为灰色小球的半径
 [path1_1 addArcWithCenter:CGPointMake(width/2, width/2) radius:r*2 startAngle:M_PI*2 endAngle:M_PI clockwise:NO];
 [path1 appendPath:path1_1];

3、第三段运动

//回到原处
 [path1 addLineToPoint:_ball1.center];

4、位移动画

利用关键帧动画实现小球沿设置好的贝塞尔曲线移动

 //执行动画
 CAKeyframeAnimation *animation1 = [CAKeyframeAnimation animationWithKeyPath:@"position"];
 animation1.path = path1.CGPath;
 animation1.removedOnCompletion = YES;
 animation1.duration = [self animationDuration];
 animation1.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
 [_ball1.layer addAnimation:animation1 forKey:@"animation1"];

5、缩放动画

在每次位移动画开始时执行缩放动画

-(void)animationDidStart:(CAAnimation *)anim{

 CGFloat delay = 0.3f;
 CGFloat duration = [self animationDuration]/2 - delay;

 [UIView animateWithDuration:duration delay:delay options:UIViewAnimationOptionCurveEaseOut| UIViewAnimationOptionBeginFromCurrentState animations:^{
  _ball1.transform = CGAffineTransformMakeScale(ballScale, ballScale);
  _ball2.transform = CGAffineTransformMakeScale(ballScale, ballScale);
  _ball3.transform = CGAffineTransformMakeScale(ballScale, ballScale);
 } completion:^(BOOL finished) {
  [UIView animateWithDuration:duration delay:delay options:UIViewAnimationOptionCurveEaseInOut| UIViewAnimationOptionBeginFromCurrentState animations:^{
   _ball1.transform = CGAffineTransformIdentity;
   _ball2.transform = CGAffineTransformIdentity;
   _ball3.transform = CGAffineTransformIdentity;
  } completion:nil];
 }];
}

6、动画循环

在每次动画结束时从新执行动画

-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
 if (_stopAnimationByUser) {return;}
 [self startPathAnimate];
}

源码下载

github

本地下载

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

时间: 2017-11-01

iOS 实现简单的加载等待动画示例(思路与实现)

先看下最后基本要实现的效果 总结一下自己的实现思路与所用到的类 1.这个肯定是要自定义的View类,起名为XDColorCircle吧,最后用的时候达到这样的效果 //创建XDColorCircle的实例化对象 XDColorCircle *circle=[[XDColorCircle alloc]initWithFrame:CGRectMake(0 ,100,self.view.frame.size.width,200)]; //添加到视图上展示 [self.view addSubview:c

iOS利用CALayer实现动画加载的效果

首先来看看效果图 实现过程如下 控制器调用就一句代码: [self showLoadingInView:self.view]; 方便控制器如此调用,就要为控制器添加一个分类 .h文件 #import <UIKit/UIKit.h> #import "GQCircleLoadView.h" @interface UIViewController (GQCircleLoad) //显示动画 - (void)showLoadingInView:(UIView*)view; //隐

iOS 进度条、加载、安装动画的简单实现

首先看一下效果图: 下面贴上代码: 控制器ViewController: #import <UIKit/UIKit.h> @interface ViewController : UIViewController @end /*** ---------------分割线--------------- ***/ #import "ViewController.h" #import "HWWaveView.h" #import "HWCircleVi

简单实现js进度条加载效果

本文实例为大家分享了js进度条加载效果的具体代码,供大家参考,具体内容如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>下载进度</title> <style> /*定义父容器*/ .content{ width: 500px; height: 200px; background: pin

Android 自定义view实现进度条加载效果实例代码

这个其实很简单,思路是这样的,就是拿view的宽度,除以点的点的宽度+二个点 之间的间距,就可以算出大概能画出几个点出来,然后就通过canvas画出点,再然后就是每隔多少时间把上面移动的点不断的去改变它的坐标就可以, 效果如下: 分析图: 代码如下: package com.example.dotloadview; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bit

python实现文本进度条 程序进度条 加载进度条 单行刷新功能

python实现文本进度条 程序进度条 加载进度条 单行刷新功能,具体内容如下所示: 利用time库来替代某个程序 的进行过程,做实例, 思路是,简单打印出来程序进度 单行刷新关键是\r, python默认是print后换行,所以加一个\r是光标回退到之前位置 import time tm=10 print('{:-^18}'.format('开始')) for i in range(tm+1): a='#'*i b='.'*(tm-i) c=(i/tm)*100 print('\r{:^3.0

网页加载时页面显示进度条加载完成之后显示网页内容

现在网上有很多网页加载进度条 ,但大多都是时间固定的. 下面的当查询大量数据时,网页加载较慢,在网页加载时,显示进度条,当网页加载完成时,进度条消失,显示网页已经加载完成的内容. 复制代码 代码如下: <html> <script language=VBScript> Dim Bar, SP Bar = 0 SP = 100 Function Window_onLoad() Bar = 95 SP = 10 End Function Function Count() if Bar

IOS开发中加载大量网络图片优化方法

IOS开发中加载大量网络图片如何优化 1.概述 在IOS下通过URL读一张网络图片并不像其他编程语言那样可以直接把图片路径放到图片路径的位置就ok,而是需要我们通过一段类似流的方式去加载网络图片,接着才能把图片放入图片路径显示.比如: -(UIImage *) getImageFromURL:(NSString *)fileURL { //NSLog(@"执行图片下载函数"); UIImage * result; NSData * data = [NSData dataWithCont

PHP + plupload.js实现多图上传并显示进度条加删除实例代码

PHP + plupload.js JS插件实现多图上传并显示进度条加删除实例,废话不多说,直接上代码 HTML代码: <!DOCTYPE html> <head> <meta charset="utf-8" /> <meta name="viewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no&qu

IOS中Weex 加载 .xcassets 中的图片资源的实例详解

IOS中Weex 加载 .xcassets 中的图片资源的实例详解 前言: 因为 .xcassets 中的图片资源只能通过 imageNamed: 方法加载,所以需要做一些特殊处理,才能提供给 Weex 使用(PS:纯属娱乐,因为 Weex 跨平台的特性,这种针对某一端做实现的方案实用价值并不大). 方案 观察 WeexSDK 发现有 WXImgLoaderProtocol 这个协议,这个协议包含了下面的方法: - (id<WXImageOperationProtocol>)downloadI

IOS中UIWebView加载Loading的实现方法

第一种方法:使用UIView and UIActivityIndicatorView 复制代码 代码如下: //创建UIWebView WebView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 44, 320, 400)]; [WebView setUserInteractionEnabled:NO]; [WebView setBackgroundColor:[UIColor clearColor]]; [WebView setDelega

Android加载Gif动画实现代码

Android加载Gif动画如何实现?相信大家都很好奇,本文就为大家揭晓,内容如下 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_he