(Shadow,Gradient)
Shadow
shadow(阴影)的目的是为了使UI更具有立体感,如图
shadow主要有三个影响因素
- x off-set 决定阴影沿着x的偏移量
- y off-set 决定阴影沿着y的偏移量
- blur value 决定了阴影的边缘区域是不是模糊的
其中不同的blur效果如图
注意
Shadow也是绘制状态相关的,意味着如果仅仅要绘制一个subpath的shadow,要注意save和restore状态。
相关函数
CGContextSetShadow
CGContextSetShadowWithColor//位移区别是设置了阴影颜色
- 1
- 2
- 1
- 2
参数
- context 绘制画板
- offset 阴影偏移量,参考context的坐标系
- blur 非负数,决定阴影的模糊程度
示例代码
- (void)drawRect:(CGRect)rect {CGContextRef context = UIGraphicsGetCurrentContext();CGContextAddArc(context,40, 40, 20, 0,M_2_PI,0);CGContextSetLineCap(context, kCGLineCapRound);CGContextSetLineWidth(context,3.0);CGContextSetShadow(context,CGSizeMake(4.0, 4.0),1.0);CGContextStrokePath(context);
}
-(instancetype)initWithFrame:(CGRect)frame{if(self = [super initWithFrame:frame]){self.opaque = NO;self.layer.borderColor = [UIColor lightGrayColor].CGColor;self.layer.borderWidth = 1.0;}return self;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
效果
关于状态保存会在最后和gradient一起再讲解一次
Gradient
渐变无非就是从一种颜色逐渐变换到另一种颜色,quart提供了两种渐变模型。
axial gradient,线性渐变,使用的时候设置好两个顶点的颜色(也可以设置中间过渡色)
例如
只设置两个颜色,和顶点
设置中间过渡色
radial gradient
这种模式的渐变允许,一个圆到另一个圆的渐变
一个点到一个圆的渐变
注意,可以对渐变结束或者开始的额外区域使用指定颜色填充
,效果
通过这两种渐变的嵌套使用,Quartz 2D能够绘制出非常漂亮的图形
渐变的两种绘制模型
- CGShading - 使用这种数据类型需要自己定义CFFunction来计算每一个点的渐变颜色,较为复杂,但是能够更灵活的绘制。
- CGGradient- 使用这种数据类型只需要制定两个顶点的颜色,以及绘制模式,其余的Quartz会给绘制,但是渐变的数学模型不灵活。
CGGradient的例子
使用步骤
- 创建一个CGGradient对象,指定颜色域(一般就是RGB),指定颜色变化的数组,指定对应颜色位置的数组,指定每个数组数据的个数
- 用CGContextDrawLinearGradient或者CGContextDrawRadialGradient绘制
- 释放CGGradient对象
代码
CGContextRef context = UIGraphicsGetCurrentContext();//用CGGradient绘制CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();size_t num_of_locations = 2;CGFloat locations[2] = {0.0,1.0};CGFloat components[8] = {1.0, 0.0, 0.0, 1.0, // 红色0.0, 1.0, 0.0, 1.0};//绿色CGGradientRef gradient = CGGradientCreateWithColorComponents(deviceRGB, components, locations,num_of_locations);CGPoint startPoint = CGPointMake(0, 0);CGPoint endPoint = CGPointMake(100, 100);CGContextDrawLinearGradient(context,gradient,startPoint, endPoint,0);CGColorSpaceRelease(deviceRGB);CGGradientRelease(gradient);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
效果
然后,我们绘制一个RadialGradient,
代码
CGContextRef context = UIGraphicsGetCurrentContext();//用CGGradient绘制CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();size_t num_of_locations = 2;CGFloat locations[2] = {0.0,1.0};CGFloat components[8] = {1.0, 1.0, 1.0, 1.0, // 白色0.0, 0.0, 0.0, 1.0};//黑色CGGradientRef gradient = CGGradientCreateWithColorComponents(deviceRGB, components, locations,num_of_locations);CGPoint startCenter = CGPointMake(30, 30);CGPoint endCenter = CGPointMake(50, 50);CGFloat startRadius = 0.0;CGFloat endRadius = 40.0;CGContextDrawRadialGradient(context,gradient, startCenter,startRadius, endCenter, endRadius, 0);CGColorSpaceRelease(deviceRGB);CGGradientRelease(gradient);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
效果
CGShading绘制
使用CGShadingCreateAxial或者CGShadingCreateRadial来创建对象,传入的参数如下
- Color Space,处理的颜色域,在iOS通畅就是device RGB
- 开始的点和结束的点
- 对于 radial gradient要传入开始和结束的半径
- CGFunction 对象来计算每个点的显示值
- 一个bool值,来确定是否要填充没有被渐变覆盖的区域
这里面最复杂的就是创建一个CGFunction对象,使用CGFunctionCreate
来创建,我们线看看这个函数
CGFunctionRef _Nullable CGFunctionCreate (void * _Nullable info,size_t domainDimension,const CGFloat * _Nullable domain,size_t rangeDimension,const CGFloat * _Nullable range,const CGFunctionCallbacks * _Nullable callbacks
);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
乍一看是不是不想再学了?当然,CGGradient对象足矣满足大部分时候的需求,不过有空的话还是耐心下来看看吧。我们先看看参数
- info 用来传递到callback的数据,注意,它的生命周期有可能不只是方法的生命周期
- domainDimension 输入的数量,quart中,就是1
- domain 一组数据,确定输入的有效间隔。quart中是0到1,0表示开始,1表示结束
- rangeDimension 输出的数量
- range 输出的有效间隔
- callbacks 用来计算的实际方法,格式如下
void myCalculateShadingValues (void *info, const CGFloat *in, CGFloat *out)
可能这样讲还是不清楚,看个例子就明白了(例子来自官方文档,我只是翻译过来的)
首先定义callback来计算实际像素值
static void myCalculateShadingValues (void *info,const CGFloat *in,CGFloat *out)
{
CGFloat v;size_t k, components;static const CGFloat c[] = {1, 0, 0.5, 0 };components = (size_t)info;v = *in;for (k = 0; k < components -1; k++)*out++ = c[k] * v;*out++ = 1;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
这里的三个参数,函数很简单out的值(r,g,b,a)分别为(in*1,in*0.in*0.5,1)
创建一个CGFunction
static CGFunctionRef myGetFunction (CGColorSpaceRef colorspace) //1 {size_t numComponents;
static const CGFloat input_value_range [2] = { 0, 1 };
static const CGFloat output_value_ranges [8] = { 0, 1, 0, 1, 0, 1, 0, 1 }; static const CGFunctionCallbacks callbacks = { 0, //2&myCalculateShadingValues,NULL };
numComponents = 1 + CGColorSpaceGetNumberOfComponents (colorspace); //3return CGFunctionCreate ((void *) numComponents, 1, input_value_range, numComponents, output_value_ranges, &callbacks);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
其中,每一行分别为
- 以colorspace作为参数
- 定义callback函数
- 计算颜色域中的颜色组建的个数,例如RGB就是三个,然后加一,表示alpha通道
用CGShading绘制Axial Gradient
CGPoint startPoint,endPoint;
CGFunctionRef myFunctionObject;
CGShadingRef myShading;
startPoint = CGPointMake(0,0.5);
endPoint = CGPointMake(1,0.5);
colorspace = CGColorSpaceCreateDeviceRGB();
myFunctionObject = myGetFunction (colorspace);
myShading = CGShadingCreateAxial (colorspace,startPoint, endPoint,myFunctionObject,false, false)
CGContextDrawShading (myContext, myShading);
CGShadingRelease (myShading);
CGColorSpaceRelease (colorspace);
CGFunctionRelease (myFunctionObject);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
用CGShading绘制Radial Gradient
原理类似
callback
static void myCalculateShadingValues (void *info,const CGFloat *in,CGFloat *out)
{size_t k, components;double frequency[4] = { 55, 220, 110, 0 };components = (size_t)info;for (k = 0; k < components - 1; k++)*out++ = (1 + sin(*in * frequency[k]))/2;*out++ = 1; // alpha
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
CGPoint startPoint, endPoint;CGFloat startRadius, endRadius;startPoint = CGPointMake(0.25,0.3);startRadius = .1;endPoint = CGPointMake(.7,0.7);endRadius = .25;colorspace = CGColorSpaceCreateDeviceRGB();myShadingFunction = myGetFunction (colorspace);CGShadingCreateRadial (colorspace,startPoint,startRadius,endPoint,endRadius,myShadingFunction,false,false)CGContextDrawShading (myContext, shading);CGShadingRelease (myShading);CGColorSpaceRelease (colorspace);CGFunctionRelease (myFunctionObject);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
效果
(Shadow,Gradient)相关推荐
- cocos2d Labels and Fonts 标签和字体(附:关于Hiero的二三事)
Labels and Fonts 标签和字体 Introduction 介绍 cocos2d 支持 TTF (True Type Fonts) 标签和纹理 atlas 标签. Pros and Con ...
- Adobe Photoshop 2022
Photoshop 2022 Mac破解软件是Mac os系统上一款专业强大的图像处理软件.Photoshop 2022内置的画笔工具极为丰富,成千上万的精致像素.动态和矢量画笔可以满 ...
- PS网页设计教程XIX——在Photoshop中创建一个优雅的作品集的网页布局
作为编码者,美工基础是偏弱的.我们可以参考一些成熟的网页PS教程,提高自身的设计能力.套用一句话,"熟读唐诗三百首,不会作诗也会吟". 本系列的教程来源于网上的PS教程,都是国外的 ...
- html5怎么转换,HTML5 canvas中的转换方法
转换方法 scale(scalewidth,scaleheight) 缩放当前绘图至更大或更小 scalewidth 缩放当前绘图的宽度 (1=100%, ...
- HTML5特效(shadow、gradient、transition、transform、filter)
文章目录 阴影(shadow) box-shadow text-shadow 渐变(gradient) linear-gradient radial-gradient 过渡(transition) 变 ...
- css3 shadow阴影
阴影部分 Shadow(阴影) text-shadow是给文本添加阴影效果,使用 text-shadow 属性给页面上的文字添加阴影效果,text-shadow 属性是在CSS2中定义的,在 CSS2 ...
- Android 自定义阴影Shadow颜色,大小等样式
最近在项目碰到一个比较头疼的项目,设计师需要给ui图中的一些按钮之类的东西添加阴影.乍一看设计图,这没啥嘛,咱们Android中不是有这个属性嘛,于是撸起袖子开搞: <TextViewandro ...
- 深度学习优化函数详解(5)-- Nesterov accelerated gradient (NAG) 优化算法
深度学习优化函数详解系列目录 深度学习优化函数详解(0)– 线性回归问题 深度学习优化函数详解(1)– Gradient Descent 梯度下降法 深度学习优化函数详解(2)– SGD 随机梯度下降 ...
- 比Momentum更快:揭开Nesterov Accelerated Gradient的真面目NAG 梯度下降
d为累计梯度 作为一个调参狗,每天用着深度学习框架提供的各种优化算法如Momentum.AdaDelta.Adam等,却对其中的原理不甚清楚,这样和一条咸鱼有什么分别!(误)但是我又懒得花太多时间去看 ...
最新文章
- Matlab与线性代数--矩阵的正交分解
- 为什么算法渐进复杂度中对数的底数总为2
- c语言rand随机输出字母,菜鸟求助,写一个随机输出26个英文字母的程序
- python2.7安装pip_python2.7 安装pip的方法步骤(管用)
- poj 2531(dfs)
- 代码覆盖度-NCover监控IIS和exe,结果分析
- 收藏 | 深度学习之Numpy基础入门教程!
- 两片74161实现60进制_74ls161集成60进制加法计数 - 74LS161集成计数器电路(2、3、4、6、8、10、60进制计数器)...
- JAVA使用bean配置ftp_FTP文件上传(By)java
- matlab中的turbo码,基于Matlab的Turbo码仿真研究
- C调用Python2.7,与调用Python3.5相差很大
- python简单计算器异常处理_Python计算器(正确除零)
- 概率论——超几何随机变量
- 最好的MATLAB入门教程
- 金蝶k3wise云服务器配置,金蝶K3WISEV15.0系统配置说明
- 解决KindEditor上传图片 不显示上传按钮问题
- ab压力测试及结果分析
- Win10家庭版添加不了新账户的解决方法
- Netty系列之Netty高性能之道
- UE4 学习记录八 给场景中添加背景音乐和动画音效,运动加速效果
热门文章
- Microbiome:中科院遗传发育所揭示植物发育和氮肥共同作用下的小麦根系微生物组...
- Cell: 为了PK抗生素而服用益生菌?后果竟然如此严重
- R语言ggplot2可视化时间序列散点图、X轴和Y轴都是时间信息、使用as.POSIXct函数自定义指定Y轴的时间范围(setting time limits in y axis)
- python使用matplotlib可视化3D曲面图、曲面图表示一个指定的因变量y与两个自变量x和z之间的函数关系
- seaborn可视化displot绘制直方图(histogram)并通过axvline函数在直方图中添加均值(mean)竖线(自定义均值竖线色彩)
- R语言seq函数生成数据序列实战
- 特征工程之数据分箱、Nominal特征编码、Ordinal分类特征编码、特征交叉组合、特征差分
- 样条+样条函数+样条分析+spline+样条插值+样条回归
- 局部变量 final Java_Java局部变量final
- 生命天书”破译20年,生命科学由此走向“大数据时代”