小程序canvas手写签名适配PC实现示例详解
作者:方大可 发布时间:2024-11-20 20:55:10
引言
继上一篇的《丝滑流畅的手写签名功能》博文才过去没多久,我才发现 canvas 2d 无法在 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 内移动时一系列点中前一个点的位置,放在就不对,如果按前一篇博客的方式做,出来的就是下面的效果:
这里记得在手指初次落下的时候,初始化这两个值,并在移动后重新赋值。
导出图片方式不一样
这里就是网上一大堆的办法,没什么好说的。
判别是否是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 值的变化,这里是竖屏,在横屏情况下值更大,看起来效果好。
猜你喜欢
- python自带日志管理模块logging,使用时可进行模块化配置,详细可参考博文Python日志采集(详细)。但logging配置起来比较
- 方法1: 用file_get_contents 以get方式获取内容:<?php$url='https://www.aspxh
- JavaScript(JS)网页–动态生成表格,供大家参考,具体内容如下在网页中,动态生成列表的内容,将数组中的object加入到列表中(没
- 一、前言python在数组中随机取值有现成的方法,但是要给每个随机值被取到的概率加权重的话,可以参考下面这个方法二、实现方式import r
- 我就废话不多说了,大家还是直接看代码吧!# -*- coding:utf-8 -*- # File: ceshitianqiimport u
- 关于变量分箱主要分为两大类:有监督型和无监督型对应的分箱方法:A. 无监督:(1) 等宽 (2) 等频 (3) 聚类B. 有监督:(1) 卡
- 目录前言魔法方法__init__方法__new__方法__call__方法__str___方法__del___方法__enter__ &am
- 本文实例分析了Python自定义进程池。分享给大家供大家参考,具体如下:代码说明一切:#encoding=utf-8#author: wal
- 如果只是因为浏览者改变了浏览器的设置,或者因为浏览器不兼容,使自己精心制作的网页变得“面目全非”,那多令人沮丧!下面我们以网页爱好者的常用工
- 一些很实用且必用的js小脚本代码:脚本1:进入页面后自动播放音乐或其它声音文件<embed src="音乐地址&q
- 在python中,文件使用十分频繁,本文将向大家介绍python文件路径的操作:得到指定文件路径、得到当前文件名、判断文件路径是否存在、获得
- 在平时的工作中,我们的目录有很多的视频文件,如果你没有一个好的视频分类习惯,在找视频素材的时候会很费时,通过对视频的分辨路进行分类可以在需要
- 本文实例讲述了python获取本地计算机名字的方法。分享给大家供大家参考。具体如下:import sys, sockethostname =
- 前言最近网站从HTTPS转为HTTP,更换了网址,旧网址做了301重定向,折腾有点大,于是在百度站长平台提交网址,不管是主动推送还是手动提交
- Python安装selenium包打开命令行窗口,进入python交互环境python尝试导入selenium包,报错,说明尚未安装sele
- 继续flask的学习之旅。今天介绍flask的登陆管理模块,还记得上一篇中的blog小项目么,登录是咱们自己写的验证代码,大概有以下几个步骤
- 在Python中,正则表达式的group和groups方法是非常有用的函数,用于处理匹配结果的分组信息。group方法是re.MatchOb
- MySQL5.7版本开始支持JSON格式,在创建表时,可以指定列表的数据类型为JSON,但是如何在JSON格式上创建索引呢??本人做了一个简
- 本文实例讲述了JS使用百度地图API自动获取地址和经纬度操作。分享给大家供大家参考,具体如下:在实际工作中我们经常会遇到这样的问题,但是当我
- Python 如何转换string到float?简单几步,让你轻松解决。打开软件,新建python项目,如图所示右键菜单中创建.py文件,如