时钟动画

序言

笔者对动画是很钟情的,今天我们一起来学习学习如何通过Core Animation实现钟的秒针、分针和时针无限动画移动,与苹果手机上的世界闹钟中的秒针、分针和时针类似。通过观察,笔者感觉是动画来实现的,而不是定时针。

不过,这里提供了两种方式来实现:

  • 通过定时器实现刷新,与挂钟一样,移动没有动画效果
  • 通过Core Animation实现,与苹果的世界时钟一样,动画均匀地移动

效果图

关于时针、分针和秒针

这里我们为了更轻量一些,直接继承于UIView,而不是UIImageView。将图片直接给layer.contents就可以了,也就没有那么重了。

对于时针、分针和秒针,我们也是直接通过添加layer来实现的。下面的方法是用于生成这三种针的layer的,其中最关键的是设置锚点。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

- (CALayer *)layerWithBackgroundColor:(UIColor *)color size:(CGSize)size {

CALayer *layer = [CALayer layer];

layer.backgroundColor = color.CGColor;

layer.anchorPoint = CGPointMake(0.5, 1);

// 设置为中心

layer.position = CGPointMake(self.frame.size.width / 2, self.frame.size.height / 2);

// 时针、分针、秒针长度是不一样的

layer.bounds = CGRectMake(0, 0, size.width, size.height);

// 加个小圆角

layer.cornerRadius = 4;

[self.layer addSublayer:layer];

return layer;

}

首先,position属性是决定子layer在父layer上的位置,默认为(0,0)。其次,anchorPoint属性是决定子layer上的哪个点会在position所指定的位置。好像很抽象啊,确实也很难理解。当年自觉coco2dx的时候,也是学习了好久才弄明白锚点。

现在,对于我们这里,我们要让position所指定的位置,也就是在时钟的正中间,那么锚点需要设置为(0.5,1)。这样所计算出来的子layer的初始位置(0.5 * layer.bounds.size.width, 1 * layer.bounds.size.height),这也就是我们所设置的正中间了。

如果这段话看不懂,请先阅读上面所推荐的文章,因此这个锚点确实不好理解。但是,要想做好动画,必须要先掌握好锚点与position的关系。

定时器实现

为了更好地说明,直接先上核心代码。下面先看看如何创建时针、分针、秒针:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

- (instancetype)initWithFrame:(CGRect)frame imageName:(NSString *)imageName {

if (self = [super initWithFrame:frame]) {

UIImage *image = [UIImage imageNamed:imageName];

self.layer.contents = (__bridge id _Nullable)(image.CGImage);

// hour layer set up

self.hourLayer = [self layerWithBackgroundColor:[UIColor blackColor]

size:CGSizeMake(3, self.frame.size.width / 2 - 40)];

// 秒针与分针一样长

self.minuteLayer = [self layerWithBackgroundColor:[UIColor blackColor]

size:CGSizeMake(3, self.frame.size.width / 2 - 20)];

self.secondLayer = [self layerWithBackgroundColor:[UIColor redColor]

size:CGSizeMake(1, self.frame.size.width / 2 - 20)];

self.secondLayer.cornerRadius = 0;

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0

target:self

selector:@selector(onTimerUpdate:)

userInfo:nil

repeats:YES];

[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

_timer = timer;

[self updateUI];

}

return self;

}

这里创建了定时器,通过定时器定时地去刷新UI,所以没有动画的过程。下面是更新UI显示的方法,主要是计算这个角度的问题:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

