123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 |
- // pages/sign/index.js
- var canvas = null;
- const app = getApp()
- Page({
- /**
- * 页面的初始数据
- */
- data: {
- id:'',
- ctx: null,
- points: [], // 存储所有笔画
- currentStroke: [], // 当前笔画
- isDrawing: false,
- },
- /**
- * 生命周期函数--监听页面加载
- */
- onLoad(options) {
- this.setData({
- id:options.id
- })
- this.initCanvas();
- },
- /**
- * 初始化画布
- * 设置画布大小、像素比例和画笔样式
- */
- async initCanvas() {
- let that = this
- // 使用ID获取canvas组件实例
- const query = wx.createSelectorQuery();
- query.select('#canvas')
- .fields({ node: true, size: true })
- .exec((res) => {
- canvas = res[0].node;
- const ctx = canvas.getContext('2d');
- // Canvas 画布的实际绘制宽高
- const width = res[0].width
- const height = res[0].height
- // 设置画布大小,使用新的API获取设备像素比
- const dpr = wx.getWindowInfo().pixelRatio;
- //这里设置宽高,为了测试图片清晰度S
- that.setData({
- canvasWidth:width,
- canvasHeight:height,
- dpr:dpr
- })
- //这里设置宽高,为了测试图片清晰度E
- canvas.width = width * dpr;
- canvas.height = height * dpr;
- ctx.scale(dpr, dpr);
- // 设置画笔样式
- ctx.strokeStyle = '#000000';
- ctx.lineWidth = 3;
- ctx.lineCap = 'round';
- ctx.lineJoin = 'round';
- //绘制背景
- ctx.fillStyle = '#fff'
- ctx.clearRect(0, 0, canvas.width, canvas.height)
- ctx.fillRect(0, 0, canvas.width, canvas.height)
- this.setData({ ctx });
- });
- },
- /**
- * 处理触摸开始事件
- * 开始一个新的笔画,记录起始点
- * @param {Object} e - 触摸事件对象
- */
- handleTouchStart(e) {
- const { x, y } = e.touches[0];
- this.setData({
- isDrawing: true,
- currentStroke: [[x, y]]
- });
- this.data.ctx.beginPath();
- this.data.ctx.moveTo(x, y);
- },
- /**
- * 处理触摸移动事件
- * 继续绘制当前笔画的路径
- * @param {Object} e - 触摸事件对象
- */
- handleTouchMove(e) {
- if (!this.data.isDrawing) return;
- const { x, y } = e.touches[0];
- this.data.currentStroke.push([x, y]);
- this.data.ctx.lineTo(x, y);
- this.data.ctx.stroke();
- },
- /**
- * 处理触摸结束事件
- * 完成当前笔画,将其添加到笔画历史中
- */
- handleTouchEnd() {
- if (!this.data.isDrawing) return;
- this.setData({
- isDrawing: false,
- points: [...this.data.points, this.data.currentStroke],
- currentStroke: []
- });
- },
- /**
- * 清除画布内容
- * 清空所有笔画记录和画布显示
- */
- handleClear() {
- const { ctx } = this.data;
- ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
- this.setData({ points: [] });
- },
- /**
- * 撤销上一步操作
- * 移除最后一笔,并重绘剩余的笔画
- */
- handleUndo() {
- if (this.data.points.length === 0) return;
- const { ctx } = this.data;
- ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
- // 移除最后一笔
- const newPoints = this.data.points.slice(0, -1);
- this.setData({ points: newPoints });
- // 重绘所有笔画
- newPoints.forEach(stroke => {
- ctx.beginPath();
- ctx.moveTo(stroke[0][0], stroke[0][1]);
- stroke.forEach(([x, y]) => {
- ctx.lineTo(x, y);
- });
- ctx.stroke();
- });
- },
- /**
- * 提交签名
- * 将画布内容转换为图片并处理提交逻辑
- * @returns {Promise<void>}
- */
- async handleSubmit() {
- let that = this
- if (this.data.points.length === 0) {
- wx.showToast({
- title: '请先签名',
- icon: 'none'
- });
- return;
- }
- try {
- // 将画布内容转换为图片
- const tempFilePath = await new Promise((resolve, reject) => {
- let { canvasWidth, canvasHeight, dpr } = that.data
- wx.canvasToTempFilePath({
- canvas: canvas,
- destWidth:canvasWidth * dpr,
- destHeight:canvasHeight * dpr,
- success: res => resolve(res.tempFilePath),
- fail: reject
- });
- });
- // 这里可以处理签名图片,比如上传到服务器
- console.log('签名图片路径:', tempFilePath);
- // 将图片转为 Base64
- that.imageToBase64(tempFilePath, function (error, base64String) {
- if (error) {
- return;
- }
- console.log(base64String)
- that.setData({
- signature: base64String
- })
- let formData = {
- id:that.data.id,
- orderSign:base64String
- }
- // 上传 Base64 编码的图片,订单签名
- app.request.POST({
- url: app.API.orderSign,
- params: formData,
- page: that,
- isLoadingTxt: '提交中...',
- isSubmitting: true,
- successFun: true
- }).then(res => {
- wx.showToast({
- title: '确认成功',
- icon: 'success',
- duration: 2000,
- mask:true,
- complete: function () {
- setTimeout(() => {
- wx.navigateBack()
- }, 1500) //延迟时间
- }
- })
- })
- //that.selfConfirm(base64String);
- });
-
- // wx.showToast({
- // title: '提交成功',
- // icon: 'success'
- // });
- // // 返回上一页
- // setTimeout(() => {
- // wx.navigateBack();
- // }, 1500);
- } catch (error) {
- console.error('提交签名失败:', error);
- wx.showToast({
- title: '提交失败',
- icon: 'error'
- });
- }
-
- },
- //图片转baose64
- imageToBase64(tempFilePath, callback) {
- wx.getFileSystemManager().readFile({
- filePath: tempFilePath,
- encoding: 'base64',
- success: function (res) {
- // 拼接与 PC 端一致的格式
- var base64Str = "data:image/png;base64," + res.data;
- callback(null, base64Str);
- },
- fail: function (error) {
- callback(error);
- }
- });
- },
- /**
- * 生命周期函数--监听页面初次渲染完成
- */
- onReady() {
- },
- /**
- * 生命周期函数--监听页面显示
- */
- onShow() {
- },
- /**
- * 生命周期函数--监听页面隐藏
- */
- onHide() {
- },
- /**
- * 生命周期函数--监听页面卸载
- */
- onUnload() {
- },
- /**
- * 页面相关事件处理函数--监听用户下拉动作
- */
- onPullDownRefresh() {
- },
- /**
- * 页面上拉触底事件的处理函数
- */
- onReachBottom() {
- },
- /**
- * 用户点击右上角分享
- */
- onShareAppMessage() {
- }
- })
|