canvas 插件_基于Angular的Canvas手写签名插件

灵感来源

之前, 在轻流的业务中遇到了一个需求, 是能够让客户使用手写签名的功能.

7d6a5c0a1dcdf2b68b93e6adf990dd01.gif
签名演示

问题来了, 这...我不会啊! 这得是Canvas了吧. 正所谓, 插件用的好, 下班走的早. 于是我就开始找插件了. 找到了一个ng生态的插件, 名字不记得了, 只记得他就一个核心文件, 封装了一个第三方插件. 没有提供任何原创的方法, 都是直接把第三方签名插件所提供的方法emit了出来. 以下就是他import的第三方插件.

https://github.com/szimek/signature_pad​github.com

那么问题来了, 那我要你干嘛? 我为啥不自己封装一个呢? 因为业务比较紧, 没有那么多时间去思考如何封装地更好. 所以直接在轻流中封装了一个更加适合轻流业务的签名模块. 比如说, 全屏签名

30c2edfcaa2067f0cfe701ad37e47f96.gif
全屏签名

在完成业务后, 我使用angular library封装了属于自己的第三方插件.

https://github.com/eve-sama/ngx-signature-pad​github.com

那么我的插件有什么特别之处呢? of course~ 因为第三方插件我认为有些地方的设计不是很合理, 并且没有一些我想要的API.

注意: 为了方便描述和对比, 在下文中, 第三方插件我将称之为sp(signature pad的缩写), 我的插件将称之为ngx-sp.

一. API风格更加ng化

现在让你来设计这个签名组件, 要求实现当用户签字的时候通知父组件一个签名事件. 当结束签字的时候需要通知父组件一个结束事件. 我们先看看sp是如何处理的

42b2c3e6ad7f8a60853dd7fcd3d035bc.png
摘自sp README部分

sp是通过一个对象的形式传递参数, 包括事件也是通过回调函数的方法. 如果是我我就不会这么设计. 我觉得ng社区的同僚应该下意识都是像下面这样设计API的

<

二. 只有小屏签名

其实全屏签名是个非常常见的场景, 但是sp并没有提供. 其实这个不能说是sp的问题. 因为他提供了一块儿签名的canvas, 理论上你就可以在这个基础上开发出各种姿势的签名. 只是我比较懒, 我希望他能提供类似如下的代码

sp.fullScreen();

遗憾的是他没有, 在全屏相关的需求中, Angular CDK是个非常好的工具, 其实可以结合CDK轻而易举地实现这样的需求. 所以, sp没有, 那ngx-sp就来做.

adecc269cebe40fdd67de369373c0180.png
摘自ngx-signature-pad README部分

需要注意一点, 大家想象下, 你比如初始化了一个签名组件, 尺寸是300*150, 在上面画了几笔. 大概这个样子

ed51cd0ab16f9e31f654c28a90b47592.png
小屏签名

当调用fullScrren()的时候, 签名组件会展示全屏化, 请问, 已经签过的内容该如何处理呢? 显然是要放大的吧. 但是小屏签名的宽高是由用户自定义的, 那么全屏的话, 假如ngx-sp真的100%的宽*100%的高, 不一定和用户设定的比例相同.

比例不同造成的后果, 就是已签过的内容会被拉宽或者拉高. 所以, 我的设定就是全屏的宽高比与小屏的宽高比是保持一致的.

58a4264e6a7bffd5e3d5e412fd97dd8c.png
全屏签名

顺便一提, 之所以我执意要把全屏的API封装进ngx-sp, 是因为全屏要做的事儿比较恶心, 我不想在业务层做这种事儿. 这几十行倒也算不上很难, 就是对canvas不熟悉、数学又差的一逼的人, 比如我, 比较折腾.

aa7a8ef8db6f81dbfcc2457c137adbdc.png
摘自ngx-sp源码

现在好了, 你只需要一个xxx.fullScreen()就可以直接全屏化, 那叫一个美汁儿美汁儿~

三. 只能判断是否被签过, 不允许更改状态

在sp中, 是这样判断是否被签名过的

