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-08-03 21:29:40

Easing圆环动画的相关文章

Swift - EasingAnimation绘制圆环动画

效果 源码 https://github.com/YouXianMing/Swift-Animations // // CircleView.swift // Swift-Animations // // Created by YouXianMing on 16/8/16. // Copyright © 2016年 YouXianMing. All rights reserved. // import UIKit // MARK: Public class : CircleView class

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

随着Rich Internet application(RIA)应用技术的发展,各个公司越来越注重于项目的用户体验性,在保证其功能完善,运行稳定的基础上,绚丽的UI和人性化的操作设计会给用户带来舒适的体验效果.前文我们学习了Blend设计简单的动画,可以使用StoryBoard快速创建一个动画效果,但是该动画效果看起来缺乏自然效果,让用户感觉太过机械化,大大的降低了用户体验性.为了是动画更为人性化,看起来更自然化,我们可以通过以下两个方式来解决: 方法1. 使用前文所提及的,帧动画技术,为了是动

09.11 jquery04 效果 基本 滑动滑出 淡入淡出 自定义动画 动画操作 工具 浏览器 对象和属性操作核心

# 效果 ### 基本 (width/height/opacity) * show() * hide() * toggle() ### 滑动滑出 (height) * slideUp()       隐藏 * slideDown()  显示 * slideToggle() ### 淡入淡出 * fadeOut()    隐藏 * fadeIn()      显示 * fadeToggle() * fadeTo() 不占用位置 消失之后后面的自动向上移动 ### 自定义动画 * animate(p

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

制作动态的网页是是前端工程师必备的技能,很好的实现动画能够极大的提高用户体验,增强交互效果,那么动画有多少实现方式,一直对此有选择恐惧症的我就总结一下,以便在开发的时候选择最好的实现方式. 1.css的transition. 语法: transition: property duration timing-function delay; property:填写需要变化的css属性如:width,line-height,font-size,color等; duration:完成过渡效果需要的时间(

segment-实现SVG路径描边绘制与动画的轻量库

今天来一起了解一个实现SVG路径描边绘制与动画的轻量级类库segment,我们从轻松上手.使用详解.资源和案例.源码解读等几个方面进行介绍. 1. 轻松上手 html方面添加segment,定义path. <script src="/dist/segment.min.js"></script> <svg> <path id="my-path" ...> </svg> JS方面利用path实例化一个segme

JQuery之动画与特效

学编程吧JQuery之动画与特效发布了,欢迎通过xuebiancheng8.com 显示与隐藏 show(spped,[callback])与hide(spped,[callback]) speed可选填slow.normal.fast,对应的速度分别为600ms.400ms.200ms.也可以直接填毫秒数,callback函数为回调函数,动作完成后调用此函数 [javascript] view plaincopyprint? $("img").show(3000,function()

(生产)create-keyframe-animation -动画实现

参考:https://github.com/HenrikJoreteg/create-keyframe-animation 实例 var animations = require('create-keyframe-animation') 新建动画: animations.registerAnimation({ name: 'move',//动画名称 animation: [ //实现的动画效果 0: {transform: `translate3d(${x}px,${y}px,0) scale(

jQuery复习—用动画和特效装扮页面(队列未整理)

用动画和特效装扮页面 一.显示和隐藏元素 设置元素的style.display属性(none/block/inline) 1.简单的改变元素显示和隐藏 (1).显示 show() (2).隐藏 hide() (3).切换状态 toggle() 2.渐变的显示和隐藏元素 (1).显示 show(speed,callback) (2).隐藏 hide(speed,callback) (3).切换状态 toggle(speed,callback) 参数说明: speed: 数字或者字符串.可以是若干毫

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

dojo学习 (1)加载 ①首先,先设置 <script> //替代使用data-dojo-config,我们创建一个dojoConfig对象(是个设置)在我们调用dojo.js之前,他们功能相同 //这比通过一大堆设置来说,更易阅读 var dojoConfig = { async: true, //这个代码注册了demo包的正确位置,于是我们可以调用dojo从CDN,并且同时还能加载本地模块 packages: [{ name: "demo", location: lo