- (void)updateUI {

NSCalendar *calender = [NSCalendar currentCalendar];

NSDateComponents *date = [calender components:NSCalendarUnitSecond

| NSCalendarUnitMinute

| NSCalendarUnitHour

fromDate:[NSDate date]];

NSInteger second = date.second;

NSInteger minute = date.minute;

NSInteger hour = date.hour;

CGFloat perHourMove = 1.0 / 12. * 360.0;

CGFloat hourAngle = hour * perHourMove + minute * (1.0 / 60.0) * perHourMove;

self.hourLayer.transform = CATransform3DMakeRotation(kAngleToRadion(hourAngle), 0, 0, 1);

// 一分钟就是一圈,也就是每秒走度

CGFloat minuteAngle = minute * 360.0 / 60.0;

self.minuteLayer.transform = CATransform3DMakeRotation(kAngleToRadion(minuteAngle), 0, 0, 1);

CGFloat secondAngle = second * 360.0 / 60.0;

self.secondLayer.transform = CATransform3DMakeRotation(kAngleToRadion(secondAngle), 0, 0, 1);

}

  • 每秒钟时针转的度数:1.0 / 12.0 * 360.0,因为一圈有12个小时,共360度,所以一小时就是这么多度
  • 每秒钟分针转的度数:一分钟转一圈,正在是360度,所以每秒分针转360/60度
  • 每秒钟秒针转的度数:60秒转一圈,共360度,所以每秒转360/60度

最后,别忘了在需要的地方调用释放定时器:

1

2

3

[self.clockView releaseTimer];

Core Animation实现时钟

其它代码与上面的采用定时器是差不多的,只是将定时器的部分改成了Core Animation部分:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

// 添加秒针动画

- (void)addSecondAnimationWithAngle:(CGFloat)angle {

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];

animation.repeatCount = HUGE_VALF;

animation.duration = 60;

animation.removedOnCompletion = NO;

animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];

animation.fromValue = @(angle * M_PI / 180);

animation.byValue = @(2 * M_PI);

[self.secondLayer addAnimation:animation forKey:@"SecondAnimationKey"];

}

// 添加分针动画

- (void)addMinuteAnimationWithWithAngle:(CGFloat)angle {

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];

animation.repeatCount = HUGE_VALF;

animation.duration = 60 * 60;

animation.removedOnCompletion = NO;

animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];

animation.fromValue = @(angle * M_PI / 180);

animation.byValue = @(2 * M_PI);

[self.minuteLayer addAnimation:animation forKey:@"MinuteAnimationKey"];

}

// 添加时针动画

- (void)addHourAnimationWithAngle:(CGFloat)angle {

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];

animation.repeatCount = HUGE_VALF;

animation.duration = 60 * 60 * 60 * 12;

animation.removedOnCompletion = NO;

animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];

animation.fromValue = @(angle * M_PI / 180);

animation.byValue = @(2 * M_PI);

[self.hourLayer addAnimation:animation forKey:@"HourAnimationKey"];

}

这里要注意,我们刚开始就可能不是0角度,因此fromValue要从angle开始。另外,我们要保证一圈一圈地转,因此要使用byValue而不是toValue。

如果不太了解Core Animation,推荐大家阅读笔者曾经在公司所进行的一次分享的内容:说说Core Animation,这里会有很多基本的概念及属性说明,也许能帮你快速了解动画。

  • 对于秒针动画:由于我们设置要转一圈,所以需要duration为60秒。
  • 对于分针动画:由于转一圈就是一小时,所以需要duration为60*60秒
  • 对于时针动画:由于转一圈就是12小时,所以需要duration为60*60*60*12秒
时间: 2024-10-20 04:53:24

时钟动画的相关文章

14款超时尚的HTML5时钟动画

时钟动画在网页应用中也非常广泛,在一些个人博客中,我们经常会看到一些相当个性化的HTML5时钟动画.今天我们向大家分享了14款形态各异的超时尚HTML5时钟动画,其中有圆盘时钟.3D时钟.个性化时钟等,强大的HTML5为时钟动画增添了不少精彩,希望能给大家带来帮助. 1.可爱的CSS3圆盘时钟动画 今天要分享的也是一款可爱的CSS3圆盘时钟动画,时钟背景是乳白色的,显得非常干净,另外,时钟也可以和你本地的时候保持同步. 在线演示 源码下载 2.HTML5 SVG圆盘时钟动画 5种时钟样式 今天我

ios开发-UI进阶-核心动画-时钟动画小案例

[注意]转载时请注明出处博客园-吃唐僧肉的小悟空http://www.cnblogs.com/hukezhu/ 今天使用CALayer的"定位点(锚点)"实现了一个时钟动画,其实就是一个小的时钟,只是实现了功能,没有做出绚丽的效果.使用UIView实现的,其实只是单纯的使用layer也可以实现.主要用到了 Quartz2D画图\ 事件处理\核心动画方面的知识. 代码不是很多,直接附上源码,注释比较详细,在源码后面再进行解释其中的一些知识点和注意点. 下图为应用截图,使用gif,没有制作