// Returns true if canvas is empty, otherwise returns false

但是并没有提供手动更改签名状态的方法. 为什么需要这样的函数呢?

比如说前文的全屏签名, 大家注意看这个操作过程

  1. 先显示小屏签名, 允许用户签名
  2. 当点击放大图标时, 全屏覆盖签名
  3. 再点击缩小图标时, 显示小屏签名

我的思路, 其实是创建2个canvas实例. 一个用于小屏, 一个用于全屏(使用CDK包装). 当用户切换模式的时候, 就会把原模式的内容copy到新模式的canvas上. 但是因为sp没有提供手动更改签名状态的方法, 就会导致一个问题.

当ngx-sp把小屏签名的内容copy到全屏签名上, 此时调用isEmpty()方法, 一定是true(也就是显示你从未签名过, 从逻辑上看, 这就是bug了). 因为你全屏签名的内容并不是鼠标绘制出来的. 而是通过canvas相关的方法copy的.

查看sp的源码, 会发现相关属性是private

2f820284a12b279ddd19f2f4502e08fb.png
摘自sp源码

问题不大, 在轻流的业务模块中, 我就强行把_isEmpty给改了. 反正private在run time时被更改, 浏览器也拦不住我.

在ngx-sp中则对外提供了手动更改状态的函数

753531e2311dcbb617e34fd69313ee9a.png

当然了, 在ngx-sp中没有使用强行更改private这种野路子的方法. 那么我是怎么做的呢? 核心思路其实就是我自己维护了这个变量.

下面这段代码, 简单来说就是在initSmallPad()中会根据开发者传递的参数(options), 初始化sp. sp对外提供了一个onBegin的方法, 当他触发的时候, 我就会手动把_isEmpty标记为false. 既然这个变量由我自己来维护, 那么我就可以任意更改了.

e7281e1c5daa5c3360d43fdfecc09155.png
摘自ngx-sp源码

所以, 同样对外暴露了isEmpty()的方法, 但是我的判断依据并不是根据sp源码里的变量, 也不是直接调用的sp的isEmpty(), 而是我自己维护的私有变量.

四. 自由度不够

sp并没有对外暴露canvas实例相关的属性. 这是一个很麻烦的事儿. 为什么呢, 给不了解canvas的同学科普一个概念. canvas是允许通过dragImage方法把图片等资源画在上面的, 如下图.

8de432c75f7dfa9d5216e801489f69e1.png
https://eve-sama.github.io/ngx-signature-pad/document (注意是PC模式)

我常年写的字儿自己都不认识. 上图的签名显然不是我手画的. 其实'前夕'那2个字是个图片.

e209779608ffd97afd0d70fd61388c7f.png
摘自ngx-sp README

在ngx-sp中很容易做到这样的事儿.

this.signature.getContext().drawImage(this.image, 230, 35, 100, 50, 230, 110, 100, 50);
this.signature.setDirty();

举个例子, 假如你的产品经理希望你在签名区域+个背景图, 类似下面这样. 在sp中确实没法实现, 因为sp只允许你设置背景颜色, 而且是纯色.

8f34d44d5b6acf85d7c88769a6578612.png
百度随便搜的

而如果在ngx-sp中, 通过获取canvas相关实例, 你可以想怎么画就怎么画.

总结

以上就是对ngx-signature-pad的介绍了, 更多介绍请查看Repo. 我也只是站在巨人的肩膀上做了一点点扩展, 希望能帮助到有需要的人~!

Repo地址

https://github.com/eve-sama/ngx-signature-pad​github.com

demo页, 如果使用浏览器的PC模式访问则侧重文档, Mobile模式则侧重demo.

NgxSignaturePad​eve-sama.github.io

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/502312.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

配置DNS服务器的需要修改的配置文件为,dns服务器配置教程

