Easing圆环动画

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 <= 0 ? 1 : self.lineWidth);
    UIColor *lineColor = (self.lineColor == nil ? [UIColor blackColor] : self.lineColor);
    CGSize   size      = self.bounds.size;
    CGFloat  radius    = size.width / 2.f - lineWidth / 2.f; // 设置半径(刚好贴到frame上面去)

    // 旋转方向
    BOOL clockWise = self.clockWise;
    CGFloat startAngle = 0;
    CGFloat endAngle   = 0;
    if (clockWise == YES) {

        startAngle = -RADIAN(180 - self.startAngle);
        endAngle   = RADIAN(180 + self.startAngle);

    } else {

        startAngle = RADIAN(180 - self.startAngle);
        endAngle   = -RADIAN(180 + self.startAngle);
    }

    // 创建出贝塞尔曲线
    UIBezierPath *circlePath \
        = [UIBezierPath bezierPathWithArcCenter:CGPointMake(size.height / 2.f, size.width / 2.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   = 0.f;
}

- (void)strokeEnd:(CGFloat)value animationType:(AHEasingFunction)func animated:(BOOL)animated duration:(CGFloat)duration {

    // 过滤掉不合理的值
    if (value <= 0) {

        value = 0;

    } else if (value >= 1) {

        value = 1.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 * 60];

        // 执行动画
        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 <= 0) {

        value = 0;

    } else if (value >= 1) {

        value = 1.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 * 60];

        // 执行动画
        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

细节

 

时间: 2024-10-29 12:28:35

Easing圆环动画的相关文章

iOS easing tween 动画效果

在iOS 开发中,要做一个动画效果,我们会用到CAKeyframeAnimation. 这个库提供了一些对frame 动画的控制,什麽是frame 动画? frame 动画就好比电视动画那样,由一格一格的图画(也可以想像成frame)构成, 快速播放图画便成了动画. 在CAKeyframeAnimation 的概念是一样, 你只需要提供keyframe 的信息, 程序会自动完成keyframe之间的"图画". 如果大家有用过adobe flash 这工具, 其实是等同motion/sh

JQuery插件Quicksand实现超炫的动画洗牌效果

  Quicksand这是一个非常不错的 jQuery 插件,用于实现动画洗牌效果,十分的实用,有需要的小伙伴可以参考下. Quicksand是一款基于jQuery的插件,能对页面上的元素进行重新排序及过滤,并且有非常不错的洗牌过渡动画效果,可以应用在很多项目中来增强用户体验.本文以实际项目应用来讲解Quicksand的使用. XHTML ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <div id="nav">    

从零开始学_JavaScript_系列(五)——dojo(基础,动画移动,重力模拟,动画合并,添加标签)

关于dojo的下载,请查看: https://dojotoolkit.org/download/ 建议下载FULL SOURCE版 如果需要讨论,请评论.或者站内信,我会尽快回复.   (1)加载 ①首先,先设置   <script>      //替代使用data-dojo-config,我们创建一个dojoConfig对象(是个设置)在我们调用dojo.js之前,他们功能相同      //这比通过一大堆设置来说,更易阅读         var dojoConfig = {       

支持xcode6的缓动函数Easing以及使用示例

支持xcode6的缓动函数Easing以及使用示例 用xcode6新建工程后,直接导致不支持之前的Easing缓动函数的代码,经过修改后就可以正常使用了,虽然比不上POP高大上的动画,但用缓动函数的动画还是能够实现很复杂的效果的. 注:Easing缓动函数服务于关键帧动画,理解这一点很重要,需要你对CoreAnimation有着很深入的了解才能够用得得心应手 提供源码如下: Easing.h 与 Easing.m // // Easing.h // Easing // // Created by

jQuery 1.9.1源码分析系列(十五)动画处理之缓动动画核心Tween_jquery

在jQuery内部函数Animation中调用到了createTweens()来创建缓动动画组,创建完成后的结果为: 可以看到上面的缓动动画组有四个原子动画组成.每一个原子动画的信息都包含在里面了. 仔细查看createTweens函数,实际上就是遍历调用了tweeners ["*"]的数组中的函数(实际上就只有一个元素). function createTweens( animation, props ) { jQuery.each( props, function( prop, v

jQuery 1.9.1源码分析系列(十五)之动画处理_jquery

首先需要有队列(queue)的基本知识.见上一章. 相关教程:jQuery下的动画处理总结: http://www.jb51.net/article/42000.htm jQuery 1.9.1源码分析系列(十五)动画处理之缓动动画核心Tween  :http://www.jb51.net/article/75821.htm a.动画入口jQuery.fn.animate函数执行流程详解 ------------------------------------------------------

JQuery动画与特效实例分析_jquery

本文实例分析了JQuery动画与特效的用法.分享给大家供大家参考.具体分析如下: 显示与隐藏 show(spped,[callback])与hide(spped,[callback]) speed可选填slow.normal.fast,对应的速度分别为600ms.400ms.200ms.也可以直接填毫秒数,callback函数为回调函数,动作完成后调用此函数 $("img").show(3000,function(){ $(this).css("border",&q

Android实现动态圆环的图片头像控件_Android

先看效果图: 现在大部分的app上难免会使用到圆形头像,所以今天我给大家分享一个单独使用的,并且周围带有圆环动画的花哨圆形头像控件,本控件是在圆形头像控件基础上实现的,只是在其周围再画一些不同大小的圆而已,就可以实现如图的效果. 圆形头像的基本原理是将设置的资源文件转化成Bitmap,然后通过BitmapShader类将Bitmap成为Paint的渲染器,然后在onDraw()中通过canvas.drawCircle(rx,ry,radius,paint);画布上画圆,而这个圆就是形成了圆形头像

Android实现动态圆环的图片头像控件

先看效果图: 现在大部分的app上难免会使用到圆形头像,所以今天我给大家分享一个单独使用的,并且周围带有圆环动画的花哨圆形头像控件,本控件是在圆形头像控件基础上实现的,只是在其周围再画一些不同大小的圆而已,就可以实现如图的效果. 圆形头像的基本原理是将设置的资源文件转化成Bitmap,然后通过BitmapShader类将Bitmap成为Paint的渲染器,然后在onDraw()中通过canvas.drawCircle(rx,ry,radius,paint);画布上画圆,而这个圆就是形成了圆形头像