在开始之前,首先感谢画板(涂鸦)实现 - iOS和iOS 画板/涂鸦 你画我猜 demo (OC版)的作者,在下从他们的的博客中获得了很多启发。还要感谢外国友人提供的 曲线优化策略。

首先从确定实现方案开始。也经历了许多挫折。因为最开始我是想用 OpenGL 来实现的。。但是由于种种原因,最后选择了 UIBezierPath 配合 CAShapeLayer 再加上 截图合成来实现。下面来看具体思路。

获取触摸的手势,都是通过相同的回调来获取的


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent*)event- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent*)event 复制代码

然后就是处理用户操作所获的点,以进行下一步的绘制,此时需记录下开始的点,然后在move 方法中进行下一步的操作,最后操作结束。


p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #000000}p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px 'PingFang SC'; color: #1e9421}p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #3e1e81}p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #294c50}p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #1e9421}p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #1337ff}p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #000000; min-height: 16.0px}span.s1 {font-variant-ligatures: no-common-ligatures}span.s2 {font-variant-ligatures: no-common-ligatures; color: #539aa4}span.s3 {font-variant-ligatures: no-common-ligatures; color: #0435ff}span.s4 {font: 14.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #000000}span.s5 {font: 14.0px Menlo; font-variant-ligatures: no-common-ligatures}span.s6 {font-variant-ligatures: no-common-ligatures; color: #c42275}span.s7 {font-variant-ligatures: no-common-ligatures; color: #31595d}span.s8 {font-variant-ligatures: no-common-ligatures; color: #78492a}span.s9 {font-variant-ligatures: no-common-ligatures; color: #000000}span.s10 {font-variant-ligatures: no-common-ligatures; color: #294c50}span.s11 {font-variant-ligatures: no-common-ligatures; color: #1e9421}span.s12 {font: 14.0px 'PingFang SC'; font-variant-ligatures: no-common-ligatures; color: #1e9421}span.s13 {font-variant-ligatures: no-common-ligatures; color: #1337ff}span.s14 {font-variant-ligatures: no-common-ligatures; color: #3e1e81}span.s15 {font-variant-ligatures: no-common-ligatures; color: #703daa}span.s16 {font-variant-ligatures: no-common-ligatures; color: #6122ae}span.s17 {font-variant-ligatures: no-common-ligatures; color: #c81b13}ctr = 0;brush.endPoint = currentPoint;// 默认画线,点击同一个点时,添加黑点if (brush.shapeType == LxShapeDefault && CGPointEqualToPoint(brush.beginPoint, brush.endPoint)) {[brush.bezierPath addArcWithCenter:currentPoint radius:self.lindWidth/4.0 startAngle:0 endAngle:2*M_PI clockwise:NO];} else if (brush.shapeType == LxShapeEraser) {[brush.bezierPath addArcWithCenter:currentPoint radius:self.lindWidth/4.0 startAngle:0 endAngle:2*M_PI clockwise:NO];}if (brush.shapeType == LxShapeEraser) {[self drawEraser:brush];} else {[self.canvas setBrush:brush];}[self storeCurrentImage];} else { // 移动if (brush.shapeType == LxShapeDefault || brush.shapeType == LxShapeEraser) {
//            CGPoint centerPoint = CGPointMake((currentPoint.x+self.lastPoint.x)*0.5, (currentPoint.y+self.lastPoint.y)*0.5);
//            [brush.bezierPath addQuadCurveToPoint:currentPoint controlPoint:centerPoint];// 此处优化策略,参考// https://code.tutsplus.com/tutorials/smooth-freehand-drawing-on-ios--mobile-13164ctr++;pts[ctr] = currentPoint;if (ctr == 4) {pts[3] = CGPointMake((pts[2].x + pts[4].x)/2.0, (pts[2].y + pts[4].y)/2.0); // move the endpoint to the middle of the line joining the second control point of the first Bezier segment and the first control point of the second Bezier segment[brush.bezierPath moveToPoint:pts[0]];[brush.bezierPath addCurveToPoint:pts[3] controlPoint1:pts[1] controlPoint2:pts[2]]; // add a cubic Bezier from pt[0] to pt[3], with control points pt[1] and pt[2]// replace points and get ready to handle the next segmentpts[0] = pts[3]; pts[1] = pts[4]; ctr = 1;}} else if (brush.shapeType == LxShapeLine) {[brush.bezierPath removeAllPoints];[brush.bezierPath moveToPoint:brush.beginPoint];[brush.bezierPath addLineToPoint:currentPoint];} else if (brush.shapeType == LxShapeEllipse) {brush.bezierPath = [UIBezierPath bezierPathWithOvalInRect:[self getRectWithStartPoint:brush.beginPoint endPoint:currentPoint]];} else if (brush.shapeType == LxShapeRect) {brush.bezierPath = [UIBezierPath bezierPathWithRect:[self getRectWithStartPoint:brush.beginPoint endPoint:currentPoint]];
//        } else if (brush.shapeType == LxShapeEraser) {} else {NSLog(@"%ld", brush.shapeType);}if (brush.shapeType == LxShapeEraser) {[self drawEraser:brush];} else {[self.canvas setBrush:brush];}self.lastPoint = currentPoint;}
}
复制代码

