Easing圆环动画

效果

源码

https://github.com/YouXianMing/Animations

//
// CircleView.h
// YXMWeather
//
// Created by XianMingYou on 15/11/12.
// Copyright (c) 2015年 XianMingYou. All rights reserved.
// #import <UIKit/UIKit.h>
#import "YXEasing.h" @interface CircleView : UIView /**
* 线条宽度
*/
@property (nonatomic) CGFloat lineWidth; /**
* 线条颜色
*/
@property (nonatomic, strong) UIColor *lineColor; /**
* 旋转方向
*/
@property (nonatomic) BOOL clockWise; /**
* 开始角度
*/
@property (nonatomic) CGFloat startAngle; /**
* 初始化view
*/
- (void)buildView; /**
* 做strokeEnd动画
*
* @param value 取值 [0, 1]
* @param func 函数指针
* @param animated 是否执行动画
* @param duration 动画持续的时间
*/
- (void)strokeEnd:(CGFloat)value animationType:(AHEasingFunction)func animated:(BOOL)animated duration:(CGFloat)duration; /**
* 做strokeStart动画
*
* @param value 取值 [0, 1]
* @param func 函数指针
* @param animated 是否执行动画
* @param duration 动画持续的时间
*/
- (void)strokeStart:(CGFloat)value animationType:(AHEasingFunction)func animated:(BOOL)animated duration:(CGFloat)duration; /**
* 便利构造器创建出实例对象
*
* @param frame frame值
* @param width 线条宽度
* @param color 线条颜色
* @param clockWise 是否是顺时钟
* @param angle 开始是否的角度(取值范围 0° ~ 360°)
*
* @return 实例对象
*/
+ (instancetype)circleViewWithFrame:(CGRect)frame
lineWidth:(CGFloat)width
lineColor:(UIColor *)color
clockWise:(BOOL)clockWise
startAngle:(CGFloat)angle; @end
//
// CircleView.m
// YXMWeather
//
// Created by XianMingYou on 15/11/12.
// Copyright (c) 2015年 XianMingYou. All rights reserved.
// #import "CircleView.h" // 将度数转换为弧度
#define RADIAN(degrees) ((M_PI * (degrees))/ 180.f) // 将弧度转换为度数
#define DEGREES(radian) ((radian) * 180.f / M_PI) @interface CircleView () /**
* 圆形layer
*/
@property (nonatomic, strong) CAShapeLayer *circleLayer; @end @implementation CircleView /**
* 初始化frame值
*
* @param frame 尺寸值
*
* @return 实例对象
*/
- (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { // 创建出layer
[self createCircleLayer];
} return self;
} /**
* 创建出layer
*/
- (void)createCircleLayer { self.circleLayer = [CAShapeLayer layer];
self.circleLayer.frame = self.bounds;
[self.layer addSublayer:self.circleLayer];
} /**
* 初始化view
*/
- (void)buildView { // 初始化信息
CGFloat lineWidth = (self.lineWidth <= ? : self.lineWidth);
UIColor *lineColor = (self.lineColor == nil ? [UIColor blackColor] : self.lineColor);
CGSize size = self.bounds.size;
CGFloat radius = size.width / .f - lineWidth / .f; // 设置半径(刚好贴到frame上面去) // 旋转方向
BOOL clockWise = self.clockWise;
CGFloat startAngle = ;
CGFloat endAngle = ;
if (clockWise == YES) { startAngle = -RADIAN( - self.startAngle);
endAngle = RADIAN( + self.startAngle); } else { startAngle = RADIAN( - self.startAngle);
endAngle = -RADIAN( + self.startAngle);
} // 创建出贝塞尔曲线
UIBezierPath *circlePath \
= [UIBezierPath bezierPathWithArcCenter:CGPointMake(size.height / .f, size.width / .f)
radius:radius
startAngle:startAngle
endAngle:endAngle
clockwise:clockWise]; // 获取path
self.circleLayer.path = circlePath.CGPath; // 设置颜色
self.circleLayer.strokeColor = lineColor.CGColor;
self.circleLayer.fillColor = [[UIColor clearColor] CGColor];
self.circleLayer.lineWidth = lineWidth;
self.circleLayer.strokeEnd = .f;
} - (void)strokeEnd:(CGFloat)value animationType:(AHEasingFunction)func animated:(BOOL)animated duration:(CGFloat)duration { // 过滤掉不合理的值
if (value <= ) { value = ; } else if (value >= ) { value = .f;
} if (animated) { // 关键帧动画
CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animation];
keyAnimation.keyPath = @"strokeEnd";
keyAnimation.duration = duration;
keyAnimation.values = \
[YXEasing calculateFrameFromValue:self.circleLayer.strokeEnd
toValue:value
func:func
frameCount:duration * ]; // 执行动画
self.circleLayer.strokeEnd = value;
[self.circleLayer addAnimation:keyAnimation forKey:nil]; } else { // 关闭动画
[CATransaction setDisableActions:YES];
self.circleLayer.strokeEnd = value;
[CATransaction setDisableActions:NO];
}
} - (void)strokeStart:(CGFloat)value animationType:(AHEasingFunction)func animated:(BOOL)animated duration:(CGFloat)duration { // 过滤掉不合理的值
if (value <= ) { value = ; } else if (value >= ) { value = .f;
} if (animated) { // 关键帧动画
CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animation];
keyAnimation.keyPath = @"strokeStart";
keyAnimation.duration = duration;
keyAnimation.values = \
[YXEasing calculateFrameFromValue:self.circleLayer.strokeStart
toValue:value
func:func
frameCount:duration * ]; // 执行动画
self.circleLayer.strokeStart = value;
[self.circleLayer addAnimation:keyAnimation forKey:nil]; } else { // 关闭动画
[CATransaction setDisableActions:YES];
self.circleLayer.strokeStart = value;
[CATransaction setDisableActions:NO];
}
} + (instancetype)circleViewWithFrame:(CGRect)frame
lineWidth:(CGFloat)width
lineColor:(UIColor *)color
clockWise:(BOOL)clockWise
startAngle:(CGFloat)angle { CircleView *circleView = [[CircleView alloc] initWithFrame:frame];
circleView.lineWidth = width;
circleView.lineColor = color;
circleView.clockWise = clockWise;
circleView.startAngle = angle; return circleView;
} @end

