微信小程序电子签名实现
实现签名方法就是使用canvas
<canvas canvas-id="firstCanvas" id='firstCanvas' bindtouchstart="bindtouchstart" bindtouchmove="bindtouchmove"></canvas>
<!-- 旋装图片 -->
<canvas canvas-id="saveImg" id='saveImg'></canvas>
<view class="clear" hidden="{{!sureBtn}}" bindtap='clear'>重新签名</view>
<view class="save {{sureBtn?'sureBet':''}}" bindtap='export'>完成</view>
在canvas上绑定手指点击事件和移动事件:
上图是想要实现的效果,
有几个考虑的点:
- 1、签字区域和按钮都是横屏显示的,这个首先想到的使用微信小程序的方法直接在json文件设置"pageOrientation":"landscape",但效果是整个屏幕横屏,标题也横,效果不同。只能通过css方法旋转实现按钮横屏展示
- 2、签字区域有个占位符,签字的时候需要去除,首先想到的是用个view去占位,然后点击切换为canvas,但是个人觉的略显刻意,就用canvas来旋转实现,bindtouchstart时让文字为空,这样也多了一个设置默认文字的函数
- 3、生成图片,在使用wx.canvasToTempFilePath({})的时候发现生成的图片也是反着的,这里用了一个笨方法,添加一个canvas来单独处理图片旋转
//index.js
//获取应用实例
const app = getApp()
Page({
data: {
context: null,
index: 0,
height: 0,
width: 0,
writeTips: '请清晰书写您的英文签名',
writeTipsTrue: true,
src:'',
sureBtn:false,
saveContext:null
},
/**记录开始点 */
bindtouchstart: function (e) {
let { writeTipsTrue } = this.data
if (writeTipsTrue) {
this.data.context.clearRect(0, 0, this.data.width, this.data.height);
this.setData({ writeTipsTrue: false, sureBtn:true })
}
this.data.context.moveTo(e.changedTouches[0].x, e.changedTouches[0].y)
},
/**记录移动点,刷新绘制 */
bindtouchmove: function (e) {
this.data.context.setLineWidth(2) // 设置线条宽度
this.data.context.lineTo(e.changedTouches[0].x, e.changedTouches[0].y);
this.data.context.stroke();
this.data.context.draw(true);
this.data.context.moveTo(e.changedTouches[0].x, e.changedTouches[0].y);
},
/**清空画布 */
clear () {
let context = this.data.context
this.setData({ writeTipsTrue: true, sureBtn:false })
context.clearRect(0, 0, this.data.width, this.data.height);
// this.data.saveContext.clearRect(0, 0, this.data.height, this.data.width);
context.save();
context.setTransform(1, 0, 0, 1, Math.ceil(this.data.width / 2), 155); // 旋转画布 默认文字区域
context.rotate(Math.PI / 2);
let str = this.data.writeTips;
context.setFontSize(24)
context.setFillStyle('#ADADB2');
context.fillText(str, 0, 0)
context.restore();
context.draw()
},
/**导出图片 */
export () {
const that = this;
let signImg;
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: that.data.width,
height: that.data.height,
destWidth: that.data.width,
destHeight: that.data.height,
canvasId: 'firstCanvas',
success (res) {
console.log(res.tempFilePath)
signImg = res.tempFilePath
that.setData({ src1: signImg})
//下载图片
wx.getImageInfo({
src: signImg, // 签字画布生成的暂存地址
success (res) {
// canvas绘制图片需要下载图片或者getImageInfo
console.log(res,'res');
let rototalImg = res.path
that.setData({ src: rototalImg})
if (rototalImg) {
// 单独处理图片旋转
that.saveImg(rototalImg)
}
}
})
}
})
},
// drew img
saveImg (signImg){
if (!this.data.sureBtn){
app.toast(this, {
type: 'text',
text: '请清晰书写您的英文签名'
})
return
}
// 旋转图
let that = this
const context = wx.createCanvasContext('saveImg');
this.setData({saveContext:context})
context.translate(that.data.width / 2, that.data.height / 2)
context.setTransform(1, 0, 0, 1, 0, Math.ceil(that.data.height / 2) -20);
context.rotate(-Math.PI / 2)
// context.drawImage(signImg, -that.data.width / 2, -that.data.height / 2, that.data.width, that.data.height)
context.drawImage(signImg, 0, 0, that.data.width, that.data.height)
// context.fill()
//绘制图片 生成图片函数写在draw()的回调中,不然会出现还没有画图就生成图片的问题
context.draw(true,()=>{
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: that.data.height,
height: that.data.width,
destWidth: that.data.height,
destHeight: that.data.width,
canvasId: 'saveImg',
fileType: 'png',
success: function (res) {
var tempFilePath = res.tempFilePath;
console.log(tempFilePath);
that.setData({ src: tempFilePath })
// 生成图片 并返回上一页 赋值
let curPages = getCurrentPages();
var prevPage = curPages[curPages.length - 2]
prevPage.setData({
signImg: tempFilePath,
})
wx.navigateBack({
delta: 1
});
},
fail: function (res) {
console.log(res);
}
});
})
},
onLoad: function (options) {
},
onShow: function () {
// 进入页面渲染canvas
let query = wx.createSelectorQuery();
const that = this;
let context
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.save();
// context.translate(Math.ceil(width / 2) - 20,0)
context.setTransform(1, 0, 0, 1, Math.ceil(width / 2), 155);
context.rotate(Math.PI / 2);
let str = that.data.writeTips;
// context.fillText(str, Math.ceil((width - context.measureText(str).width) / 2), Math.ceil(height / 2) - 20)
context.setFontSize(24)
context.setFillStyle('#ADADB2');
// context.fillRect(0, 0, that.data.height, that.data.width);
context.fillText(str, 0, 0)
context.restore();
context.draw()
});
},
// 弹窗
onToast(){
app.toast(this, {
type: 'text',
text: '生成成功'
})
},
onShareAppMessage: (res) => { }
})
相关注释代码中都有,也么有优化,有好的方法,还希望大佬们多多指点
微信小程序电子签名实现的更多相关文章
- 微信小程序刚注册快速达到1000uv
一.什么是微信小程序uv UV:是累计独立访问,1个微信号就是一个uv,多次访问不算 大家想提升微信小程序uv都是为了开通流量主 二.流量主开通标准 达到1000uv就可以开通:严重违纪不 ...
- 微信小程序开发心得
微信小程序也已出来有一段时间了,最近写了几款微信小程序项目,今天来说说感受. 首先开发一款微信小程序,最主要的就是针对于公司来运营的,因为,在申请appid(微信小程序ID号)时候,需要填写相关的公司 ...
- 微信小程序体验(2):驴妈妈景区门票即买即游
驴妈妈因为出色的运营能力,被腾讯选为首批小程序内测单位.驴妈妈的技术开发团队在很短的时间内完成了开发任务,并积极参与到张小龙团队的内测问题反馈.驴妈妈认为,移动互联网时代,微信是巨大的流量入口,也是旅 ...
- 微信小程序(微信应用号)组件讲解
这篇文章主要讲解微信小程序的组件. 首先,讲解新建项目.现在有句话:招聘三天以上微信小程序开发,这个估计只能去挖微信的工程师了.技术新,既然讲解,那我们就从开始建项目讲解. 打开微信web开发者工具, ...
- 神技!微信小程序(应用号)抢先入门教程(附最新案例DEMO-豆瓣电影)持续更新
微信小程序 Demo(豆瓣电影) 由于时间的关系,没有办法写一个完整的说明,后续配合一些视频资料,请持续关注 官方文档:https://mp.weixin.qq.com/debug/wxadoc/de ...
- 通过微信小程序看前端
前言 2016年9月22日凌晨,微信官方通过“微信公开课”公众号发布了关于微信小程序(微信应用号)的内测通知.整个朋友圈瞬间便像炸开了锅似的,各种揣测.介绍性文章在一夜里诞生.而真正收到内测邀请的公众 ...
- 快速了解微信小程序的使用,一个根据小程序的框架开发的todos app
微信官方已经开放微信小程序的官方文档和开发者工具.前两天都是在看相关的新闻来了解小程序该如何开发,这两天官方的文档出来之后,赶紧翻看了几眼,重点了解了一下文档中框架与组件这两个部分,然后根据简易教程, ...
- 来自于微信小程序的一封简讯
9月21晚间,微信向部分公众号发出公众平台-微信应用号(小程序)的内测邀请,向来较为低调的微信在这一晚没人再忽视它了. 来自个人博客:Damonare的个人博客 一夜之间火了的微信应用号你真的知道吗? ...
- 微信小程序前端源码逻辑和工作流
看完微信小程序的前端代码真的让我热血沸腾啊,代码逻辑和设计一目了然,没有多余的东西,真的是大道至简. 废话不多说,直接分析前端代码.个人观点,难免有疏漏,仅供参考. 文件基本结构: 先看入口app.j ...
随机推荐
- MySQL从库维护经验分享
前言: MySQL 主从架构应该是最常用的一组架构了.从库会实时同步主库传输来的数据,一般从库可以作为备用节点或作查询使用.其实不只是主库需要多关注,从库有时候也要经常维护,本篇文章将会分享几点从库维 ...
- 2021年主流CRM系统盘点
面对市面上五花八门的CRM系统,相信您在选择的时候肯定是一头雾水.哪个CRM系统功能最强大?哪个CRM系统性价比最高?哪个CRM系统最适合企业使用?本篇文章小编将选出几家有代表性的CRM系统,并进行对 ...
- [xml模块、hashlib模块、subprocess模块、os与sys模块、configparser模块]
[xml模块.hashlib模块.subprocess模块.os与sys模块.configparser模块] xml模块 XML:全称 可扩展标记语言,为了能够在不同的平台间继续数据的交换,使交换的数 ...
- createrepo 建立本地yum源
linux使用createrepo制作本地yum源 目录 linux使用createrepo制作本地yum源 安装createrepo软件包 进入本地rpm包目录 执行完后可以看到生成的repod ...
- 【CentOS_7】一行shell实现自动清理过期日志
昨日web测试环境登录白屏,慌忙登上机器查看,半天没找到问题. 不知哪根筋不对,df -h 一看 , /dev/sda1 已经100%. 立马 du -sh *,发现log日志有点大. 手工清理后,业 ...
- spec cpu2006 官网
https://www.spec.org/cpu2006/Docs/install-guide-unix.html
- MySQL给某个用户给某个库表设置权限
-- 用root(最高权限的用户)进行以下操作-- 创建数据库:emc_power CREATE DATABASE emc_power DEFAULT CHARACTER SET utf8 COLLA ...
- IIS 10 设置FTP Passive Mode 固定端口
1. Run [Start] - [Server Manager] and Click [Tools] - [Internet Information Services (IIS) Manager]. ...
- HDFS 高可用(HA)环境搭建
步骤一:修改公共属性配置 core-site.xml 文件 [root@node-01 ~]# cd /root/apps/hadoop-3.2.1/etc/hadoop [root@node-01 ...
- 网上的说TB6560存在的问题
https://www.amobbs.com/thread-5506456-2-1.html