vue移動端使用canvas簽名的實現(xiàn)
效果

canvas畫板移動端 .gif
需求
在一些項目業(yè)務中,經(jīng)常會使用到畫板,讓用戶自己去寫/畫一些東西做標示,比如說在線簽電子合約、簽名等,如果不用插件,那么如何使用h5的canvas畫布來實現(xiàn)這一需求呢? 【本篇只討論移動端,PC端請看上篇】
分析
很明顯,我們需要一個canvas,關于canvas的一些基本操作可以在w3school或者別的一些平臺上熟悉一下,其實本例也是基礎操作。本案例在vue中完成。(脫離vue也一樣。)
- 首先,需要一個canvas畫布
- 其次,考慮邏輯
- 把邏輯實現(xiàn)
1. canvas畫布
隨意布局的一個畫布,此處值得注意的是如果canvas的寬高確定,則在html>canvas中直接寫寬高,如果不確定,根據(jù)別的元素變化,那么可以在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. 邏輯分析
由于本篇只討論移動端端,因此無非是在畫布上監(jiān)聽三個觸摸事件:touchstart、touchmove、touchend。
那么,在這三個事件中,分別需要做什么呢?
touchstart
開始滑動按下,需要做:
- 獲取觸摸點做畫布上的位置
- 存為一個點坐標(起始點)
- 以起始點建立一個路徑
- 開啟畫布操作
touchmove
觸摸滑動時,又要做那些準備呢?
- 判斷是否開啟畫布操作,如果沒開啟就禁止繪制,因此先判斷是否當前狀態(tài)可繪制
- 獲取觸摸點做畫布上的位置
- 上一個點到這一個點作連線
- 繪制出來
- 當前點存儲,下一次用
touchend
滑動結束,事件結束:
- closePath() // 停止繪制
- 關閉畫布操作的開關
好了,其實就是這三個事件,理清楚之后去代碼實現(xiàn)就簡單得多了。附上代碼一份。
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); // 把路徑移動到畫布中的指定點,不創(chuàng)建線條(起始點)
this.ctx.lineTo(x, y); // 添加一個新點,然后創(chuàng)建從該點到畫布中最后指定點的線條,不創(chuàng)建線條
this.ctx.stroke(); // 繪制
this.point.x = x, this.point.y = y; // 重置點坐標為上一個坐標
}
},
// 滑動結束
mEnd () {
if(this.moving) {
this.ctx.closePath(); // 停止繪制
this.moving = false; // 關閉繪制開關
}
},
},
思考
- 上一篇,在PC端完成繪制,本篇如法炮制,在移動端也順利完成,相比pc端只是稍微的修改了一下獲取坐標點的算法而已。那么PC端和移動端如何并存呢?
- 出錯了,怎么重新繪制呢?
- 繪制完成后,怎么保存呢?
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
vue + any-touch實現(xiàn)一個iscroll 實現(xiàn)拖拽和滑動動畫效果
這篇文章主要介紹了vue + any-touch實現(xiàn)一個iscroll實現(xiàn)拖拽和滑動動畫效果,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-04-04
Vue中使用event的坑及解決event is not defined
這篇文章主要介紹了Vue中使用event的坑及解決event is not defined,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03

