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 进度条、加载、安装动画的简单实现

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

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 仿微博客户端红包加载界面 XLDotLoading效果

一.显示效果 二.原理简介 1.思路 要实现这个效果需要先知道这两个硬币是怎样运动的,然后通过放大.缩小的效果实现的这种有距离感的效果.思路如下: 一.这两个硬币是在一定范围内做相对运动的,可以先使一个硬币在一个固定范围内做左右的往复运动,另一个硬币和它做"相对运动"即可. 二.让硬币从左至右移动时先变小再回复正常:从右至左移动时先变大再回复正常:这样就实现了这用有距离感的"相对运动". 2.代码 第一步 要实现一个硬币在一定范围内实现左右往复运动,需要先固定一个范

微信JSSDK多图片上传并且解决IOS系统上传一直加载的问题

微信多图片上传必须挨个上传,也就是不能并行,得串行: 那么我们可以定义一个如下所示的上传函数: var serverIds = []; function uploadImages(localImagesIds) { if (localImagesIds.length === 0) { $.showPreloader('正在提交数据...'); $('form').submit(); } wx.uploadImage({ localId: localImagesIds[0], // 需要上传的图片

iOS开发中用imageIO渐进加载图片及获取exif的方法

imageIO完成渐进加载图片 一.常见渐进加载图片模式   目前我们看到的渐进加载主要有以下三种实现方式:   1)  依次从web上加载不同尺寸的图片,从小到大.最开始先拉取一个小缩略图做拉伸显示,然后拉取中等规格的图,拉取完毕直接覆盖显示,最后拉取原图,拉取完成后显示原图.   2)直接从web上拉取最大的图片,每接受一点儿数据就显示一点儿图片,这样就会实现从上到下一点点刷新出来的效果.   3)结合第1种和第2种,先拉取一个缩略图做拉伸显示,然后采用第二种方法直接拉取原图,这样即可以实现

Android自定义View实现loading动画加载效果

项目开发中对Loading的处理是比较常见的,安卓系统提供的不太美观,引入第三发又太麻烦,这时候自己定义View来实现这个效果,并且进行封装抽取给项目提供统一的loading样式是最好的解决方式了. 先自定义一个View,继承自LinearLayout,在Layout中,添加布局控件 /** * Created by xiedong on 2017/3/7. */ public class Loading_view extends LinearLayout { private Context m

iOS开发中UIWebView的加载本地数据的三种方式

UIWebView是IOS内置的浏览器,可以浏览网页,打开文档 html/htm pdf docx txt等格式的文件. safari浏览器就是通过UIWebView做的. 服务器将MIME的标识符等放入传送的数据中告诉浏览器使用那种插件读取相关文件. uiwebview加载各种本地文件(通过loadData方法): UIWebView加载内容的三种方式: 1 加载本地数据文件 指定文件的MIMEType 编码格式使用@"UTF-8" 2加载html字符串(可以加载全部或者部分html

利用JS实现简单的瀑布流加载图片效果

今天学习了一个瀑布流加载效果,很多网站都有瀑布流效果,瀑布流就是很多产品显示在网页上,宽相同,高度不同,表现为多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部. 原理是: 1.设定一行中的列数: 2.取第一行中每一个div的高度并把每一个高度放进一个数组中: 3.算出数组中最小高度的index值: 4.把第二行的第一个div放到最小高度的div的下方并把重新算出的高度值放进数组中,重新计算最小高度的index值: 5.以此类推实现多栏布局的瀑布流效果: 6.如果最后一

Android使用View Animation实现动画加载界面

之前分别介绍了View Animation和Drawable Animation,学了就要用啊,今天给大家一个使用View Animation实现动画加载界面的实现. 首先先看一下实现效果. 下面是实现代码 package com.example.animationloading; import java.util.Timer; import java.util.TimerTask; import android.annotation.SuppressLint; import android.a

Android框架Volley之利用Imageloader和NetWorkImageView加载图片的方法

首先我们在项目中导入这个框架: implementation 'com.mcxiaoke.volley:library:1.0.19' 在AndroidManifest文件当中添加网络权限: <uses-permission android:name="android.permission.INTERNET"/> 下面是我们的首页布局: 在这个布局当中我们将Volley框架的所有功能都做成了一个按钮,按下按钮之后就会在"显示结果"下面显示结果,显示结果下

vue初始化动画加载的实例

1.在入口文件index.html中加入loading动画: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="renderer" content="webkit|ie-comp|ie-stand"> <meta content="width=device-width, initial-sca