微信小程序横屏签字板

基于 無苼 大佬的代码修改并添加了注释

  1. 新增hasDrawn变量,避免保存空白画布的情况。
  2. 默认图片保存格式从PNG改为JPG
  3. 将线头端点改为了圆角

小程序横屏签字板

json

{
  "navigationBarTitleText": "签字板",
  "pageOrientation": "landscape",
  "usingComponents": {}
}

wxml

<canvas type="2d" id="canvas" disable-scroll="true" bindtouchmove="handleMove" bindtouchstart="handleStart" binderror="handleError" style="width:{{width}}px;height:{{height}}px;"></canvas>
<view class="btn">
  <button class="clear" bindtap="clearClick">重签</button>
  <button class="confirm" bindtap="saveClick">确认</button>
</view>

wxss

page {
  background-color: #fff;
}

canvas {
  border: 1px solid #00000014;
  background-color: #F5F7FB;
}

.btn {
  width: 100%;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  box-sizing: border-box;
  padding-right: 30rpx;
  height: 60px;
}

.btn button {
  margin: 0;
  border-radius: 0;
  width: 85rpx;
  height: 30rpx;
  font-size: 13rpx;
  color: #006ec7;
}

.btn .clear {
  margin-right: 12rpx;
  color: #3670F5;
  background-color: #6795ff33;
}

.btn .confirm {
  color: #fff;
  background-color: #3670F5;
}

js

Page({
  data: {
    canvas: '', // 画布节点
    ctx: null, // 画布上下文
    pr: 0, // 像素比
    width: 0, // 画布宽度
    height: 0, // 画布高度
    preX: 0, // 上一个触碰点的X坐标
    preY: 0, // 上一个触碰点的Y坐标
    hasDrawn: false, // 是否已经绘制过
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function () {
    this.getSystemInfo(); // 获取系统信息
    this.initCanvas(); // 初始化画布
  },
  onShow() {
    this.listenToWindowResize(); // 监听窗口尺寸变化
  },
  // 监听窗口尺寸变化
  listenToWindowResize() {
    const that = this;
    // 监听器,当窗口尺寸改变时更新画布尺寸并重新初始化画布
    wx.onWindowResize((res) => {
      const {
        windowWidth,
        windowHeight
      } = res.size;
      that.updateCanvasSize(windowWidth, windowHeight);
      that.initCanvas(); // 重新初始化画布
    });
  },
  // 获取系统信息
  getSystemInfo() {
    const that = this;
    // 获取系统信息
    wx.getSystemInfo({
      success: ({
        pixelRatio,
        windowWidth,
        windowHeight
      }) => {
        that.updateCanvasSize(windowWidth, windowHeight); // 更新画布尺寸
        that.setData({
          pr: pixelRatio // 设备像素比
        });
      }
    });
  },
  // 更新画布尺寸
  updateCanvasSize(width, height) {
    this.setData({
      width, // 窗口宽度
      height: height - 60, // 窗口高度减去底部导航栏高度,
    });
  },
  // 触摸开始事件处理
  handleStart(e) {
    const {
      changedTouches
    } = e; // 获取触控事件中的触摸点信息
    if (changedTouches.length > 0) {
      const touch = changedTouches[0]; // 获取第一个触摸点
      this.data.ctx.beginPath(); // 开始新的路径
      this.data.preX = touch.x; // 更新前一个X坐标
      this.data.preY = touch.y; // 更新前一个Y坐标
      this.setData({
        hasDrawn: true // 设置hasDrawn为true,表示已经开始绘制
      });
    }
  },
  // 触摸移动事件处理
  handleMove(e) {
    const {
      changedTouches
    } = e; // 获取触控事件中的触摸点信息
    if (changedTouches.length > 0) {
      const touch = changedTouches[0]; // 获取第一个触摸点
      const {
        preX,
        preY
      } = this.data; // 获取前一个X和Y坐标
      this.data.ctx.moveTo(preX, preY); // 移动到前一个坐标
      this.data.ctx.lineTo(touch.x, touch.y); // 绘制一条线到当前坐标
      this.data.ctx.stroke(); // 执行绘制
      this.data.preX = touch.x; // 更新前一个X坐标
      this.data.preY = touch.y; // 更新前一个Y坐标
    }
  },
  // 错误处理
  handleError(e) {
    console.log("画布触摸错误" + e);
  },
  // 初始化画布
  initCanvas() {
    const {
      width,
      height,
      pr
    } = this.data; // 获取数据中的宽度、高度和像素比
    const query = wx.createSelectorQuery().in(this); // 创建选择器查询对象
    query.select('#canvas').fields({ // 选择id为canvas的元素并获取其节点和尺寸信息
      node: true,
      size: true
    }).exec(([res]) => {
      const canvas = res.node; // 获取canvas节点
      const ctx = canvas.getContext('2d'); // 获取2D绘图上下文
      canvas.width = width * pr; // 设置canvas宽度
      canvas.height = height * pr; // 设置canvas高度
      ctx.scale(pr, pr); // 根据像素比缩放绘图上下文
      ctx.lineGap = 'round'; // 设置线条间隙样式为圆角
      ctx.lineJoin = 'round'; // 设置连接两条线段的拐角样式为圆角
      ctx.lineWidth = 4; // 设置线条宽度
      ctx.font = '40px Arial'; // 设置字体样式
      ctx.fillStyle = '#ecf0ef'; // 设置填充颜色
      ctx.lineCap = 'round'; // 设置线条端点样式为圆角
      this.setData({
        ctx, // 设置绘图上下文
        canvas // 设置canvas节点
      });
    });
  },
  //清除画布
  clearClick() {
    const {
      width,
      height
    } = this.data; // 获取数据中的宽度和高度
    this.data.ctx.clearRect(0, 0, width, height); // 清除画布上的内容
    this.setData({
      hasDrawn: false // 设置hasDrawn为false,表示未开始绘制
    });
  },
  //保存图片
  saveClick: function () {
    // 如果尚未开始绘制
    if (!this.data.hasDrawn) {
      wx.showToast({
        title: '请先在画布上绘制内容',
        icon: 'none'
      });
      return; // 结束函数执行
    }
    // 将画布转换为临时文件
    wx.canvasToTempFilePath({
      x: 0,
      y: 0,
      width: this.data.width,
      height: this.data.height,
      destWidth: this.data.width * this.data.pr,
      destHeight: this.data.height * this.data.pr,
      canvasId: 'canvas',
      canvas: this.data.canvas,
      fileType: 'jpg',
      success(res) {
        // 保存图片到相册
        wx.saveImageToPhotosAlbum({
          filePath: res.tempFilePath,
          success(res) {
            wx.showToast({
              title: '保存成功',
              icon: 'success'
            })
          }
        })
      }
    })
  },
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值