变换CALayer锚点实现模拟时钟的动画
变换CALayer锚点实现模拟时钟的动画
变换锚点得需要一点理论知识,看下图就能明白:).
开始实现模拟时钟效果:
//
// 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(, , , )];
showView.layer.borderWidth = .f;
showView.layer.cornerRadius = .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(.f, .f); // 设置layer的frame值(在showView正中间摆放)
layer.frame = CGRectMake(showView.middleX, showView.middleY, , ); // 添加进showView中
[showView.layer addSublayer:layer]; // 定时器
_timer = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]];
[_timer event:^{
static int i = ; // 每秒增加的角度
layer.transform = \
CATransform3DMakeRotation(DEGREES__TO__RADIANS((/.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(, , , )];
_timeLabel.textAlignment = NSTextAlignmentCenter;
_timeLabel.font = [UIFont fontWithName:@"HelveticaNeue-Thin" size:.f];
_timeLabel.textColor = [UIColor cyanColor];
_timeLabel.center = self.view.center;
_timeLabel.y += ;
[self.view addSubview:_timeLabel]; // 显示参考用的view
UIView *showView = [[UIView alloc] initWithFrame:CGRectMake(, , , )];
showView.layer.borderWidth = .f;
showView.layer.cornerRadius = .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(.f, .f); // 设置layer的frame值(在showView正中间摆放)
secondLayer.frame = CGRectMake(showView.middleX, showView.middleY, , ); // 添加进showView中
[showView.layer addSublayer:secondLayer]; // 新建分钟Layer
// ----------------------------------------------------- //
CALayer *minuteLayer = [CALayer layer];
minuteLayer.backgroundColor = [UIColor greenColor].CGColor; // 重置锚点
minuteLayer.anchorPoint = CGPointMake(.f, .f); // 设置layer的frame值(在showView正中间摆放)
minuteLayer.frame = CGRectMake(showView.middleX, showView.middleY, , ); // 添加进showView中
[showView.layer addSublayer:minuteLayer]; // 新建时钟Layer
// ----------------------------------------------------- //
CALayer *hourLayer = [CALayer layer];
hourLayer.backgroundColor = [UIColor blueColor].CGColor; // 重置锚点
hourLayer.anchorPoint = CGPointMake(.f, .f); // 设置layer的frame值(在showView正中间摆放)
hourLayer.frame = CGRectMake(showView.middleX, showView.middleY, , ); // 添加进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[] intValue];
float min = [timeArray[] intValue] + sec / .f;
float hour = [timeArray[] intValue] + min / .f; secondLayer.transform = \
CATransform3DMakeRotation(DEGREES__TO__RADIANS(/.f)*sec + \
DEGREES__TO__RADIANS(), \
0.0, 0.0, 1.0); minuteLayer.transform = \
CATransform3DMakeRotation(DEGREES__TO__RADIANS(/.f)*min + \
DEGREES__TO__RADIANS(), \
0.0, 0.0, 1.0); hourLayer.transform = \
CATransform3DMakeRotation(DEGREES__TO__RADIANS(/.f)*hour + \
DEGREES__TO__RADIANS(), \
0.0, 0.0, 1.0); _timeLabel.text = [NSString stringWithFormat:@"%02d:%02d:%02d",
[timeArray[] intValue],
[timeArray[] intValue],
[timeArray[] intValue]]; } timeInterval:NSEC_PER_SEC];
[_timer start];
} @end
RootViewController.m
变换CALayer锚点实现模拟时钟的动画的更多相关文章
- 【CSS3】纯CSS代码实现模拟时钟,+js对时功能。
使用CSS3纯代码来实现模拟时钟,及指针动画功能. 在这里主要使用到css3一些基本元素: border-radius:圆角边框,画圆形:表盘 Transform:变换,旋转,扭曲:刻度盘,指针形状 ...
- 模拟时钟(AnalogClock)和数字时钟(DigitalClock)
Demo2\clock_demo\src\main\res\layout\activity_main.xml <LinearLayout xmlns:android="http://s ...
- 一个模拟时钟的时间选择器 ClockPicker
最近开发的一个模拟时钟的时间选择器 ClockPicker,用于 Bootstrap,或者单独作为一个 jQuery 插件. 源代码托管在 GitHub 上: ClockPicker 最近项目中需要用 ...
- android脚步---数字时钟和模拟时钟
时钟UI组件是两个非常简单的组件,分为Digitalclock 和Analogclock, main.xml文件,书中程序有问题,加了两个组件,一个Button和一个<Chronometer ...
- Java多线程之sleep方法阻塞线程-模拟时钟
package org.study2.javabase.ThreadsDemo.status; import java.text.SimpleDateFormat; import java.util. ...
- css模拟时钟
css模拟时钟 思路: 画时钟数字(x,y)坐标 x = x0 + r*cos(deg) y = y0 + r*sin(deg) 知识点: 创建元素: createElement 添加元素: appe ...
- 模拟时钟(AnalogClock)
模拟时钟(AnalogClock) 显示一个带时钟和分针的表面 会随着时间的推移变化 常用属性: android:dial 可以为表面提供一个自定义的图片 下面我们直接看代码: 1.Activity ...
- Windows下编程--模拟时钟的实现
windows下编程--模拟时钟的实现: 主要可以分为几个步骤: (1) 编写按键事件处理(启动和停止时钟) (2) 编写时钟事件处理,调用显示时钟函数 (3) 编写显示时钟函数,要调用显 ...
- VC++SDK编程——模拟时钟
#include <Windows.h> #include <tchar.h> #include <math.h> typedef struct Time { in ...
随机推荐
- MarkDown编辑使用指南
MarkDown Markdown是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式. 区块元素 标题title # h1 ## h2 ### h3 # ...
- teleport助手不可以使用剪切板的问题解决
在使用teleport堡垒机的时候,你使用teleport助手会发现不可以使用剪切板,接下来就是解决方法. 解决办法:更新freerdp 基于环境:win10(win7下更新好像没有用),telepo ...
- PHP中return,exit,die的区别
参考:die(),exit(),return的区别 1.die() 是遇到错误才停止,停止程序运行,输出内容(是程序级别的) 2.exit,exit():是一个函数 是停止程序运行,前者不输出内容:后 ...
- eclipse下JAVA的搭建
练手JAVA用eclipse比android studio快很多,android studio啥都好,就是太慢 参考资料:http://blog.csdn.net/21aspnet/article/d ...
- audio标签的自动播放(ios)
0.应用场景 前端移动端开发,经常有播放音乐的需求.比如我有公司做过类似支付宝的年度账单,功能是用户在查看年度账单的过程中播放轻音乐. 1.audio标签播放mp3 (一)常用属性和API介绍 1.c ...
- 从0开始整合SSM框架--2.spring整合mybatis
依赖:<properties> <!-- spring版本号 --> <spring.version>4.1.3.RELEASE</spring.versio ...
- 【C#高级】泛型(一)
泛型,.net 2.0之后出现,基本只要代码中出现 ‘<>’ 尖括号就可以确定是泛型. 在2.0之前大多是使用Object来代替,因为所有类都是Object的派生类,根据继承的原理Obje ...
- J2EE的体系架构
J2EE是Java2平台企业版(Java 2 Platform,Enterprise Edition),它的核心是一组技术规范与指南,提供基于组件的方式来设计.开发.组装和部署企业应用.J2EE使用多 ...
- 过滤网址和输入框中的特殊字符,防止sql注入
using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Secu ...
- C# 之构造函数
构造函数是一种特殊的成员函数,它主要用于为对象分配存储空间,对数据成员进行初始化. 构造函数具有一些特殊的性质: (1)构造函数的名字必须与类同名; (2)构造函数没有返回类型,它可以带参数,也可以不 ...