POP按钮动画

简介:

POP按钮动画

 

效果

 

源码

https://github.com/YouXianMing/Animations


//
//  ButtonPressViewController.m
//  Facebook-POP-Animation
//
//  Created by YouXianMing on 15/11/16.
//  Copyright © 2015年 ZiPeiYi. All rights reserved.
//

#import "ButtonPressViewController.h"
#import "POP.h"
#import "UIColor+CustomColors.h"
#import "StrokeCircleLayerConfigure.h"
#import "FillCircleLayerConfigure.h"
#import "GCD.h"

@interface ButtonPressViewController ()

@property (nonatomic, strong) UIButton          *button;
@property (nonatomic, strong) CAShapeLayer      *circleShape1;
@property (nonatomic, strong) CAShapeLayer      *circleShape2;

@property (nonatomic, strong) UILabel           *label;

@end

@implementation ButtonPressViewController

- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    [self setup];
}

#pragma mark - setup
- (void)setup {
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    // 完整显示按住按钮后的动画效果
    _button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    _button.layer.cornerRadius = 50.f;
    _button.backgroundColor = [UIColor cyanColor];
    _button.center = self.view.center;
    [self.view addSubview:_button];
    
    self.label               = [[UILabel alloc] initWithFrame:_button.bounds];
    self.label.font          = Font_HYQiHei(30);
    self.label.textAlignment = NSTextAlignmentCenter;
    self.label.text          = @"0%";
    [self.button addSubview:self.label];
    
    // 按住按钮后没有松手的动画
    [_button addTarget:self
                action:@selector(scaleToSmall)
      forControlEvents:UIControlEventTouchDown | UIControlEventTouchDragEnter];
    
    // 按住按钮松手后的动画
    [_button addTarget:self
                action:@selector(scaleAnimations)
      forControlEvents:UIControlEventTouchUpInside];
    
    // 按住按钮后拖拽出去的动画
    [_button addTarget:self
                action:@selector(scaleToDefault)
      forControlEvents:UIControlEventTouchDragExit];
    
    // 圆环1
    {
        self.circleShape1 = [CAShapeLayer layer];
        self.circleShape1.strokeEnd = 0.f;
        StrokeCircleLayerConfigure *config = [StrokeCircleLayerConfigure new];
        config.lineWith     = 0.5f;
        config.startAngle   = 0;
        config.endAngle     = M_PI * 2;
        config.radius       = 55.f;
        config.circleCenter = self.view.center;
        [config configCAShapeLayer:self.circleShape1];
        [self.view.layer addSublayer:self.circleShape1];
    }
    
    // 圆环2
    {
        self.circleShape2 = [CAShapeLayer layer];
        self.circleShape2.strokeEnd = 0.f;
        StrokeCircleLayerConfigure *config = [StrokeCircleLayerConfigure new];
        config.lineWith     = 0.5f;
        config.startAngle   = 0;
        config.endAngle     = M_PI * 2;
        config.radius       = 60.f;
        config.clockWise    = YES;
        config.circleCenter = self.view.center;
        [config configCAShapeLayer:self.circleShape2];
        [self.view.layer addSublayer:self.circleShape2];
    }
}

#pragma mark - Button events
- (void)scaleToSmall {
    
    [_button.layer pop_removeAllAnimations];
    
    // 变小尺寸
    POPBasicAnimation *scaleAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
    scaleAnimation.toValue            = [NSValue valueWithCGSize:CGSizeMake(0.7f, 0.7f)];
    scaleAnimation.delegate           = self;
    [_button.layer pop_addAnimation:scaleAnimation forKey:nil];
    
    // 颜色
    POPSpringAnimation *backgroundColor = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerBackgroundColor];
    backgroundColor.toValue             = (id)[UIColor magentaColor].CGColor;
    [_button.layer pop_addAnimation:backgroundColor forKey:@"magentaColor"];
}

- (void)scaleAnimations {
    
    [_button.layer pop_removeAllAnimations];
    
    // 恢复尺寸
    POPBasicAnimation *scaleAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
    scaleAnimation.toValue            = [NSValue valueWithCGSize:CGSizeMake(1.f, 1.f)];
    scaleAnimation.delegate           = self;
    [_button.layer pop_addAnimation:scaleAnimation forKey:nil];
    
    // 颜色
    POPSpringAnimation *backgroundColor = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerBackgroundColor];
    backgroundColor.toValue             = (id)[UIColor cyanColor].CGColor;
    [_button.layer pop_addAnimation:backgroundColor forKey:nil];
}

