小程序canvas手写签名适配PC实现示例详解

作者:方大可 时间:2024-11-20 20:55:10 

引言

继上一篇的《丝滑流畅的手写签名功能》博文才过去没多久,我才发现 canvas 2d 无法在 PC 的小程序中使用,真实白费了我的优化了,还好之前的代码没删掉,原本以为直接简单改改就能用,发现还不是,下面看看吧。

先看看效果图

小程序canvas手写签名适配PC实现示例详解

鼠标用起来效果不怎么样,但是还是挺流畅的。

看看代码

主要就看看 Page.js 的代码吧,也就这个不一样,当然 HTML 内的 canvas 标签记得加上 canvas-id,把 type = '2d' 给去掉。

// pages/mine/signature/drawCanvas/drawCanvas.js
var app = getApp()
Page({
 data: {
   context: null,
   index: 0,
   height: 0,
   width: 0,
   // 前 一点
   preX: 0,
   preY: 0,
   preCenterX: 0,
   preCenterY: 0
 },
 onShow: function () {
   let query = wx.createSelectorQuery();
   const that = this;
   query.select('#firstCanvas').boundingClientRect();
   query.exec(function (rect) {
     let width = rect[0].width;
     let height = rect[0].height;
     that.setData({
       width,
       height
     });
     const context = wx.createCanvasContext('firstCanvas')
     that.setData({
       context: context
     })
     context.setStrokeStyle('#000000')
     context.setLineWidth(2)
     context.setFontSize(20)
   });
 },
 /**记录开始点 */
 bindtouchstart: function (e) {
   let context = this.data.context
   let curX = e.changedTouches[0].x
   let curY = e.changedTouches[0].y
   context.beginPath()
   context.moveTo(curX, curY)
   this.data.preX = curX
   this.data.preY = curY
   this.data.preCenterX = curX
   this.data.preCenterY = curY
 },
 /**记录移动点,刷新绘制 */
 bindtouchmove: function (e) {
   let context = this.data.context
   let preX = this.data.preX
   let preY = this.data.preY
   let preCenterX = this.data.preCenterX
   let preCenterY = this.data.preCenterY
   let curX = e.changedTouches[0].x
   let curY = e.changedTouches[0].y
   let deltaX = Math.abs(preX - curX)
   let deltaY = Math.abs(preY - curY)
   // 相差大于3像素的时候作二阶贝塞尔曲线
   if (deltaX >= 3 || deltaY >= 3) {
     // 前后两点中心点
     let centerX = (preX + curX) / 2
     let centerY = (preY + curY) / 2
     //这里以前一点作为控制点,中心点作为终点,起始点为上一次的中点,很流畅啊!
     context.moveTo(preCenterX, preCenterY)
     context.quadraticCurveTo(preX, preY, centerX, centerY);
     context.stroke();
     context.draw(true);
     this.data.preX = curX
     this.data.preY = curY
     this.data.preCenterX = centerX
     this.data.preCenterY = centerY
   }
 },
 /**清空画布 */
 clear: function () {
   let context = this.data.context
   context.clearRect(0, 0, this.data.width, this.data.height);
   context.draw();
   context.setStrokeStyle('#000000')
   context.setLineWidth(2)
   context.setFontSize(20)
 },
 /**导出图片 */
 export: function () {
   const that = this;
   this.data.context.draw(false, wx.canvasToTempFilePath({
     x: 0,
     y: 0,
     width: that.data.width,
     height: that.data.height,
     destWidth: that.data.width,
     destHeight: that.data.height,
     fileType: 'png',
     canvasId: 'firstCanvas',
     success(res) {
       app.log("tempFilePath:" + res.tempFilePath);
// 你的代码
     },
     fail() {
       wx.showToast({
         title: '提交失败',
         icon: 'none',
         duration: 2000
       })
     }
   }))
 },
})

下面仔细讲讲不同点

  • 获取canvas方式不一样

这里因为使用的是旧版本的 canvas,所以用的还是原来的方式获取 canvas 的。

  • 属性值多加了 preCenterX 和 preCenterY

这个就很奇怪哦,可能是因为 canvas 的用法不一样,导致使用贝塞尔曲线的时候无法正确的定位到前一点位置,也可能是里面的前一点位置就是 canvas 内移动时一系列点中前一个点的位置,放在就不对,如果按前一篇博客的方式做,出来的就是下面的效果:

小程序canvas手写签名适配PC实现示例详解

这里记得在手指初次落下的时候,初始化这两个值,并在移动后重新赋值。

  • 导出图片方式不一样

这里就是网上一大堆的办法,没什么好说的。

判别是否是PC版本

这里涉及一个判别是否是 pc 版本的小程序的问题,看下面代码

wx.getSystemInfo({
     success:function(res){
       that.setData({
         systemInfo:res,
       })
       if(res.platform == "devtools"){
           //开发者工具
       }else if(res.platform == "ios"){
           //IOS
       }else if(res.platform == "android"){
           //android
       }else {
       //电脑了吧
       }
     }
   })

在使用的地方合理选择正确的手写签名页面就可以,这里建议分别做两个页面,别把功能耦合在一起。

注意事项

  • 真机调试有问题,真机调试 SelectorQuery.exec 方法不执行回调,太坑了。要查看的话使用预览吧,预览是没问题的。

  • 还有就是横竖屏问题,我这设置的横屏实际显示的竖屏,可以在全局设置窗口改变吧,我就不动了。

  • 最后就是样式问题,为什么我的图标不行了?这里注意下 rpx 值的变化,这里是竖屏,在横屏情况下值更大,看起来效果好。

标签:小程序,canvas,手写签名,PC
0
投稿

猜你喜欢

  • 详解Python进行数据相关性分析的三种方式

    2022-05-09 18:50:12
  • 如何只取数据库的前3条记录?

    2010-06-28 18:28:00
  • DJango的创建和使用详解(默认数据库sqlite3)

    2024-01-24 20:24:39
  • 全面解读Python Web开发框架Django

    2022-06-24 19:41:45
  • JavaScript ES6 Class类实现原理详解

    2024-02-24 07:54:49
  • 基于Bootstrap分页的实例讲解(必看篇)

    2024-04-16 10:31:58
  • Python实现读取字符串按列分配后按行输出示例

    2023-08-07 19:39:14
  • MySql 缓存查询原理与缓存监控和索引监控介绍

    2024-01-29 07:30:15
  • 基于python中的TCP及UDP(详解)

    2023-12-22 19:54:38
  • MAC下mysql安装配置方法图文教程

    2024-01-17 22:38:46
  • sqlserver数据库最大Id冲突问题解决方法之一

    2024-01-28 01:48:06
  • python性能测量工具cProfile使用解析

    2022-01-28 08:22:03
  • vue中如何引入html静态页面

    2023-07-02 17:03:34
  • Python子类继承父类构造函数详解

    2023-02-27 09:13:03
  • python3+PyQt5使用数据库窗口视图

    2023-03-08 10:44:26
  • SqlServer应用之sys.dm_os_waiting_tasks 引发的疑问(中)

    2024-01-16 02:25:00
  • asp截取字符串方法

    2009-02-09 13:30:00
  • 零基础写python爬虫之抓取百度贴吧代码分享

    2022-09-04 23:55:12
  • Vue 项目性能优化方案分享

    2024-05-10 14:20:36
  • 如何把ACCESS转成SQL数据库

    2007-08-11 13:51:00
  • asp之家 网络编程 m.aspxhome.com