细节

Easing圆环动画的更多相关文章

  1. Swift - EasingAnimation绘制圆环动画

    Swift - EasingAnimation绘制圆环动画 效果 源码 https://github.com/YouXianMing/Swift-Animations // // CircleView ...

  2. Expression Blend实例中文教程(10) - 缓冲动画快速入门Easing

    随着Rich Internet application(RIA)应用技术的发展,各个公司越来越注重于项目的用户体验性,在保证其功能完善,运行稳定的基础上,绚丽的UI和人性化的操作设计会给用户带来舒适的 ...

  3. 前端制作动画的几种方式(css3,js)

    制作动态的网页是是前端工程师必备的技能,很好的实现动画能够极大的提高用户体验,增强交互效果,那么动画有多少实现方式,一直对此有选择恐惧症的我就总结一下,以便在开发的时候选择最好的实现方式. 1.css ...

  4. jQuery动画的实现

    没有引入deferred机制,其余流程都有了 //////////// //创建动画缓动对象 // //////////// function Tween(value, prop, animation ...

  5. jQuery-1.9.1源码分析系列(十五) 动画处理

    首先需要有队列(queue)的基本知识.见上一章. a.动画入口jQuery.fn.animate函数执行流程详解 先根据参数调用jQuery.speed获取动画相关参数,得到一个类似如下的对象:并且 ...

  6. jQuery-1.9.1源码分析系列(十五) 动画处理——缓动动画核心Tween

    在jQuery内部函数Animation中调用到了createTweens()来创建缓动动画组,创建完成后的结果为: 可以看到上面的缓动动画组有四个原子动画组成.每一个原子动画的信息都包含在里面了. ...

  7. 读<jquery 权威指南>[3]-动画

    一. 显示与隐藏——hide(),show() 1. 方法: hide(speed,[callback]); show(speed,[callback]); 说明:这两个方法还可以实现带动画效果的显示 ...

  8. Android 动画 setVisibility 后出错解决方法

    ===先说明下背景. 写的是个ListView 设置 adapter,并在列表末尾显示加载更多,点击 加载更多 时, 变成一个 圆环形的加载动画和 正在加载. 说明下,这个 加载动画是自己做得,一个圆 ...

  9. jQuery系列 第五章 jQuery框架动画特效

    第五章 jQuery框架动画特效 5.1 jQuery动画特效说明 jQuery框架中为我们封装了众多的动画和特效方法,只需要调用对应的动画方法传递合适的参数,就能够方便的实现一些炫酷的效果,而且jQ ...

随机推荐

  1. shell实现增加删除Linux系统用户脚本(密码为随机)

    README shell环境下运行脚本,根据需求选择相应的功能. List \t\t create the userlist 这一步是必须执行的,脚本会识别本地当前目录下的文件 Useradd \t\ ...

  2. 【LOJ】#2290. 「THUWC 2017」随机二分图

    题解 看了一眼觉得是求出图对图统计完美匹配的个数(可能之前做过这样模拟题弃疗了,一直心怀恐惧... 然后说是统计一下每种匹配出现的概率,也就是,当前左边点匹配状态为S,右边点匹配状态为T,每种匹配出现 ...

  3. java.lang.NoClassDefFoundError: javax/persistence/EntityListeners

    在使用 Hibernate 进行数据库操作的时候,在启动 Tomcat 服务器后,Console 控制台可能会打印出这样的异常:java.lang.NoClassDefFoundError: java ...

  4. CentOS 7下安装Python3.6和pip

    一.安装python3.6 1.1.安装python3.6需要依赖包 yum install openssl-devel bzip2-devel expat-devel gdbm-devel read ...

  5. win划分磁盘

    我的电脑-->管理 磁盘管理: 右键压缩卷 输入压缩空间量,进行压缩 右键未分配的磁盘-->新建逻辑卷 选取需要的格式

  6. java 工厂模式和内部类的完美结合

    package com.bikeqx.test; public class Main{ public static void apply(ServiceFactory sf){ Service s = ...

  7. 数据挖掘算法:关联分析二(FP-tree算法)

    三.FP-tree算法 下面介绍一种使用了与Apriori完全不同的方法来发现频繁项集的算法FP-tree.FP-tree算法在过程中没有像Apriori一样产生候选集,而是采用了更为紧凑的数据结构组 ...

  8. MDP中值函数的求解

    MDP概述   马尔科夫决策过程(Markov Decision Process)是强化学习(reinforcement learning)最基本的模型框架.它对序列化的决策过程做了很多限制.比如状态 ...

  9. Linux进程管理子系统

    <进程要素> <进程与程序的区别> 程序: 存放在硬盘上一些列代码和数据的可执行映像,是一个静止的实体 进程: 是一个执行中的程序,是动态的实体 <进程4要素> 1 ...

  10. luoguP2490 [SDOI2011]黑白棋 博弈论 + 动态规划

    博弈部分是自己想出来的,\(dp\)的部分最后出了点差错QAQ 从简单的情况入手 比如\(k = 2\) 如果有这样的局面:$\circ \bullet $,那么先手必输,因为不论先手怎样移动,对手都 ...