在WIN2003怎么安装部署DNS服务器(DNS服务是全称 域名服务器&#xff0c;是把域名地址主机名解析到网络地址的一项服务).下面是学习啦小编收集整理的dns服务器配置教程&#xff0c;希望对大家有帮助~~dns服务器配置教程工具/原料WIN2003 DNS组件 操作系统光盘安装添加DNS服务器角…

php源码怎样安装mysql_安装MySQL

三、mysql的安装&#xff0c;与php、Apache相结合打开下载的文件&#xff0c;双击运行&#xff0c;出现如下界面。mysql安装向导启动&#xff0c;按“Next”继续。选择安装类型&#xff0c;有“Typical(默认)”、“Complete(完全)”、“Custom(用户自定义)”三个选项&#xff0…

python循环经典例题_python练习题:循环打印嵌套列表

好久没写博文了&#xff0c;添加一个练习题&#xff0c;选自《head_first_python》~~ python列表&#xff1a;以中括号开始和结束"[]"&#xff1b;列表项以逗号"&#xff0c;"分隔开&#xff0c;使用赋值操作符""赋予一个标识符。如&#xff1a;…

开发测试服务器配置信息,node服务端中台实现及开发测试生产环境配置

本人node服务端新人一枚&#xff0c;网上找了不少资料&#xff0c;看了很多别人的配置信息&#xff0c;感觉都不是很合适&#xff0c;看的多了自己也明白配置的具体思路跟实现方式了&#xff0c;以下为我的实现方式。通过package.json里面的scripts配置命令行信息&#xff0c;然…

mysql数字前面有0_Mysql中前边有0的数据,0会被舍去的问题

最近由于项目的需求&#xff0c;需要频繁地拉取不同数据库中的数据&#xff0c;拉取数据的过程中&#xff0c;各种问题&#xff0c;十分悲催&#xff0c;真所谓&#xff0c;一个疏忽&#xff0c;你就要被推倒重来...在经历了无数次被推倒又站起来&#xff0c;然后又被推倒的艰苦…

狸窝音频剪辑软件_「附下载链接」常用的5款视频格式转换软件,收藏起来吧...

日常生活中&#xff0c;大家可能会自己制作一些记录生活的小视频&#xff0c;或者作为爱好上传到视频平台&#xff0c;就会用到很多种的视频格式&#xff0c;比如MP4、MKV、WMV、FLV、MOV、DV等等。因为有的视频网站需要特殊格式的视频才能上传&#xff0c;或者因为视频体积太大…

mysql 触发器 运算符_mysql三元运算,上下连表,视图,触发器,存储过程,事务等不常用方法...

1 MySql中的三元运算符有两种方法&#xff1a;1、case when 条件 then (条件为true时执行) else(条件为false时执行) end;/*end不可少*/2、select *,if(expr1,expr2,expr3) from 表名;实例&#xff1a;SELECT if(isnull(sum(c.MONEY)),0,sum(c.MONEY)) AS m1 FROM Table2 上下连…

求字典key的和python_python怎么将字典key相同的value值, 合并

python怎么将字典key相同的value值&#xff0c; 以逗号隔开&#xff0c;整为一行数据 源数据&#xff1a; test_dict1 {text: 50.00€ Rabatt fr Bestellungen ber 10.00€, strong_off: 50.00€, html_text: 50.00€ Rabatt fr Bestellungen ber 10.00€} test_dict2 {text:…

简单的mysql左链接_简单谈谈mysql左连接内连接

前言最近忙着开发x省冷链追溯系统&#xff0c;天天干到晚上十一点多才回到家&#xff0c;周末也加班&#xff0c;没啥时间写博客&#xff0c;闲下来再好好写写业务&#xff1a; sql语句统计出入库数据。问题&#xff1a;只统计了X端入库单。原因&#xff1a; 没有发现X端的数据…

c语言 空格_C语言100题集合-ex003

系列文章《C语言经典100例》持续创作中&#xff0c;欢迎大家的关注和支持。喜欢的同学记得点赞收藏哦&#xff5e;1 题目函数&#xff1a;fun() 功能&#xff1a;统计一行字符串单词的个数&#xff0c;作为函数值返回描述&#xff1a;一行字符串在主函数中输入&#xff0c;规定…

go 默认http版本_【每日一库】超赞的 Go 语言 INI 文件操作

点击上方蓝色“Go语言中文网”关注我们&#xff0c;领全套Go资料&#xff0c;每天学习 Go 语言如果你使用 INI 作为系统的配置文件&#xff0c;那么一定会使用这个库吧。没错&#xff0c;它就是号称地表 最强大、最方便 和 最流行 的 Go 语言 INI 文件操作库&#xff1a;https:…

python程序设计第一章答案_Python《学习手册:第一章-习题》

人们选择Python的六大主要原因是什么&#xff1f; 软件质量&#xff1a;Python注重可读性、一致性和软件质量。Python代码的设计致力于可读性&#xff0c;因此具备了比传统脚本语言更优秀的可重用性和可维护性。 Python的一致性保证了其代码易于理解。 Python支持软件开发的高级…

redis数据丢失_有效避免数据丢失!Redis持久化方案选择详解

为什么需要持久化呢&#xff1f;通常情况下redis的数据全部存储在内存中,数据库一旦故障发生重启数据会全部丢失&#xff0c;即使是在redis cluster或者redis sentinel模式下主从同步数据的恢复仍然需要一段时间。持久化功能在于能够有效地避免因进程退出造成的数据丢失问题&am…

做python开发要用多大的内存_Python 在分配内存需要考虑的问题

由此能看出可变对象在扩充时的秘密&#xff1a;超额分配机制&#xff1a;申请新内存时并不是按需分配的&#xff0c;而是多分配一些&#xff0c;因此当再添加少量元素时&#xff0c;不需要马上去申请新内存 非均匀分配机制&#xff1a;三类对象申请新内存的频率是不同的&#x…

mysql审计 社区版有吗_mysql 5.6 社区版上审计功能,不扯皮

官网https://mariadb.com/kb/en/mariadb/about-the-mariadb-audit-plugin/一、环境说明MySQL 5.6.25 社区版Mariadb 10.0.25 社区版mysql 企业版有审计功能需要收费&#xff0c;社区版被阉割的不行不行了&#xff0c;和古时候的太监没啥区别了&#xff0c;比较重要的功能特性都…

python用outlook自动发邮件_Python 调用outlook发送邮件(转 )

单账号&#xff1a; import win32com.client as win32 def send_mail(): outlook win32.Dispatch(Outlook.Application) mail_item outlook.CreateItem(0) # 0: olMailItem mail_item.Recipients.Add(testtest.com) mail_item.Subject Mail Test mail_item.BodyFormat 2 # …

win10子系统ubuntu图形界面_win10系统中安装ubuntu子系统及图形界面

作为全球最流行且最有影响力的Linux开源系统之一&#xff0c;Ubuntu自发布以来在应用体验方面&#xff1a;有较大幅度的提升&#xff0c;即使对比Windows、MacoS等操作系统&#xff0c;最新版本的Ubuntu也不逊色。下面教大家在win10系统中安装ubuntu子系统及图形界面。第一步&a…

为什么python打开pygame秒关闭后在运行_当我运行Python程序时,pygame窗口打开片刻,然后退出 - python...

我是一个刚开始尝试通过在线课程使用python和pygame制作游戏的程序员。但是&#xff0c;当我运行以下代码时&#xff0c;pygame窗口将打开一秒钟&#xff0c;然后关闭。 import pygame pygame.init() screen pygame.display.set_mode((900,700)) finished False while finish…

es 时间字段聚合_ES之五:ElasticSearch聚合

1、单值聚合Sum求和,dsl参考如下&#xff1a;{"size": 0,"aggs": {"return_balance": {"sum": {"field": "balance"}}}}返回balance之和&#xff0c;其中size0 表示不需要返回参与查询的文档。Min求最小值{"…

div字体居中_div和span的使用

这节我们来制作以下效果我们先把四个段落的文字都写出来&#xff0c;分别包含在p标签里现在看到的效果如下我们来一点一点给它加入样式首先&#xff0c;来使文字水平居中并且加背景色但是这样显示的效果有一些问题&#xff0c;直接加入文字背景会显示背景顶着两头&#xff0c;导…