close
当前位置: 物联网在线 > 技术文库 > ios >

开源项目-拼图验证控件TTGPuzzleVerify的实现

最近抽空写了个拼图验证控件,用户可以通过水平、垂直,或者直接拖动拼图块,完成拼图图案,来完成验证。拼图块的形状可以自定义,默认提供了经典的拼图形状、圆形、正方形,整个拼图的图案也是支持从图片生成的。

CocoaPods: pod "TTGPuzzleVerify"
 

开源项目-拼图验证控件TTGPuzzleVerify的实现

接下来,说说TTGPuzzleVerify的整体设计思路和实现原理。

分析 组成部分

先直观上分析一下控件的组成部分:

开源项目-拼图验证控件TTGPuzzleVerify的实现

可以直观看出,控件应该由三个部分组成:

拼图块:就是从原图上 “抠” 出来的拼图形状的图片块

原始图片:拼图整体图案的图片

镂空背景:从原始图片上抠出拼图块以后,给用户提示用的,透明度更低的拼图块镂空背景

拆解步骤

分析完了控件的组成,现在就来梳理一下控件的整个创建、交互流程。

开源项目-拼图验证控件TTGPuzzleVerify的实现

输入:图片、拼图形状、拼图大小、镂空的位置、拼图块的起始位置

生成拼图路径:根据拼图类型,生成对应的贝塞尔曲线

从图片抠出拼图块、镂空:有了拼图路径,就可以抠出拼图块和镂空的部分

设置位置、样式:根据参数设置拼图块的初始位置、样式,如阴影、镂空的透明度等

用户拖动:响应用户的头动手势,移动拼图块,根据坐标判断是否完成拼图

回调:用户完成拼图后,要回调,让外部响应拼图完成事件

关键技术点

从上面的步骤可以整理出来几个关键的技术点,如下:

拼图的路径生成

普通的形状,如正方形、圆形之类的还好,代码实现比较方便,但是复杂的拼图图案怎么办?

从图片上“抠出”拼图块、镂空

有了拼图的形状路径,如何从图片上抠出拼图块和镂空?

用户拖动拼图、完成拼图验证

抠出了拼图块,如何将用户的手势对应到移动拼图块,最终完成验证?

下面针对这三个点着重写下实现原理。

实现 拼图的路径生成

既然手写代码太难,那就从现有的图案生成代码。

1. 找SVG素材

既然要能随意改变大小,就要找矢量的图,Google “free svg”、“free icon”之类的,很容易就能找到免费的矢量图素材,例如TTGPuzzleVerify里面用的拼图形状就是从 iconmonstr.com 找来的。

2. 编辑

直接下载回来的SVG还需要调整一下,如去除背景,我是用Sketch来编辑的。

开源项目-拼图验证控件TTGPuzzleVerify的实现

3. 生成代码

拼图的路径本质上就是拼图的轮廓,在Sketch里面把拼图SVG的背景色等颜色删除,然后就是将其转换为代码。

这里可以用 PaintCode plugin for Sketch ,将Sketch的拼图矢量路径导出成代码。

4. 调整代码

直接生成的代码有时可能会不适用,可以人工调整下,然后就可以放到自己的类里面了:

+ (UIBezierPath *)classicPuzzlePath { static UIBezierPath *puzzleShape = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ puzzleShape = [UIBezierPath bezierPath]; [puzzleShape moveToPoint:CGPointMake(17.45, 71.16)]; // 此处省略很多行=。=,PaintCode生成的 [puzzleShape closePath]; }); return puzzleShape; }

5. UIBezierPath拼图路径的大小、位置调整

直接导出的拼图路径的大小、位置是固定的,但是控件是要可以支持改变大小、位置的,所以,要对路径做变换,刚好 UIBezierPath 支持 CGAffineTransform 变换。

大小变换:

// 大小变换,path是生成的原始路径,_puzzleSize是传入的拼图块大小 [path applyTransform:CGAffineTransformMakeScale(_puzzleSize.width / path.bounds.size.width, _puzzleSize.height / path.bounds.size.height)];

位置变换:

// 位置变换,path是生成的原始路径,_puzzleBlankPosition是传入的拼图块、镂空位置 [path applyTransform:CGAffineTransformMakeTranslation( _puzzleBlankPosition.x - path.bounds.origin.x, _puzzleBlankPosition.y - path.bounds.origin.y)];

至此,拼图的路径就写好了。

从图片上“抠出”拼图块、镂空

1. 拼图块

有了UIBezierPath路径,抠出拼图块还是比较容易的,直接用 CAShapeLayer 来 “mask” 图片即可:

// 拼图路径 UIBezierPath *puzzlePath = [self getNewScaledPuzzledPath]; // 创建mask layer CAShapeLayer *puzzleMaskLayer = [CAShapeLayer new]; puzzleMaskLayer.frame = self.bounds; puzzleMaskLayer.path = puzzlePath.CGPath; // Mask到图片imageView上 _puzzleImageView.layer.mask = puzzleMaskLayer;

效果就是:

开源项目-拼图验证控件TTGPuzzleVerify的实现

2. 镂空图片

抠出拼图块还是很容易的,但是“镂空”怎么办?

其实道理是一样的,都是 mask ,只不过mask的区域反过来而已。

CAShapeLayer 的 fillRule 就可以调整“填充的规则”,此处用 kCAFillRuleEvenOdd 就可以了,文档的解释如下:


(责任编辑:ioter)

用户喜欢...

CN0398开发板和ADuCM360_demo_cn0398开源软件包解决了土壤测量系统设

保持适当的土壤湿度和pH值是植物健康的基本要求,无论是用于大规模农业还是简单的家庭菜园。然而,为了测量这些土壤特性,开发人员需要设计出具有成本效益的高精度模拟信号链,能够将...


创新的组合:开源和众筹

开源已经被称为力量倍增器,这是使公司的员工,融资和资源更为有效的一个因素。但是,在过去的几年里,开源已经开始与另一个力量倍增器 - 众筹相提并论。现在,这种结合的结果正在出...


太阳能收集项目为2.4GHz通知的远程MSP430供电

最简单的是,能量采集是能量采取一种形式的能量,并将其转化为电能,可以储存在电池或超级电容器(也被称为超级杯或超级杯)。太阳能应用范围从高压屋顶光伏到用于远程低功率应用的小...


博世和奔驰合作的互联泊车项目

CES博世展台,我们看到了一个有趣的角落。 一个工程师穿着复古的着装,在一个130年前的工作台上生产零件。机器因为年代久远,还是通过脚踩踏板来驱动。但博世给工作台加装了工业4.0网关...


推荐 10 个饱受好评且功能独特的开源人工智能项目

关于人工智能的项目,相信大家都看过或者用过不少了,但它们的大多数看上去都十分“高大上”,让人感觉要掌握他们犹如习屠龙之术一样。事实上,有很多关于人工智能的项目还是十分实...


盘点·GitHub最著名的20个Python机器学习项目

开源是技术创新和快速发展的核心。这篇文章向你展示Python机器学习开源项目以及在分析过程中发现的非常有趣的见解和趋势。 我们分析了GitHub上的前20名Python机器学习项目,发现scikit-Lear...


“开源”为何对于IoT如此重要?

物联网、开源、操作系统是目前IT业界的热门词汇,也正是这三个词汇构成了物联网开源操作系统。 对于物联网发展而言,“碎片化”是主要的问题,其中芯片、传感器、通信协议、应用场景...


12英寸晶圆厂再添新势力 广州粤芯半导体项目动工

芯片,极为微小的电子器件,它被喻为“工业粮食”,是所有整机设备的“心脏”。官方介绍,长期以来,广州缺乏...


基于Zedboard的开源软件定义无线电(SDR)设备:Panoradio!

软件定义无线电(Software Defined Radio, SDR)是一种现代无线电广播通信技术,它采用软件定义的无线通信协议而非“纯硬件电路”实现各种通信和信号采集功能,这种方式打破了有史以来设备...


总投资35亿 大陆最大半导体显示芯片封测“双子”项目落户合肥

「双子项目」总投资约35亿元人民币,由北京芯动能投资管理有限公司、北京奕斯伟科技有限公司、台湾颀邦科技股份...