- (void)scaleToDefault{
    
    [_button.layer pop_removeAllAnimations];
    
    // 恢复尺寸
    POPBasicAnimation *scaleAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
    scaleAnimation.toValue            = [NSValue valueWithCGSize:CGSizeMake(1.f, 1.f)];
    scaleAnimation.delegate           = self;
    [_button.layer pop_addAnimation:scaleAnimation forKey:nil];
    
    // 颜色
    POPSpringAnimation *backgroundColor = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerBackgroundColor];
    backgroundColor.toValue             = (id)[UIColor cyanColor].CGColor;
    [_button.layer pop_addAnimation:backgroundColor forKey:nil];
}

#pragma mark - POP delegate
- (void)pop_animationDidStart:(POPAnimation *)anim {

    NSLog(@"pop_animationDidStart %@", anim);
}

- (void)pop_animationDidReachToValue:(POPAnimation *)anim {

    NSLog(@"pop_animationDidReachToValue %@", anim);
}

- (void)pop_animationDidStop:(POPAnimation *)anim finished:(BOOL)finished {

    NSLog(@"pop_animationDidStop %@", anim);
    
}

- (void)pop_animationDidApply:(POPAnimation *)anim {

    NSLog(@"pop_animationDidApply %@", anim);
    
    NSValue *toValue = (NSValue *)[anim valueForKeyPath:@"currentValue"];
    CGSize size      = [toValue CGSizeValue];
    
    CGFloat percent         = (size.height - calculateConstant(0, 1, 1, 0.7))/calculateSlope(0, 1, 1, 0.7);
    _circleShape1.strokeEnd = percent;
    _circleShape2.strokeEnd = percent;

    double showValue = fabs(percent * 100);
    self.label.text  = [NSString stringWithFormat:@"%.f%%", showValue];
}

#pragma mark - Y = kX + b
CGFloat calculateSlope(CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2) {
    
    return (y2 - y1) / (x2 - x1);
}

CGFloat calculateConstant(CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2) {
    
    return (y1*(x2 - x1) - x1*(y2 - y1)) / (x2 - x1);
}

@end

细节

处理好POP动画的代理即可.


目录
相关文章
|
6月前
screenfull全屏、退出全屏、指定元素全屏的使用步骤
screenfull全屏、退出全屏、指定元素全屏的使用步骤
382 5
UG01---NX10头部是标题栏 ,界面认识,进入全屏点击右下角,继续点击就退出了
UG01---NX10头部是标题栏 ,界面认识,进入全屏点击右下角,继续点击就退出了
|
6月前
|
JavaScript
vue 全屏 screenfull —— 整页全屏,指定元素全屏,退出全屏,全屏切换等
vue 全屏 screenfull —— 整页全屏,指定元素全屏,退出全屏,全屏切换等
615 0
|
6月前
|
前端开发 JavaScript
js 进入浏览器全屏(F11效果)、退出全屏、指定元素全屏、判断当前是否全屏、监听浏览器全屏事件、定义全屏时的css样式(全屏伪类)
js 进入浏览器全屏(F11效果)、退出全屏、指定元素全屏、判断当前是否全屏、监听浏览器全屏事件、定义全屏时的css样式(全屏伪类)
649 0
|
8月前
在viewWillAppear函数中禁止左滑,viewWillDisappear开启左滑动产生进入下一个页面来回滑动造成无法点击点击按钮问题
在viewWillAppear函数中禁止左滑,viewWillDisappear开启左滑动产生进入下一个页面来回滑动造成无法点击点击按钮问题
41 0
|
8月前
让元素沾满全屏
让元素沾满全屏
40 0
|
移动开发 前端开发
H5页面,使用cursor: pointer;出现的问题:点击元素时,相邻元素或者自身背景色闪烁.
H5页面,使用cursor: pointer;出现的问题:点击元素时,相邻元素或者自身背景色闪烁.
全屏了却判断为未全屏(已解决)
全屏了却判断为未全屏(已解决)
|
存储 图形学
|
JavaScript 开发者
动画-使用 transition-group 元素实现列表动画|学习笔记
快速学习动画-使用 transition-group 元素实现列表动画
154 0
动画-使用 transition-group 元素实现列表动画|学习笔记

热门文章

最新文章