All Projects → linjc → smooth-signature

linjc / smooth-signature

Licence: MIT license
H5带笔锋手写签名,支持PC端和移动端,任何前端框架均可使用

Programming Languages

typescript
32286 projects
Vue
7211 projects
javascript
184084 projects - #8 most used programming language
HTML
75241 projects

Projects that are alternatives of or similar to smooth-signature

eosdart ecc
Elliptic curve cryptography functions in Dart. Private Key, Public Key, Signature, AES, Encryption, Decryption
Stars: ✭ 25 (-94.73%)
Mutual labels:  signature
larsign
Laravel signature certification with web API server.
Stars: ✭ 18 (-96.2%)
Mutual labels:  signature
jwt-core
[READ-ONLY] Core component of the JWT Framework
Stars: ✭ 46 (-90.3%)
Mutual labels:  signature
leptin
🔗 Leptin is a PoW blockchain completely built in Nodejs.
Stars: ✭ 57 (-87.97%)
Mutual labels:  signature
memory signature
A small wrapper class providing an unified interface to search for various memory signatures
Stars: ✭ 69 (-85.44%)
Mutual labels:  signature
binance-signature-examples
Examples of generating HMAC and RSA signature for Binance API
Stars: ✭ 170 (-64.14%)
Mutual labels:  signature
iOS-Signature-Capture
iOS-Signature-Capture is helps to capture the user signature with name and signed date in iOS and supports both Objective-c and Swift languages.
Stars: ✭ 50 (-89.45%)
Mutual labels:  signature
AutomatedOutlookSignature
PowerShell script to automate the creation of Outlook signatures using Active Directory attributes.
Stars: ✭ 36 (-92.41%)
Mutual labels:  signature
git-secure-tag
Secure git tag signing
Stars: ✭ 44 (-90.72%)
Mutual labels:  signature
GPGit
A shell script that automates the process of signing Git sources via GPG
Stars: ✭ 84 (-82.28%)
Mutual labels:  signature
signature
HMAC and RSA signature for Laravel and Lumen
Stars: ✭ 26 (-94.51%)
Mutual labels:  signature
SSL-TLS-ECDSA-timing-attack
Timing Attack on TLS' ECDSA signature
Stars: ✭ 41 (-91.35%)
Mutual labels:  signature
wascap
Embed, extract, and validate capability claims in JWTs for WebAssembly modules
Stars: ✭ 59 (-87.55%)
Mutual labels:  signature
pdf-sign-check
A java / spring boot application to help you sign and check signed pdf documents
Stars: ✭ 81 (-82.91%)
Mutual labels:  signature
fortify
Fortify enables web applications to use smart cards, local certificate stores and do certificate enrollment. This is the desktop application repository.
Stars: ✭ 88 (-81.43%)
Mutual labels:  signature
go-dkim
A Go library to create and verify DKIM signatures (migrated)
Stars: ✭ 38 (-91.98%)
Mutual labels:  signature
orchestrate-node
This Orchestrate library provides convenient access to the Orchestrate API from applications written in server-side NodeJS
Stars: ✭ 19 (-95.99%)
Mutual labels:  signature
qdigidoc
DEPRECATED DigiDoc3 Client is a program that can be used to sign digitally with ID-card and Mobile-ID, check the validity of digital signatures and open and save documents inside the signature container.
Stars: ✭ 25 (-94.73%)
Mutual labels:  signature
trim-canvas
A tiny (< 100 LoC) library for trimming whitespace from a canvas element with no dependencies
Stars: ✭ 48 (-89.87%)
Mutual labels:  signature
mini-smooth-signature
小程序版带笔锋手写签名,支持微信/支付宝/钉钉/QQ小程序
Stars: ✭ 85 (-82.07%)
Mutual labels:  signature

smooth-signature 带笔锋手写签名

Demo

前言

受疫情的影响,无纸化流程和电子合同开始普及,电子签名需求也不断增加,签名体验也在逐渐改善,从一开始简单的canvas画线,到追求线条丝滑圆润,再到要求和纸上写字一样的笔锋效果等等。网上不少现成开源的签名库,其中signature_pad笔锋效果实现比较好,但具体使用还是会发现有明显的锯齿感,于是利用工作之余,根据自身理解换了另一种方案实现了一套,同时也为小程序开发了一版,一起分享给有需要的同学。

mini-smooth-signature 小程序版带笔锋手写签名,支持多平台小程序使用

安装

npm install smooth-signature
#
yarn add smooth-signature

或通过<script>引用,全局变量 window.SmoothSignature

<script src="https://unpkg.com/smooth-signature/dist/index.umd.min.js" />

也可自行下载smooth-signature.js到本地引用

使用

<div>
    <canvas />
</div>
import SmoothSignature from "smooth-signature";

const canvas = document.querySelector("canvas");
const signature = new SmoothSignature(canvas);

// 生成PNG
signature.getPNG() // 或者 signature.toDataURL()

// 生成JPG
signature.getJPG() // 或者 signature.toDataURL('image/jpeg')

// 清屏
signature.clear()

// 撤销
signature.undo()

// 是否为空
signature.isEmpty()

// 生成旋转后的新画布 -90/90/-180/180
signature.getRotateCanvas(90)

配置[options]

所有配置项均是可选的