其中绘制线段、椭圆、矩形的部分不再赘述。

关于撤销和恢复的部分是基于每次操作后的截图,把截图异步保存到本地指定文件夹内,然后通过当前所在的索引切换,即可实现撤销和恢复。

其中的录屏(有音频)功能使用 ReplayKit 来简单实现。如果只是了无音频的录屏,可参考ASScreenRecorder.

Demo链接 , 觉得好的请点一个 Star。

iOS 画板 涂鸦 答题相关推荐

  1. Html5 canvas 简单画布画板涂鸦例子

    简单的Html5 canvas 画板涂鸦例子,巧妙的使用onmousemove 事件来实现画画, 可以实现指定颜色和宽度,如图: <!DOCTYPE HTML> <html>& ...

  2. canvas画板涂鸦动画进度条动画

    目录 什么是 canvas 画板涂鸦动画 进度条动画 写在最后 什么是 canvas canvas 是 HTML5 新定义的标签,通过使用脚本(通常是 JavaScript)绘制图形.允许脚本语言动态 ...

  3. html canvas生成图片,html5 canvas画板涂鸦生成图片代码

    特效描述:html5 canvas 画板涂鸦 生成图片代码.html5画板涂鸦 代码结构 1. HTML代码 清 空 生成图片 var canvas,board,img; canvas = docum ...

  4. iOS 图片编辑——涂鸦——随手指移动随意画线

    iOS 涂鸦 我们已经讲过画直线 和画带箭头的线段 参考:http://blog.csdn.net/lwjok2007/article/details/50885376 这节 我们尝试做一下 随意画 ...

  5. iOS 照片涂鸦功能的实现

    作者 | 周强 杏仁 APP 团队负责人,关注大前端. 上个版本项目图片编辑需求中有一项涂鸦,涂鸦就是选取颜色后根据手指滑动路径在图片上生成对应路径,并最终生成一张新图片.接到项目,Google.Gi ...

  6. 电脑PHP动画制作画板,涂鸦板简单实现 Html5编写属于自己的画画板

    这篇文章主要教大家如何使用Html5编写属于自己的画画板,进行绘画.调整颜色等操作,感兴趣的小伙伴们可以参考一下 最近了解到html5强大的绘图功能让我惊奇,于是,写了个小玩意---涂鸦板,能实现功能 ...

  7. Canvas画板涂鸦生成图片

    笔者从事教育软件行业,担任公司的前端开发,产品主要应用于PC端和移动端.之前遇到一个需求:老师在课堂上发布一张习题图片给学生练习的时候,学生要在移动端上接受老师发的图片,并在上面写出答案提交,然后老师 ...

  8. 利用CGMutablePathRef制作画板涂鸦

    效果图: : 具体代码如下: ViewControl: #import "ViewController.h" #import "PenView.h" #impo ...

  9. Android画布放大缩小,android画板---涂鸦,缩放,旋转,贴纸实现

    前言 最近有需求要做一个画布,这个画布以一个图片为背景,可以实现缩放,涂鸦以及贴纸的功能,缩放和涂鸦要兼顾,于是就想到了可以加入手势和多点触控,大致就是两只手指头可以拖动或者旋转或者放大,单只手指可以 ...

最新文章

  1. 记录-- vue+element树节点的标注
  2. 1.将cocos2d-x项目移植到Linux环境下,将cocos2d-x项目移植到手机上
  3. CJOJ 1087 【NOIP2010】乌龟棋 / Luogu 1541 乌龟棋(动态规划)
  4. oracle查询sql记录数,oracle查询所有表的记录数SQL
  5. 04. 非必要不提供default constructor
  6. C++:DFS求最优路径
  7. 在SVN安装目录的bin文件夹下没有找到svn.exe
  8. parser.parse_known_args()理解
  9. Django DTL 加减乘除求余
  10. ipad能不能装python_ipad能下载python么
  11. 养老保险不到60岁能领吗
  12. python运行调出控制台_python控制台怎么打开
  13. 一个企业如何运营微商管理系统?
  14. 层(Overlays)
  15. python获取评论数据
  16. 一年级的孩子可以学习机器人编程
  17. ubuntu下安装telnet服务
  18. 怎么恢复回收站清空删除的文件
  19. unity字体效果-1分钟制作字体 荧光 效果(TextMeshPro)
  20. ablation study 消融实验/消融研究

热门文章

  1. 功不唐捐——高兴的一天
  2. 从MIT协议谈契约精神
  3. 如何将旧手机soul聊天记录导入到新手机中
  4. Apache http设置反向代理和负载均衡
  5. Error (0xc0000225) installing Windows 7 on VirtualBox
  6. 马赛克(蒙太奇)图片生成--Python实现
  7. vbscript下载文件(使用https绕过无效的证书错误)
  8. java常见的异种类_JCA - 自然 - BlogJava
  9. 解决在x86平台装openwrt旁路由大流量断网问题(intel网卡驱动bug问题)
  10. Java之Stream的管道处理