14款形态各异的超时尚HTML5时钟动画

14款超时尚的HTML5时钟动画(附源码)   时钟动画在网页应用中也非常广泛,在一些个人博客中,我们经常会看到一些相当个性化的HTML5时钟动画.今天我们向大家分享了14款形态各异的超时尚HTML5时钟动画,其中有圆盘时钟.3D时钟.个性化时钟等,强大的HTML5为时钟动画增添了不少精彩,希望能给大家带来帮助. 1.可爱的CSS3圆盘时钟动画 在线演示:http://www.html5tricks.com/demo/css3-circle-clock/index.html 源码下载:http:

iOS中的时钟动画

iOS 动画效果非常多,我们在开发中可能会遇到很多动画特效,我们就会用到核心动画框架CoreAnimation,核心动画里面的动画效果有很多,都是在QuartzCore.framework框架里面,今天我们看看其只一个CADisplayLink使用,并且完成一个雪花效果: 效果图如下: 1.引入框架 2.引入头文件 CADisplayLink最主要的特征是能提供一个周期性的调用我们赋给它的selector的机制,从这点上看它很像定时器NSTimer. CADisplayLink是一个能让我们以和

利用html5制作一个时钟动画

1 <canvas id="clock" width="500" height="500" style="background-color: yellow"></canvas> 1 var clock=document.getElementById("clock"); 2 var cxt=clock.getContext("2d"); 3 function dra

15个超强悍的CSS3圆盘时钟动画赏析

在网页上,特别是个人博客中经常会用到时钟插件,一款个性化的时钟插件不仅可以让页面显得美观,而且可以让访客看到当前的日期和时间.今天我们给大家收集了15个超强悍的圆盘时钟动画,很多都是基于CSS3,也有一部分利用jQuery和SVG,让我们一起来看看吧. 1.纯CSS3/SVG实现的带秒针表盘圆盘复古时钟 现在的网页上圆盘时钟越来越少见了,更多的是数字时钟和数字日历.之前我们分享过一些基于jQuery和CSS3的圆盘时钟动画,比如纯CSS3 3D立体圆盘时钟动画和jQuery实现一个挂在墙上的圆盘

C# WPF 时钟动画(1/2)

微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言, 如果对您有所帮助:欢迎赞赏. C# WPF 时钟动画(1/2) 内容目录 实现效果 业务场景 编码实现 本文参考 源码下载 1.实现效果 目前只实现了秒针动画,下篇文章实现完整效果,可在网站上查看,微信公众号今天只发布了一篇. 效果 2.业务场景 玩具 3.编码实现 工程简单,只更改一个主窗体文件,另加一个时钟背景图片 3.1 主窗体 MainWindow.xaml 布局时钟的时针.分针.秒针,及添加秒针动画,秒针动画写

仿写及比较标哥的iOS时钟动画

一.前言 以前看各种绚丽的UI特效动画代码,采用的方法是会先运行一篇,然后直接去看实现代码.初学时抱着瞻仰的态度去接触,去认识,是没有错的.但是在了解了像素.动画渲染机制,CoreAnimation API,推导过二维.三维的仿射矩阵之后,我们可以改变阅读UI动画博文或者是源码的方式了. Talk is cheap, show me the code——Linus Torvalds. 大量的仿写:一定一定要多写——叶孤城__ 在CodeReview线下大会上的发言. 最近安居客.猿题库.蘑菇街.

使用Quartz2D实现时钟动画(一)

要实现时钟效果,首先将素材表盘拖入工程 1.定义时针.分针.秒针三个图层类成员属性 @property(nonatomic,strong)CALayer *secondLayer; @property(nonatomic,strong)CALayer *minuteLayer; @property(nonatomic,strong)CALayer *hourLayer; 2.建立表盘图层,设置属性,并添加到父view上 // 创建时钟layer 设置属性 CALayer *clockLayer=