绘图与动画之使用自定义属性与颜色渐变实现色带加载动画
2015-09-03 14:58
651 查看
基础知识
本书用到的主要技术有自定义属性动画与颜色渐变。自定义属性动画在 绘图与动画系列之使用自定义属性与图像掩膜实现灯泡开关动画一文中已经讲过,这里就不再解释。
颜色渐变
Quartz提供了两种创建颜色渐变的数据类型:CGShadingRef和CGGradientRef,而渐变的种类则分为轴向和径向两种,两种数据类型均可以绘制这两种渐变。本文中用到的是CGGradientRef,创建CGGradientRef需要指定色域、分割点(包含起点和终点)相对位置、对应颜色组成以及分割点数量。
CGGradientRef myGradient; CGColorSpaceRef myColorspace; size_t num_locations = 2; CGFloat locations[2] = { 0.0, 1.0 }; //起点和终点相对位置 CGFloat components[8] = { 1.0, 0.5, 0.4, 1.0, // 起点颜色 0.8, 0.8, 0.3, 1.0 }; // 终点颜色 myColorspace = CGColorSpaceCreateDeviceRGB(); myGradient = CGGradientCreateWithColorComponents (myColorspace, components, locations, num_locations);
轴向渐变
在起点和终点之间画线,颜色会沿着这条线渐变,位于这条线的同一条垂线上的点颜色相同。
创建轴向渐变需要指定起点和终点的坐标,并且可以通过options设置是否绘制超出起点和终点以外的部分。
CGPoint myStartPoint, myEndPoint; myStartPoint.x = 0.0; myStartPoint.y = 0.0; myEndPoint.x = 1.0; myEndPoint.y = 1.0; CGContextDrawLinearGradient (myContext, myGradient, myStartPoint, myEndPoint, 0);
径向渐变
简单来说就是两个圆环之间的渐变,包括点和圆环之间的渐变。
创建径向渐变除了起点和终点坐标以外,还需要起点和终点的半径(以绘制圆环)。
CGPoint myStartPoint, myEndPoint; CGFloat myStartRadius, myEndRadius; myStartPoint.x = 0.15; myStartPoint.y = 0.15; myEndPoint.x = 0.5; myEndPoint.y = 0.5; myStartRadius = 0.1; myEndRadius = 0.25; CGContextDrawRadialGradient (myContext, myGradient, myStartPoint, myStartRadius, myEndPoint, myEndRadius, kCGGradientDrawsAfterEndLocation);
引言
之前曾经看过一个色带加载的动画,大概效果是颜色从左向右循环渐变,于是在此也尝试做一个实现。思路及算法
可以看出,动画的主体由一条渐变色带组成,色带上的颜色从左往右循环运动。实现这种效果需要两个部分:创建渐变色带,定义一个颜色关于时间的周期函数。
本文中的色带包括五个分割点,而其颜色则在(1.0, 0.6, 0, 1.0)至(0.6, 1.0, 0, 1.0)之间变化,也就是red和green始终在0.6到1.0之间。
而颜色组成关于时间的函数则是一个周期函数:
代码实现
首先需要定义一个包含时间属性的CALayer@interface IPZColorLoadLayer : CALayer @property int loadTime; @end
实现自定义属性动画、周期函数及渐变色带绘制
@implementation IPZColorLoadLayer @dynamic loadTime; +(BOOL)needsDisplayForKey:(NSString *)key{ if ([@"loadTime" isEqualToString:key]) { return true; } return [super needsDisplayForKey:key]; } -(id<CAAction>)actionForKey:(NSString *)event{ if ([self presentationLayer]!=nil) { if ([@"loadTime" isEqualToString:event]) { CABasicAnimation *animation=[CABasicAnimation animationWithKeyPath:@"loadTime"]; animation.fromValue=[[self presentationLayer] valueForKey:@"loadTime"]; return animation; } } return [super actionForKey:event]; } -(void)drawInContext:(CGContextRef)ctx{ CGGradientRef myGradient; CGColorSpaceRef myColorspace; size_t num_locations = 5; CGFloat locations[5] = { 0.0,0.25,0.5,0.75, 1.0 }; CGFloat components[20] = {[self getColor:0.6], [self getColor:1.0], 0.0, 1.0, // Start color [self getColor:0.7], [self getColor:0.9], 0.0, 1.0, // Second color [self getColor:0.8], [self getColor:0.8], 0.0, 1.0, // Third color [self getColor:0.9], [self getColor:0.7], 0.0, 1.0, // Fourth color [self getColor:1.0], [self getColor:0.6], 0.0, 1.0, // End color }; myColorspace = CGColorSpaceCreateDeviceRGB(); myGradient = CGGradientCreateWithColorComponents (myColorspace, components,locations, num_locations); CGPoint myStartPoint, myEndPoint; CGRect frame=self.bounds; myStartPoint.x = 0.0; myStartPoint.y = frame.origin.y; myEndPoint.x = frame.size.width; myEndPoint.y = frame.origin.y; CGContextDrawLinearGradient (ctx, myGradient, myStartPoint, myEndPoint, 0); } - (CGFloat)getColor:(CGFloat)originValue{ int offset=self.loadTime % 8 ; int value=originValue*10+offset; if (value>10) { value=10-value%10; } if (value<6) { int origin=originValue *10; value=6+(value -(10-origin))%4; } return value/10.0f; } @end
在view中通过间断赋值实现动画效果。
- (void)drawRect:(CGRect)rect { IPZColorLoadLayer *loadLayer=[IPZColorLoadLayer new]; loadLayer.frame=CGRectMake(rect.origin.x, rect.origin.y+300, rect.size.width, 2); [self.layer addSublayer:loadLayer]; _loadLayer=loadLayer; [NSTimer scheduledTimerWithTimeInterval:0.15 target:self selector:@selector(updateColor:) userInfo:nil repeats:true]; } - (void)updateColor:(id)sender{ _loadTime++; _loadLayer.loadTime=_loadTime;; }
相关文章推荐
- TCP/IP、Http等各层协议汇总表
- ios开发 UI阶段第八周
- android性能优化之SparseArray
- LTE学习:LTE系统中RB、RBG、CCE、REG分别是如何定义的
- NOIP2014联合权值
- 一名程序员的自我修养
- JavaScript-概述
- scanf和gets的几个区别
- Android drawable中xml标签属性
- 小议:SharePoint 2013如何创建与Web Application不同的Host Header Site Collection?
- 为什么网页背景图片都切开
- UINavigationController
- java_servlet字符过滤器filter
- 不相交数据结构
- Java性能优化(8):改写equals时总是要改写hashCode
- Openflow Plugin学习笔记2
- Openflow Plugin学习笔记1
- 再探设计模式之访问者模式
- 当文本溢出包含的元素时加省略号之text-overflow
- J2EE相关总结