1. 程式人生 > 程式設計 >vue移動端使用canvas簽名的實現

vue移動端使用canvas簽名的實現

效果

canvas畫板移動端 .gif

需求

  在一些專案業務中,經常會使用到畫板,讓使用者自己去寫/畫一些東西做標示,比如說線上籤電子合約、簽名等,如果不用外掛,那麼如何使用h5的canvas畫布來實現這一需求呢? 【本篇只討論移動端,PC端請看上篇】

分析

  很明顯,我們需要一個canvas,關於canvas的一些基本操作可以在w3school或者別的一些平臺上熟悉一下,其實本例也是基礎操作。本案例在vue中完成。(脫離vue也一樣。)

  • 首先,需要一個canvas畫布
  • 其次,考慮邏輯
  • 把邏輯實現

1. canvas畫布


隨意佈局的一個畫布,此處值得注意的是如果canvas的寬高確定,則在html>canvas中直接寫寬高,如果不確定,根據別的元素變化,那麼可以在js中初始化畫布時寫。

html

<div class="boardBox" ref="boardBox">
  <canvas ref="board"
      
  </canvas>
</div>

佈局

.boardBox{
  margin: 30px auto;
  width: 90vw;
  height: 25vh;
  background: #f9f9f9;
  canvas{
    border: 1px solid #b3b3b3;
  }
}

畫布初始化

let board = this.$refs.board;  // 獲取DOM
board.width = this.$refs.boardBox.offsetWidth; // 設定畫布寬
board.height = this.$refs.boardBox.offsetHeight;  // 設定畫布高
this.ctx = board.getContext('2d');  // 二維繪圖
this.ctx.strokeStyle = '#000';  // 顏色
this.ctx.lineWidth = 3; // 線條寬度

2. 邏輯分析

由於本篇只討論移動端端,因此無非是在畫布上監聽三個觸控事件:touchstart、touchmove、touchend。

那麼,在這三個事件中,分別需要做什麼呢?

touchstart

開始滑動按下,需要做:

  • 獲取觸控點做畫布上的位置
  • 存為一個點座標(起始點)
  • 以起始點建立一個路徑
  • 開啟畫布操作

touchmove

觸控滑動時,又要做那些準備呢?

  • 判斷是否開啟畫布操作,如果沒開啟就禁止繪製,因此先判斷是否當前狀態可繪製
  • 獲取觸控點做畫布上的位置
  • 上一個點到這一個點作連線
  • 繪製出來
  • 當前點儲存,下一次用

touchend

滑動結束,事件結束:

  • closePath() // 停止繪製
  • 關閉畫布操作的開關

好了,其實就是這三個事件,理清楚之後去程式碼實現就簡單得多了。附上程式碼一份。

3. 程式碼

CSS略,如初始化即可,不是重點。

<div class="boardBox" ref="boardBox">
  <canvas ref="board"
      @touchstart="mStart"
      @touchmove="mMove"
      @touchend="mEnd">
  </canvas>
</div>
data() {
  return {
    ctx: null,point: {
      x: 0,y: 0
    },moving: false  // 是否正在繪製中且移動
  };
},mounted() {
  let board = this.$refs.board;  // 獲取DOM
  board.width = this.$refs.boardBox.offsetWidth; // 設定畫布寬
  board.height = this.$refs.boardBox.offsetHeight;  // 設定畫布高
  this.ctx = board.getContext('2d');  // 二維繪圖
  this.ctx.strokeStyle = '#000';  // 顏色
  this.ctx.lineWidth = 3; // 線條寬度
},methods: {
  // 觸控(開始)
  mStart (e) {
    console.log(e);
    let x = e.touches[0].clientX - e.target.offsetLeft,y = e.touches[0].clientY - e.target.offsetTop;  // 獲取觸控點在畫板(canvas)的座標
    this.point.x = x;
    this.point.y = y;
    this.ctx.beginPath();
    this.moving = true;
  },// 滑動中...
  mMove (e) {
    if(this.moving) {
      let x = e.touches[0].clientX - e.target.offsetLeft,y = e.touches[0].clientY - e.target.offsetTop;  // 獲取觸控點在畫板(canvas)的座標
      this.ctx.moveTo(this.point.x,this.point.y);  // 把路徑移動到畫布中的指定點,不建立線條(起始點)
      this.ctx.lineTo(x,y); // 新增一個新點,然後建立從該點到畫布中最後指定點的線條,不建立線條
      this.ctx.stroke(); // 繪製
      this.point.x = x,this.point.y = y;  // 重置點座標為上一個座標
    }
  },// 滑動結束
  mEnd () {
    if(this.moving) {
      this.ctx.closePath();  // 停止繪製
      this.moving = false;  // 關閉繪製開關
    }
  },},

思考

  1. 上一篇,在PC端完成繪製,本篇如法炮製,在移動端也順利完成,相比pc端只是稍微的修改了一下獲取座標點的演算法而已。那麼PC端和移動端如何並存呢?
  2. 出錯了,怎麼重新繪製呢?
  3. 繪製完成後,怎麼儲存呢?

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。