PHP群:95885625 Hbuilder+MUI群:81989597 站长QQ:634381967
    您现在的位置: 首页 > 开发编程 > 编程杂谈 > 正文

    微信小程序手写签名代码分享

    作者:admin来源:网络浏览:时间:2021-02-25 10:19:20我要评论
    导读:微信小程序手写签名,先来看一下效果jsPage({data:{canvasName:'handWriting',ctx:'',canvasWidth:0,canvasHeight:0,trans...
    微信小程序手写签名,先来看一下效果

    微信小程序手写签名代码分享


    js

    1. Page({ 
    2.   data: { 
    3.     canvasName: 'handWriting'
    4.     ctx: ''
    5.     canvasWidth: 0, 
    6.     canvasHeight: 0, 
    7.     transparent: 1, // 透明度 
    8.     selectColor: 'black'
    9.     lineColor: '#1a1a1a'// 颜色 
    10.     lineSize: 1.5,  // 笔迹倍数 
    11.     lineMin: 0.5,   // 最小笔画半径 
    12.     lineMax: 8,     // 最大笔画半径 
    13.     pressure: 1,     // 默认压力 
    14.     smoothness: 60,  //顺滑度,用60的距离来计算速度 
    15.     currentPoint: {}, 
    16.     currentLine: [],  // 当前线条 
    17.     firstTouch: true// 第一次触发 
    18.     radius: 1, //画圆的半径 
    19.     cutArea: { top: 0, right: 0, bottom: 0, left: 0 }, //裁剪区域 
    20.     bethelPoint: [],  //保存所有线条 生成的贝塞尔点; 
    21.     lastPoint: 0, 
    22.     chirography: [], //笔迹 
    23.     currentChirography: {}, //当前笔迹 
    24.     linePrack: [],//划线轨迹 , 生成线条的实际点 
    25.     half: 0 //绘制一半点 
    26.   }, 
    27.   onLoad() { 
    28.     let canvasName = this.data.canvasName 
    29.     let ctx = wx.createCanvasContext(canvasName) 
    30.     this.setData({ 
    31.       ctx: ctx 
    32.     }) 
    33.     var query = wx.createSelectorQuery(); 
    34.     query.select('.handCenter').boundingClientRect(rect => { 
    35.  
    36.       this.setData({ 
    37.         canvasWidth: rect.width, 
    38.         canvasHeight: rect.height 
    39.       }) 
    40.  
    41.       /* 将canvas背景设置为 白底,不设置  导出的canvas的背景为透明 */ 
    42.       this.setCanvasBg('#fff'); 
    43.  
    44.  
    45.     }).exec(); 
    46.  
    47.   }, 
    48.  
    49.   // 笔迹开始 
    50.   uploadScaleStart(e) { 
    51.     if (e.type != 'touchstart'return false
    52.     let ctx = this.data.ctx; 
    53.     ctx.setFillStyle(this.data.lineColor);  // 初始线条设置颜色 
    54.     ctx.setGlobalAlpha(this.data.transparent);  // 设置半透明 
    55.     let currentPoint = { 
    56.       x: e.touches[0].x, 
    57.       y: e.touches[0].y 
    58.     } 
    59.     let currentLine = this.data.currentLine; 
    60.     currentLine.unshift({ 
    61.       time: new Date().getTime(), 
    62.       dis: 0, 
    63.       x: currentPoint.x, 
    64.       y: currentPoint.y 
    65.     }) 
    66.     this.setData({ 
    67.       currentPoint, 
    68.     }) 
    69.     if (this.data.firstTouch) { 
    70.       this.setData({ 
    71.         cutArea: { top: currentPoint.y, right: currentPoint.x, bottom: currentPoint.y, left: currentPoint.x }, 
    72.         firstTouch: false 
    73.       }) 
    74.     } 
    75.     this.pointToLine(currentLine); 
    76.   }, 
    77.   // 笔迹移动 
    78.   uploadScaleMove(e) { 
    79.     this.data.half++; 
    80.     if ((this.data.half % 3) != 0) { 
    81.       return false 
    82.     } 
    83.     if (e.type != 'touchmove'return false
    84.     if (e.cancelable) { 
    85.       // 判断默认行为是否已经被禁用 
    86.       if (!e.defaultPrevented) { 
    87.         e.preventDefault(); 
    88.       } 
    89.     } 
    90.     let point = { 
    91.       x: e.touches[0].x, 
    92.       y: e.touches[0].y 
    93.     } 
    94.     //测试裁剪 
    95.     if (point.y < this.data.cutArea.top) { 
    96.       this.data.cutArea.top = point.y; 
    97.     } 
    98.     if (point.y < 0) this.data.cutArea.top = 0; 
    99.  
    100.     if (point.x > this.data.cutArea.right) { 
    101.       this.data.cutArea.right = point.x; 
    102.     } 
    103.     if (this.data.canvasWidth - point.x <= 0) { 
    104.       this.data.cutArea.right = this.data.canvasWidth; 
    105.     } 
    106.     if (point.y > this.data.cutArea.bottom) { 
    107.       this.data.cutArea.bottom = point.y; 
    108.     } 
    109.     if (this.data.canvasHeight - point.y <= 0) { 
    110.       this.data.cutArea.bottom = this.data.canvasHeight; 
    111.     } 
    112.     if (point.x < this.data.cutArea.left) { 
    113.       this.data.cutArea.left = point.x; 
    114.     } 
    115.     if (point.x < 0) this.data.cutArea.left = 0; 
    116.     this.setData({ 
    117.       lastPoint: this.data.currentPoint, 
    118.       currentPoint: point 
    119.     }) 
    120.     let currentLine = this.data.currentLine 
    121.     currentLine.unshift({ 
    122.       time: new Date().getTime(), 
    123.       dis: this.distance(this.data.currentPoint, this.data.lastPoint), 
    124.       x: point.x, 
    125.       y: point.y 
    126.     }) 
    127.     this.pointToLine(currentLine); 
    128.   }, 
    129.   // 笔迹结束 
    130.   uploadScaleEnd(e) { 
    131.     if (e.type != 'touchend'return 0; 
    132.     let point = { 
    133.       x: e.changedTouches[0].x, 
    134.       y: e.changedTouches[0].y 
    135.     } 
    136.     this.setData({ 
    137.       lastPoint: this.data.currentPoint, 
    138.       currentPoint: point 
    139.     }) 
    140.     let currentLine = this.data.currentLine 
    141.     currentLine.unshift({ 
    142.       time: new Date().getTime(), 
    143.       dis: this.distance(this.data.currentPoint, this.data.lastPoint), 
    144.       x: point.x, 
    145.       y: point.y 
    146.     }) 
    147.     if (currentLine.length > 2) { 
    148.       var info = (currentLine[0].time - currentLine[currentLine.length - 1].time) / currentLine.length; 
    149.       //$("#info").text(info.toFixed(2)); 
    150.     } 
    151.     //一笔结束,保存笔迹的坐标点,清空,当前笔迹 
    152.     //增加判断是否在手写区域; 
    153.     this.pointToLine(currentLine); 
    154.     var currentChirography = { 
    155.       lineSize: this.data.lineSize, 
    156.       lineColor: this.data.lineColor 
    157.     }; 
    158.     var chirography = this.data.chirography 
    159.     chirography.unshift(currentChirography); 
    160.     this.setData({ 
    161.       chirography 
    162.     }) 
    163.     var linePrack = this.data.linePrack 
    164.     linePrack.unshift(this.data.currentLine); 
    165.     this.setData({ 
    166.       half: 0, 
    167.       linePrack, 
    168.       currentLine: [] 
    169.     }) 
    170.   }, 
    171.   retDraw() { 
    172.     this.data.ctx.clearRect(0, 0, 700, 730) 
    173.     this.data.ctx.draw(); 
    174.  
    175.     //设置canvas背景 
    176.     this.setCanvasBg("#fff"); 
    177.   }, 
    178.  
    179.   //画两点之间的线条;参数为:line,会绘制最近的开始的两个点; 
    180.   pointToLine(line) { 
    181.     this.calcBethelLine(line); 
    182.     return
    183.   }, 
    184.   //计算插值的方式; 
    185.   calcBethelLine(line) { 
    186.     if (line.length <= 1) { 
    187.       line[0].r = this.data.radius; 
    188.       return
    189.     } 
    190.     let x0, x1, x2, y0, y1, y2, r0, r1, r2, len, lastRadius, dis = 0, time = 0, curveValue = 0.5; 
    191.     if (line.length <= 2) { 
    192.       x0 = line[1].x 
    193.       y0 = line[1].y 
    194.       x2 = line[1].x + (line[0].x - line[1].x) * curveValue; 
    195.       y2 = line[1].y + (line[0].y - line[1].y) * curveValue; 
    196.       x1 = x0 + (x2 - x0) * curveValue; 
    197.       y1 = y0 + (y2 - y0) * curveValue;; 
    198.  
    199.     } else { 
    200.       x0 = line[2].x + (line[1].x - line[2].x) * curveValue; 
    201.       y0 = line[2].y + (line[1].y - line[2].y) * curveValue; 
    202.       x1 = line[1].x; 
    203.       y1 = line[1].y; 
    204.       x2 = x1 + (line[0].x - x1) * curveValue; 
    205.       y2 = y1 + (line[0].y - y1) * curveValue; 
    206.     } 
    207.     //从计算公式看,三个点分别是(x0,y0),(x1,y1),(x2,y2) ;(x1,y1)这个是控制点,控制点不会落在曲线上;实际上,这个点还会手写获取的实际点,却落在曲线上 
    208.     len = this.distance({ x: x2, y: y2 }, { x: x0, y: y0 }); 
    209.     lastRadius = this.data.radius; 
    210.     for (let n = 0; n < line.length - 1; n++) { 
    211.       dis += line[n].dis; 
    212.       time += line[n].time - line[n + 1].time; 
    213.       if (dis > this.data.smoothness) break
    214.     } 
    215.     this.setData({ 
    216.       radius: Math.min(time / len * this.data.pressure + this.data.lineMin, this.data.lineMax) * this.data.lineSize 
    217.     }); 
    218.     line[0].r = this.data.radius; 
    219.     //计算笔迹半径; 
    220.     if (line.length <= 2) { 
    221.       r0 = (lastRadius + this.data.radius) / 2; 
    222.       r1 = r0; 
    223.       r2 = r1; 
    224.       //return; 
    225.     } else { 
    226.       r0 = (line[2].r + line[1].r) / 2; 
    227.       r1 = line[1].r; 
    228.       r2 = (line[1].r + line[0].r) / 2; 
    229.     } 
    230.     let n = 5; 
    231.     let point = []; 
    232.     for (let i = 0; i < n; i++) { 
    233.       let t = i / (n - 1); 
    234.       let x = (1 - t) * (1 - t) * x0 + 2 * t * (1 - t) * x1 + t * t * x2; 
    235.       let y = (1 - t) * (1 - t) * y0 + 2 * t * (1 - t) * y1 + t * t * y2; 
    236.       let r = lastRadius + (this.data.radius - lastRadius) / n * i; 
    237.       point.push({ x: x, y: y, r: r }); 
    238.       if (point.length == 3) { 
    239.         let a = this.ctaCalc(point[0].x, point[0].y, point[0].r, point[1].x, point[1].y, point[1].r, point[2].x, point[2].y, point[2].r); 
    240.         a[0].color = this.data.lineColor; 
    241.         this.bethelDraw(a, 1); 
    242.         point = [{ x: x, y: y, r: r }]; 
    243.       } 
    244.     } 
    245.     this.setData({ 
    246.       currentLine: line 
    247.     }) 
    248.   }, 
    249.   //求两点之间距离 
    250.   distance(a, b) { 
    251.     let x = b.x - a.x; 
    252.     let y = b.y - a.y; 
    253.     return Math.sqrt(x * x + y * y); 
    254.   }, 
    255.   ctaCalc(x0, y0, r0, x1, y1, r1, x2, y2, r2) { 
    256.     let a = [], vx01, vy01, norm, n_x0, n_y0, vx21, vy21, n_x2, n_y2; 
    257.     vx01 = x1 - x0; 
    258.     vy01 = y1 - y0; 
    259.     norm = Math.sqrt(vx01 * vx01 + vy01 * vy01 + 0.0001) * 2; 
    260.     vx01 = vx01 / norm * r0; 
    261.     vy01 = vy01 / norm * r0; 
    262.     n_x0 = vy01; 
    263.     n_y0 = -vx01; 
    264.     vx21 = x1 - x2; 
    265.     vy21 = y1 - y2; 
    266.     norm = Math.sqrt(vx21 * vx21 + vy21 * vy21 + 0.0001) * 2; 
    267.     vx21 = vx21 / norm * r2; 
    268.     vy21 = vy21 / norm * r2; 
    269.     n_x2 = -vy21; 
    270.     n_y2 = vx21; 
    271.     a.push({ mx: x0 + n_x0, my: y0 + n_y0, color: "#1A1A1A" }); 
    272.     a.push({ c1x: x1 + n_x0, c1y: y1 + n_y0, c2x: x1 + n_x2, c2y: y1 + n_y2, ex: x2 + n_x2, ey: y2 + n_y2 }); 
    273.     a.push({ c1x: x2 + n_x2 - vx21, c1y: y2 + n_y2 - vy21, c2x: x2 - n_x2 - vx21, c2y: y2 - n_y2 - vy21, ex: x2 - n_x2, ey: y2 - n_y2 }); 
    274.     a.push({ c1x: x1 - n_x2, c1y: y1 - n_y2, c2x: x1 - n_x0, c2y: y1 - n_y0, ex: x0 - n_x0, ey: y0 - n_y0 }); 
    275.     a.push({ c1x: x0 - n_x0 - vx01, c1y: y0 - n_y0 - vy01, c2x: x0 + n_x0 - vx01, c2y: y0 + n_y0 - vy01, ex: x0 + n_x0, ey: y0 + n_y0 }); 
    276.     a[0].mx = a[0].mx.toFixed(1); 
    277.     a[0].mx = parseFloat(a[0].mx); 
    278.     a[0].my = a[0].my.toFixed(1); 
    279.     a[0].my = parseFloat(a[0].my); 
    280.     for (let i = 1; i < a.length; i++) { 
    281.       a[i].c1x = a[i].c1x.toFixed(1); 
    282.       a[i].c1x = parseFloat(a[i].c1x); 
    283.       a[i].c1y = a[i].c1y.toFixed(1); 
    284.       a[i].c1y = parseFloat(a[i].c1y); 
    285.       a[i].c2x = a[i].c2x.toFixed(1); 
    286.       a[i].c2x = parseFloat(a[i].c2x); 
    287.       a[i].c2y = a[i].c2y.toFixed(1); 
    288.       a[i].c2y = parseFloat(a[i].c2y); 
    289.       a[i].ex = a[i].ex.toFixed(1); 
    290.       a[i].ex = parseFloat(a[i].ex); 
    291.       a[i].ey = a[i].ey.toFixed(1); 
    292.       a[i].ey = parseFloat(a[i].ey); 
    293.     } 
    294.     return a; 
    295.   }, 
    296.   bethelDraw(point, is_fill, color) { 
    297.     let ctx = this.data.ctx; 
    298.     ctx.beginPath(); 
    299.     ctx.moveTo(point[0].mx, point[0].my); 
    300.     if (undefined != color) { 
    301.       ctx.setFillStyle(color); 
    302.       ctx.setStrokeStyle(color); 
    303.     } else { 
    304.       ctx.setFillStyle(point[0].color); 
    305.       ctx.setStrokeStyle(point[0].color); 
    306.     } 
    307.     for (let i = 1; i < point.length; i++) { 
    308.       ctx.bezierCurveTo(point[i].c1x, point[i].c1y, point[i].c2x, point[i].c2y, point[i].ex, point[i].ey); 
    309.     } 
    310.     ctx.stroke(); 
    311.     if (undefined != is_fill) { 
    312.       ctx.fill();  
    313.     } 
    314.     ctx.draw(true
    315.   }, 
    316.   selectColorEvent(event) { 
    317.     console.log(event) 
    318.     var color = event.currentTarget.dataset.colorValue; 
    319.     var colorSelected = event.currentTarget.dataset.color; 
    320.     this.setData({ 
    321.       selectColor: colorSelected, 
    322.       lineColor: color 
    323.     }) 
    324.   }, 
    325.   setCanvasBg(color) { 
    326.     this.data.ctx.rect(0, 0, this.data.canvasWidth, this.data.canvasHeight - 4); 
    327.     // ctx.setFillStyle('red') 
    328.     this.data.ctx.setFillStyle(color) 
    329.     this.data.ctx.fill()  //设置填充 
    330.     this.data.ctx.draw()    //开画 
    331.  
    332.   } 
    333. }) 
    wxml

    1. <view class="container"
    2.   <view class="handCenter"
    3.     <canvas class="handWriting" disable-scroll="true" bindtouchstart="uploadScaleStart" bindtouchmove="uploadScaleMove" 
    4.       bindtouchend="uploadScaleEnd" bindtap="mouseDown" canvas-id="handWriting"
    5.     </canvas> 
    6.   </view> 
    7.   <button style="margin-top:20rpx" catchtap="retDraw">重写</button> 
    8. </view> 

    wxss

    1. .handWriting { 
    2.   background: #fff; 
    3.   width: 500rpx; 
    4.   height: 700rpx; 
    5.   
    6. .handRight { 
    7.   display: inline-flex; 
    8.   align-items: center; 
    9.   
    10. .handCenter { 
    11.   box-shadow: 0 4px 12px rgba(0,0,0,.25); 
    12.   flex: 5; 
    13.   overflow: hidden; 
    14.   box-sizing: border-box; 
    15.   margin-top: 30rpx; 
    16.   
    17. .handTitle { 
    18.   transform: rotate(90deg); 
    19.   flex: 1; 
    20.   color: #666; 
    21.   
    22. .handBtn button { 
    23.   font-size: 28rpx; 
    24.   
    25. .handBtn { 
    26.   height: 95vh; 
    27.   display: inline-flex; 
    28.   flex-direction: column; 
    29.   justify-content: space-between; 
    30.   align-content: space-between; 
    31.   flex: 1; 
    32.   
    33. .delBtn { 
    34.   position: absolute; 
    35.   top: 250rpx; 
    36.   left: 0rpx; 
    37.   transform: rotate(90deg); 
    38.   color: #180303; 
    39.   
    40. .delBtn image { 
    41.   position: absolute; 
    42.   top: 13rpx; 
    43.   left: 25rpx; 
    44.   
    45. .subBtn { 
    46.   position: absolute; 
    47.   bottom: 52rpx; 
    48.   left: -3rpx; 
    49.   display: inline-flex; 
    50.   transform: rotate(90deg); 
    51.   background: #008ef6; 
    52.   color: #fff; 
    53.   margin-bottom: 30rpx; 
    54.   text-align: center; 
    55.   justify-content: center; 
    56.   
    57. .black-select { 
    58.   width: 60rpx; 
    59.   height: 60rpx; 
    60.   position: absolute; 
    61.   top: 30rpx; 
    62.   left: 25rpx; 
    63. .black-select.color_select { 
    64.   width: 90rpx; 
    65.   height: 90rpx; 
    66.   top: 30rpx; 
    67.   left: 10rpx; 
    68. .red-select { 
    69.   width: 60rpx; 
    70.   height: 60rpx; 
    71.   position: absolute; 
    72.   top:140rpx; 
    73.   left:25rpx; 
    74. .red-select.color_select { 
    75.   width: 90rpx; 
    76.   height: 90rpx; 
    77.   top: 120rpx; 
    78.   left: 10rpx; 

    转载请注明(B5教程网)原文链接:https://b5.mxunkeji.com/content-74-6511-1.html
    相关热词搜索: