小程序封装手写签名组件

小程序封装手写签名组件

在本篇博客中,我们将学习如何封装一个手写签名组件,它将允许用户在小程序中手写签名,保存签名,清除签名和撤销上一步操作。

思路

使用 canvas 组件来绘制手写签名。canvas 元素允许我们绘制2D图形,我们可以使用它来绘制签名。创建一个自定义组件,该组件将包含一个 canvas 元素,以及保存、清除和撤销上一步操作的功能。

  1. 我们首先需要新建一个自定义组件文件夹。在小程序的根目录下,创建一个名为 signaImage 的文件夹。在 signaImage 文件夹下,创建一个名为 signaImage.wxml 的文件,以及一个名为 signaImage.js 的文件。
  2. signaImage.wxml 文件中,创建一个 canvas 元素,并绑定一些事件,以便我们能够绘制签名。我们还将创建一些按钮,以便用户可以保存、清除和撤销签名。
  3. signaImage.js 文件中,编写代码来处理用户与组件的交互。创建一个 signaImage 类,该类将包含保存、清除和撤销签名的方法。我们还将编写一些事件处理程序,以便我们能够绘制签名并处理用户与按钮的交互。
  4. 最后,在 app.json 文件中注册我们的组件,以便我们可以在小程序中使用它。

代码实现

signaImage.wxml

<canvas canvas-id="signaImage" bindtouchstart="touchStart" bindtouchmove="touchMove" bindtouchend="touchEnd"></canvas>
<button bindtap="save">保存</button>
<button bindtap="clear">清除</button>
<button bindtap="undo">撤销</button>

signaImage.js

class signaImage {
    
    
  constructor(ctx) {
    
    
    this.ctx = ctx;
    this.paths = [];
    this.currentPath = null;
  }
  
  start(x, y) {
    
    
    this.currentPath = {
    
    points: [{
    
    x, y}], color: '#000000', width: 2};
  }
  
  move(x, y) {
    
    
    this.currentPath.points.push({
    
    x, y});
    this.draw();
  }
  
  end() {
    
    
    this.paths.push(this.currentPath);
    this.currentPath = null;
  }
  
  undo() {
    
    
    this.paths.pop();
    this.draw();
  }
  
  clear() {
    
    
    this.paths = [];
    this.draw();
  }
  
  draw() {
    
    
    this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
    this.paths.forEach(path => {
    
    
      this.ctx.strokeStyle = path.color;
      this.ctx.lineWidth = path.width;
      this.ctx.beginPath();
      path.points.forEach((point, index) => {
    
    
        if (index === 0) {
    
    
          this.ctx.moveTo(point.x, point.y);
        } else {
    
    
          this.ctx.lineTo(point.x, point.y);
        }
      });
      this.ctx.stroke();
    });
    if (this.currentPath) {
    
    
      this.ctx.strokeStyle = this.currentPath.color;
      this.ctx.lineWidth = this.currentPath.width;
      this.ctx.beginPath();
      this.currentPath.points.forEach((point, index) => {
    
    
        if (index === 0) {
    
    
          this.ctx.moveTo(point.x, point.y);
        } else {
    
    
          this.ctx.lineTo(point.x, point.y);
        }
      });
      this.ctx.stroke();
    }
  }
}

Component({
    
    
  /**
   * 组件的属性列表
   */
  properties: {
    
    },

  /**
   * 组件的初始数据
   */
  data: {
    
    },

  /**
   * 组件的方法列表
   */
  methods: {
    
    
    save() {
    
    
      wx.canvasToTempFilePath({
    
    
        canvasId: 'signaImage',
        success: (res) => {
    
    
          wx.saveImageToPhotosAlbum({
    
    
            filePath: res.tempFilePath,
            success: () => {
    
    
              wx.showToast({
    
    title: '保存成功', icon: 'success'});
            }
          });
        }
      });
    },
    
    clear() {
    
    
      const ctx = wx.createCanvasContext('signaImage', this);
      const signaImage = new signaImage(ctx);
      signaImage.clear();
    },
    
    undo() {
    
    
      const ctx = wx.createCanvasContext('signaImage', this);
      const signaImage = new signaImage(ctx);
      signaImage.undo();
    },
    
    touchStart(event) {
    
    
      const {
    
    x, y} = event.changedTouches[0];
      const ctx = wx.createCanvasContext('signaImage', this);
      const signaImage = new signaImage(ctx);
      signaImage.start(x, y);
    },
    
    touchMove(event) {
    
    
      const {
    
    x, y} = event.changedTouches[0];
      const ctx = wx.createCanvasContext('signaImage', this);
      const signaImage = new signaImage(ctx);
      signaImage.move(x, y);
    },
    
    touchEnd(event) {
    
    
      const ctx = wx.createCanvasContext('signaImage', this);
      const signaImage = new signaImage(ctx);
      signaImage.end();
    }
  }
});

app.json

{
    
    
  "pages": [
    "pages/index/index"
  ],
  "window": {
    
    
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "WeChat",
    "navigationBarTextStyle": "black"
  },
  "usingComponents": {
    
    
    "signaImage": "/signaImage/signaImage"
  }
}

注意事项

  • signaImage.js 中, wx.createCanvasContext 方法来获取 canvas 的上下文对象。这个方法有两个参数,第一个参数是 canvas 的 id,第二个参数是组件实例对象。这里我们传入了 this,表示我们在组件内部使用这个方法。
  • signaImage.js 中,我们通过 paths 数组来存储已经绘制的路径,通过 currentPath 变量来存储当前正在绘制的路径。我们可以通过 paths 数组来撤销上一步操作,通过 currentPath 变量来清除当前正在绘制的路径。
  • signaImage.wxml 中, canvas-id 来指定 canvas 元素的 id。这个 id 将用于在 signaImage.js文件中获取 canvas 上下文对象。
  • signaImage.wxml 文件, canvas 元素的 bindtouchstartbindtouchmovebindtouchend 属性来绑定 touch 事件,从而实现手写签名功能。
  • index.wxml 文件,引入了自定义组件 signaImage,并在其中设置了组件的宽度和高度,使其适应屏幕大小。
  • index.js 文件,通过 wx.getSystemInfo 方法来获取系统信息,从而动态设置 canvas 的宽度和高度,使其适应不同的屏幕大小。

总结

本文详细介绍了如何封装一个小程序手写签名组件,包括签名、保存签名、清除签名和撤销功能。使用 canvas 来实现手写签名功能,通过自定义组件的方式来封装手写签名组件,使其可以在不同的页面中重复使用。同时,用面向对象的编程方式,将手写签名的逻辑封装在一个 signaImage 类中,使代码更加清晰易懂。最后希望能帮助大家更好地理解和使用本文介绍的手写签名组件。

猜你喜欢

转载自blog.csdn.net/2303_76218115/article/details/130196971
今日推荐