tanda tangan halus H5 hadir dengan tanda tangan tulisan tangan ujung pena dan mendukung penggunaan PC/seluler
toko mini program mini perpustakaan manajemen multi-negara, mendukung penggunaan program mini multi-platform
Dipengaruhi oleh epidemi, proses tanpa kertas dan kontrak elektronik menjadi populer, permintaan akan tanda tangan elektronik juga terus meningkat, dan pengalaman tanda tangan secara bertahap meningkat, dari awalnya menggambar garis di atas kanvas sederhana, hingga mengejar garis halus dan bulat. , dan kemudian membutuhkan kertas Jepang. Efek tepi pena sama dengan tulisan di atasnya, dll. Ada banyak perpustakaan tanda tangan open source siap pakai di Internet. Diantaranya, efek guratan tanda tangan_pad lebih baik, tetapi Anda masih akan menemukan perasaan bergerigi yang jelas saat menggunakannya pemahaman sendiri. Pada saat yang sama, Kami juga mengembangkan versi program mini dan membagikannya kepada siswa yang membutuhkan.
npm install mini-smooth-signature
# 或
yarn add mini-smooth-signature
Mendukung program mini WeChat/Alipay/DingTalk/QQ. Berikut ini adalah kode pengujian untuk platform DingTalk. Silakan lihat Contoh kode contoh setiap platform. Program mini di platform lain dapat merujuk ke contoh yang ada untuk memverifikasi penggunaannya.
< view >
< canvas
id = " signature "
width = " {{width * scale}} "
height = " {{height * scale}} "
style = " width:{{width}}px;height:{{height}}px; "
disable-scroll = " {{true}} "
onTouchStart = " handleTouchStart "
onTouchMove = " handleTouchMove "
onTouchCancel = " handleTouchEnd "
onTouchEnd = " handleTouchEnd "
/>
</ view >
import Signature from 'mini-smooth-signature' ;
Page ( {
data : {
width : 320 ,
height : 200 ,
scale : 2 ,
} ,
onReady ( ) {
this . initSignature ( )
} ,
// 初始化
initSignature ( ) {
const ctx = dd . createCanvasContext ( 'signature' ) ;
this . signature = new Signature ( ctx , {
width : this . data . width ,
height : this . data . height ,
scale : this . data . scale ,
getImagePath : ( ) => {
return new Promise ( ( resolve ) => {
ctx . toTempFilePath ( {
success : res => resolve ( res . filePath ) ,
} )
} )
}
} ) ;
} ,
// 绑定touchstart事件
handleTouchStart ( e ) {
const pos = e . touches [ 0 ] ;
this . signature . onDrawStart ( pos . x , pos . y ) ;
} ,
// 绑定touchmove事件
handleTouchMove ( e ) {
const pos = e . touches [ 0 ] ;
this . signature . onDrawMove ( pos . x , pos . y ) ;
} ,
// 绑定touchend/touchcancel事件
handleTouchEnd ( ) {
this . signature . onDrawEnd ( ) ;
} ,
} ) ;
Semua item konfigurasi bersifat opsional
const signature = new Signature ( ctx , {
width : 300 ,
height : 600 ,
scale : 2 ,
minWidth : 4 ,
maxWidth : 10 ,
color : '#1890ff' ,
bgColor : '#efefef' ,
} ) ;
pilihan.lebar
Lebar kanvas yang sebenarnya dirender pada halaman (px)
number
pilihan.tinggi
Ketinggian kanvas sebenarnya yang dirender pada halaman (px)
number
pilihan.skala
Zoom kanvas
number
pilihan.warna
warna kuas
string
options.bgColor
Warna latar belakang kanvas
string
pilihan.getImagePath
Fungsi janji yang menghasilkan gambar sementara untuk menyimpan riwayat. Jika item ini tidak dikonfigurasi, fungsi pembatalan tidak tersedia.
promise
opsi.toDataURL
Hasilkan fungsi gambar base64
function
pilihan.requestAnimationFrame
Dieksekusi saat penggambaran ulang berikutnya terjadi. Digunakan untuk meningkatkan kinerja pengecatan dan mengurangi kelambatan dan ketidakhalusan
function
pilihan.openSmooth
Apakah akan mengaktifkan efek tepi pena, diaktifkan secara default
boolean
pilihan.minWidth
Lebar minimum kuas (px), lebar minimum kuas saat ujung pena dihidupkan
number
pilihan.maxWidth
Lebar maksimum kuas (px), lebar maksimum kuas saat tepi kuas diaktifkan, atau lebar normal kuas saat tepi kuas tidak diaktifkan
number
pilihan.minSpeed
Kecepatan minimum (px/ms) yang diperlukan kuas untuk mencapai lebar minimum. Kisaran nilainya adalah 1,0-10,0. Semakin kecil nilainya, semakin mudah kuas menjadi tipis, dan efek ujung kuas akan semakin besar jelas. Anda dapat menyesuaikan sendiri efek tampilan dan memilih nilai yang Anda puas.
number
pilihan.maxWidthDiffRate
Persentase maksimum pertambahan (penurunan) lebar dua garis yang berdekatan. Kisaran nilainya adalah 1-100. Untuk mencapai efek guratan, lebar kuas akan berubah seiring dengan kecepatan kuas terlalu besar, efek transisi akan tiba-tiba, gunakan maxWidthDiffRate untuk membatasi perbedaan lebar agar efek transisi lebih natural. Anda dapat menyesuaikan sendiri efek tampilannya dan memilih nilai yang Anda puas.
number
pilihan.maxHistoryLength
Batasi jumlah catatan sejarah, yaitu jumlah maksimum yang dapat dibatalkan. Melewati 0 akan mematikan fungsi catatan sejarah.
number
// 画布上下文context
signature . ctx
// 清屏
signature . clear ( )
// 撤销,如果未配置getImagePath,则不可用
signature . undo ( )
// 获取base64图片,若未配置toDataURL,则不可用
signature . toDataURL ( )
// 是否为空
signature . isEmpty ( )
Biasanya kita menulis di atas kertas, jika diperhatikan lebih dekat akan terlihat bahwa ketebalan guratannya tidak merata, hal ini disebabkan oleh perbedaan gaya tekan dan kecepatan gerak pena pada saat proses menulis. Di browser komputer dan seluler, meskipun kita tidak bisa mendapatkan tekanan sentuhan, kita bisa menggunakan kecepatan gerakan kuas untuk mendapatkan efek goresan yang tidak rata, membuat font terlihat setajam tulisan di atas kertas. , proses implementasi spesifik diperkenalkan di bawah (kode yang ditunjukkan di bawah ini hanya untuk memudahkan pemahaman, bukan kode implementasi akhir).
Kumpulkan koordinat titik yang dipindahkan dengan mendengarkan peristiwa perpindahan kanvas, catat waktu saat ini, lalu simpan ke larik titik.
function onTouchMove ( x , y ) {
const point = { x , y , t : Date . now ( ) }
points . push ( point ) ;
} ;
Hitung jarak antara dua titik melalui koordinat kedua titik tersebut, lalu bagi dengan selisih waktu untuk mendapatkan kecepatan gerak.
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 ) ;
Dapatkan kecepatan pergerakan antara dua titik, lalu hitung lebar garis melalui algoritma sederhana, di mana maxWidth, minWidth, dan minSpeed adalah item konfigurasi
const addWidth = ( maxWidth - minWidth ) * speed / minSpeed ;
const lineWidth = Math . min ( Math . max ( maxWidth - addWidth , minWidth ) , maxWidth ) ;
Selain itu, untuk mencegah perbedaan lebar antara dua garis yang berdekatan menjadi terlalu besar dan menyebabkan efek transisi yang tiba-tiba, perlu dilakukan pembatasan, di mana maxWidthDiffRate adalah item konfigurasi dan preLineWidth adalah lebar baris sebelumnya.
const rate = ( lineWidth - preLineWidth ) / preLineWidth ;
const maxRate = maxWidthDiffRate / 100 ;
if ( Math . abs ( rate ) > maxRate ) {
const per = rate > 0 ? maxRate : - maxRate ;
lineWidth = preLineWidth * ( 1 + per ) ;
}
Sekarang setelah Anda mengetahui lebar garis antara setiap dua titik, langkah selanjutnya adalah menggambar garis. Agar garis terlihat membulat dan transisi antar ketebalan garis menjadi lebih natural, saya rata-ratakan garis antara dua titik menjadi tiga segmen, dimana:
Mulailah menggambar garis, pertama-tama lihat ruas garis pertama, karena ruas garis pertama berpotongan dengan garis sebelumnya, untuk menjamin kelancaran transisi antara kedua garis tersebut, digunakan kurva Bezier kuadrat, dan titik awalnya titik adalah titik awal dari segmen ketiga baris sebelumnya (pre_x2, pre_y2)
ctx . lineWidth = lineWidth1
ctx . beginPath ( ) ;
ctx . moveTo ( pre_x2 , pre_y2 ) ;
ctx . quadraticCurveTo ( x0 , y0 , x1 , y1 ) ;
ctx . stroke ( ) ;
Ruas garis kedua merupakan garis peralihan yang menghubungkan ruas pertama dan ruas ketiga. Karena lebar garis ruas pertama dan ruas ketiga berbeda, maka ruas garis kedua diisi dengan trapesium agar efek peralihannya lebih besar. alami.
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 ( ) ;
Ulangi operasi di atas saat menggambar baris berikutnya di paragraf ketiga.