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)

用户喜欢...

Semtech利用LoRaWAN推出用于物联网开发的免费开源工具集

Semtech希望通过免费的,开源的,以LoRaWAN为重点的物联网开发教育工具来揭开RF的神秘色彩。 Semtech宣布推出两个新的免费教育工具系列,以帮助设计人员了解LoRaWAN以及如何在设计中实现它,尤...


AI 圣经 PRML《模式识别与机器学习》官方开源了!

红色石头相信任何一个搞机器学习、深度学习的人都应该听说过一本经典教材:《Pattern Recognition and Machine Learning》,中文译名《模式识别与机器学习》,简称 PRML。出自微软剑桥研究院实验室...


为什么76%的物联网项目失败以及如何取得成功

在物联网(IOT)已经引起了世界的想象,在过去的几年里。毫无疑问:该行业预计将在202年内全球增长到820亿美元,它有可能解决众多挑战,无论是微不足道的还是严肃的。 但要小心!隐藏在...


开源物联网平台汇总

物联网(IoT)是帮助人工智能(AI)以更好的方式控制和理解事物的未来技术。 我们收集了一些最有名的物联网平台,帮助您以受控方式开发物联网项目。 物联网平台是帮助设置和管理互联网...


Startup将开源驱动到物联网

由Linaro成员组成的创业公司希望成为物联网的红帽,为终端节点,网关和汽车提供Linux和Zephyr RTOS的配置。Foundries.io旨在提供与处理器无关的代码,以便在物联网开发人员具有各种越来越多的特...


基于FPGA的模块化快速原型系统是实现高性能电力电子研发项目的基础

FPGA提供了令人印象深刻的计算能力,这在电力电子系统中的要求越来越高。基于FPGA的模块化快速原型系统是实现高性能电力电子研发项目的基础。 电力电子中算法的必要性 随着当今电力电子...


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

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


创新的组合:开源和众筹

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


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

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


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

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