变换CALayer锚点实现模拟时钟的动画

简介:

变换CALayer锚点实现模拟时钟的动画

 

变换锚点得需要一点理论知识,看下图就能明白:).

https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreAnimation_guide/CoreAnimationBasics/CoreAnimationBasics.html#//apple_ref/doc/uid/TP40004514-CH2-SW15

开始实现模拟时钟效果:

//
//  RootViewController.m
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "RootViewController.h"
#import "YXGCD.h"

@interface RootViewController ()

@property (nonatomic, strong) GCDTimer *timer;

@end

// 将角度转换为弧度
#define DEGREES__TO__RADIANS(d)  ((d) * M_PI / 180.f)

@implementation RootViewController


- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // 显示参考用的view
    UIView *showView = [[UIView alloc] initWithFrame:CGRectMake(0, 20, 300, 300)];
    showView.layer.borderWidth = 1.f;
    showView.layer.cornerRadius = 150.f;
    showView.layer.borderColor = [UIColor redColor].CGColor;
    showView.center = self.view.center;
    [self.view addSubview:showView];
    
    // 新建layer
    CALayer *layer = [CALayer layer];
    layer.backgroundColor = [UIColor blackColor].CGColor;
    
    // 重置锚点
    layer.anchorPoint = CGPointMake(0.f, 0.f);
    
    // 设置layer的frame值(在showView正中间摆放)
    layer.frame = CGRectMake(showView.middleX, showView.middleY, 1, 150);
    
    // 添加进showView中
    [showView.layer addSublayer:layer];
    
    // 定时器
    _timer = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]];
    [_timer event:^{
        static int i = 1;
        
        // 每秒增加的角度
        layer.transform = \
            CATransform3DMakeRotation(DEGREES__TO__RADIANS((360/60.f) * i++), 0.0, 0.0, 1.0);
    } timeInterval:NSEC_PER_SEC];
    [_timer start];
}


@end

 

重要的代码:

以下是最终效果:

完整代码:

//
//  RootViewController.m
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "RootViewController.h"
#import "YXGCD.h"

static NSDateFormatter* _DMLogDateFormatter = nil;

@interface RootViewController ()

@property (nonatomic, strong) GCDTimer *timer;
@property (nonatomic, strong) UILabel  *timeLabel;

@end

// 将角度转换为弧度
#define DEGREES__TO__RADIANS(d)  ((d) * M_PI / 180.f)

@implementation RootViewController


- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor blackColor];
    
    // 日期格式
    _DMLogDateFormatter = [[NSDateFormatter alloc] init];
    [_DMLogDateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]];
    [_DMLogDateFormatter setDateFormat:@"HH:mm:ss"];
    
    // 显示label
    _timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 30)];
    _timeLabel.textAlignment = NSTextAlignmentCenter;
    _timeLabel.font = [UIFont fontWithName:@"HelveticaNeue-Thin" size:29.f];
    _timeLabel.textColor = [UIColor cyanColor];
    _timeLabel.center = self.view.center;
    _timeLabel.y += 190;
    [self.view addSubview:_timeLabel];
    
    // 显示参考用的view
    UIView *showView = [[UIView alloc] initWithFrame:CGRectMake(0, 20, 300, 300)];
    showView.layer.borderWidth = 1.f;
    showView.layer.cornerRadius = 150.f;
    showView.layer.borderColor = [UIColor redColor].CGColor;
    showView.center = self.view.center;
    [self.view addSubview:showView];
    
    // 新建秒钟Layer
    // ----------------------------------------------------- //
    CALayer *secondLayer = [CALayer layer];
    secondLayer.backgroundColor = [UIColor whiteColor].CGColor;
    
    // 重置锚点
    secondLayer.anchorPoint = CGPointMake(0.f, 0.f);
    
    // 设置layer的frame值(在showView正中间摆放)
    secondLayer.frame = CGRectMake(showView.middleX, showView.middleY, 1, 140);
    
    // 添加进showView中
    [showView.layer addSublayer:secondLayer];
    
    
    // 新建分钟Layer
    // ----------------------------------------------------- //
    CALayer *minuteLayer = [CALayer layer];
    minuteLayer.backgroundColor = [UIColor greenColor].CGColor;
    
    // 重置锚点
    minuteLayer.anchorPoint = CGPointMake(0.f, 0.f);
    
    // 设置layer的frame值(在showView正中间摆放)
    minuteLayer.frame = CGRectMake(showView.middleX, showView.middleY, 1, 120);
    
    // 添加进showView中
    [showView.layer addSublayer:minuteLayer];
    
    
    // 新建时钟Layer
    // ----------------------------------------------------- //
    CALayer *hourLayer = [CALayer layer];
    hourLayer.backgroundColor = [UIColor blueColor].CGColor;
    
    // 重置锚点
    hourLayer.anchorPoint = CGPointMake(0.f, 0.f);
    
    // 设置layer的frame值(在showView正中间摆放)
    hourLayer.frame = CGRectMake(showView.middleX, showView.middleY, 1, 100);
    
    // 添加进showView中
    [showView.layer addSublayer:hourLayer];
    
    
    // 定时器
    _timer = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]];
    [_timer event:^{
        
        NSString *timerNow = [_DMLogDateFormatter stringFromDate:[NSDate date]];
        NSArray *timeArray = [timerNow componentsSeparatedByString:@":"];

        // 获取到时间
        float sec =  [timeArray[2] intValue];
        float min =  [timeArray[1] intValue] + sec / 60.f;
        float hour = [timeArray[0] intValue] + min / 60.f;
        
        secondLayer.transform = \
            CATransform3DMakeRotation(DEGREES__TO__RADIANS(360/60.f)*sec + \
                                      DEGREES__TO__RADIANS(180), \
                                      0.0, 0.0, 1.0);
        
        minuteLayer.transform = \
        CATransform3DMakeRotation(DEGREES__TO__RADIANS(360/60.f)*min + \
                                  DEGREES__TO__RADIANS(180), \
                                  0.0, 0.0, 1.0);
        
        hourLayer.transform = \
        CATransform3DMakeRotation(DEGREES__TO__RADIANS(360/24.f)*hour + \
                                  DEGREES__TO__RADIANS(360), \
                                  0.0, 0.0, 1.0);
        
        _timeLabel.text = [NSString stringWithFormat:@"%02d:%02d:%02d",
                           [timeArray[0] intValue],
                           [timeArray[1] intValue],
                           [timeArray[2] intValue]];
        
    } timeInterval:NSEC_PER_SEC];
    [_timer start];
}


@end

RootViewController.m

目录
相关文章
|
8月前
UE4 动画蓝图中两类动画曲线的使用
UE4 动画蓝图中两类动画曲线的使用
79 1
UE4 动画蓝图中两类动画曲线的使用
|
8月前
|
前端开发
canvas正交坐标系旋转--监听滚轮
canvas正交坐标系旋转--监听滚轮
63 0
|
10月前
|
前端开发 JavaScript
【Three.js入门】渲染第一个场景及物体(轨道控制器、坐标轴辅助器、移动缩放旋转)
【Three.js入门】渲染第一个场景及物体(轨道控制器、坐标轴辅助器、移动缩放旋转)
202 0
|
12月前
|
移动开发 前端开发 Shell
使用canvas绘制时钟
使用canvas绘制时钟
59 0
|
前端开发
canvas炫酷转盘时钟
canvas炫酷转盘时钟,拿来即用
47 0
canvas炫酷转盘时钟
An动画基础之元件的图形动画与按钮动画
An动画基础之元件的图形动画与按钮动画
211 0
An动画基础之元件的图形动画与按钮动画
An动画基础之散件动画原理与形状提示点
An动画基础之散件动画原理与形状提示点
674 0
An动画基础之散件动画原理与形状提示点
|
JavaScript 前端开发 算法
html+css+JavaScript实现简洁的圆形时钟数字时钟+指针时钟
使用前端三件套实现一个实时跟新的时钟,其中包括电子时钟和刻度时钟
234 0
html+css+JavaScript实现简洁的圆形时钟数字时钟+指针时钟
鼠标控制物体旋转、移动、缩放(Unity3D)
Unity3D对于鼠标操作物体的旋转、移动、缩放的功能点使用的比较多。 今天就分享如何使用Unity实现鼠标对于物体的旋转、移动、缩放。