const signature = new SmoothSignature(canvas, {
    width: 1000,
    height: 600,
    scale: 2,
    minWidth: 4,
    maxWidth: 10,
    color: '#1890ff',
    bgColor: '#efefef'
});

options.width

画布在页面实际渲染的宽度(px)

  • Type: number
  • Default:canvas.clientWidth || 320

options.height

画布在页面实际渲染的高度(px)

  • Type: number
  • Default:canvas.clientHeight || 200

options.scale

画布缩放,可用于提高清晰度

  • Type: number
  • Default:window.devicePixelRatio || 1

options.color

画笔颜色

  • Type: string
  • Default:black

options.bgColor

画布背景颜色,默认透明

  • Type: string
  • Default:

options.openSmooth

是否开启笔锋效果,默认开启

  • Type: boolean
  • Default:true

options.minWidth

画笔最小宽度(px),开启笔锋时画笔最小宽度

  • Type: number
  • Default:2

options.maxWidth

画笔最大宽度(px),开启笔锋时画笔最大宽度,或未开启笔锋时画笔正常宽度

  • Type: number
  • Default:6

options.minSpeed

画笔达到最小宽度所需最小速度(px/ms),取值范围1.0-10.0,值越小,画笔越容易变细,笔锋效果会比较明显,可以自行调整查看效果,选出自己满意的值。

  • Type: number
  • Default:1.5

options.maxWidthDiffRate

相邻两线宽度增(减)量最大百分比,取值范围1-100,为了达到笔锋效果,画笔宽度会随画笔速度而改变,如果相邻两线宽度差太大,过渡效果就会很突兀,使用maxWidthDiffRate限制宽度差,让过渡效果更自然。可以自行调整查看效果,选出自己满意的值。

  • Type: number
  • Default:20

options.maxHistoryLength

限制历史记录数,即最大可撤销数,传入0则关闭历史记录功能

  • Type: number
  • Default:20

options.onStart

绘画开始回调函数

  • Type: function

options.onEnd

绘画结束回调函数

  • Type: function

实现原理

我们平时纸上写字,细看会发现笔画的粗细是不均匀的,这是写字过程中,笔的按压力度和移动速度不同而形成的。而在电脑手机浏览器上,虽然我们无法获取到触摸的压力,但可以通过画笔移动的速度来实现不均匀的笔画效果,让字体看起来和纸上写字一样有“笔锋”。下面介绍具体实现过程(以下展示代码只为方便理解,非最终实现代码)。

1、采集画笔经过的点坐标和时间

通过监听画布move事件采集移动经过的点坐标,并记录当前时间,然后保存到points数组中。

function onMove(event) {
    const e = event.touches && event.touches[0] || event;
    const rect = this.canvas.getBoundingClientRect();
    const point = {
        x: e.clientX - rect.left,
        y: e.clientY - rect.top,
        t: Date.now()
    }
    points.push(point);
}

2、计算两点之间移动速度

通过两点坐标计算出两点距离,再除以时间差,即可得到移动速度。

const distance = Math.sqrt(Math.pow(end.x - start.x, 2) + Math.pow(end.y - start.y, 2));
const speed = distance / (end.t - start.t);

3、计算两点之间线的宽度

得到两点间移动速度,接下来通过简单算法计算出线的宽度,其中maxWidth、minWidth、minSpeed为配置项

const addWidth = (maxWidth - minWidth) * speed / minSpeed;
const lineWidth = Math.min(Math.max(maxWidth - addWidth, minWidth), maxWidth);

另外,为了防止相邻两条线宽度差太大,而出现突兀的过渡效果,需要做下限制,其中maxWidthDiffRate为配置项,preLineWidth为上一条线的宽度

const rate = (lineWidth - preLineWidth) / preLineWidth;
const maxRate = maxWidthDiffRate / 100;
if (Math.abs(rate) > maxRate) {
    const per = rate > 0 ? maxRate : -maxRate;
    lineWidth = preLineWidth * (1 + per);
}

4、画线

现在已经知道每两点间线的宽度,接下来就是画线了。为了让线条看起来圆润以及线粗细过渡更自然,我把两点之间的线平均成三段,其中:

  1. 第一段(x0,y0 - x1,y1)线宽设置为当前线宽和上一条线宽的平均值lineWidth1 = (preLineWidth + lineWidth) / 2
  2. 第二段(x1,y1 - x2,y2)
  3. 第三段(x2,y2 - next_x0,next_y0)线宽设置为当前线宽和下一条线宽的平均值lineWidth3 = (nextLineWidth + lineWidth) / 2

开始画线,先来看第一段线,因为第一段线和上一条线相交,为了保证两条线过渡比较圆润,采用二次贝塞尔曲线,起点为上一条线的第三段起点(pre_x2, pre_y2)

ctx.lineWidth = lineWidth1
ctx.beginPath();
ctx.moveTo(pre_x2, pre_y2);
ctx.quadraticCurveTo(x0, y0, x1, y1);
ctx.stroke();

第二段线为承接第一段和第三段的过渡线,由于第一段和第三段线宽有差异,所以第二段线使用梯形填充,让过渡效果更自然。

ctx.beginPath();
ctx.moveTo(point1.x, point1.y);
ctx.lineTo(point2.x, point2.y);
ctx.lineTo(point3.x, point3.y);
ctx.lineTo(point4.x, point4.y);
ctx.fill();

第三段等画下一条线时重复上述操作即可。

快捷链接

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].