微信小程式(學習六) -- 回退Canvas繪圖
阿新 • • 發佈:2019-02-06
關於Canvas如何繪製塗鴉,請看上一章
該節是基於上一節做的修改,佈局和樣式表都一樣。
<view class="box_box6" bindtap="recoverCanvas">
<image src='/images/recover.png'></image>
</view>
.canvas_tools .box_box6 {
height: 100rpx;
width: 100rpx;
border-radius: 50rpx;
margin-top: 25rpx;
margin-left: 25rpx;
background-color : #afa99c;
}
.canvas_tools .box_box6 image{
height: 60rpx;
width: 60rpx;
margin-top: 20rpx;
margin-left: 20rpx;
}
// pages/draw.js
Page({
/**
* 頁面的初始資料
*/
data: {
isClear: false,
penColor: 'red',
lineWidth: 5,
curContexts: [],
pathCount: 0,
contextCount: 0,
},
/**
* 觸控開始
*/
touchStart: function (e) {
//得到觸控點的座標
this.startX = e.changedTouches[0].x
this.startY = e.changedTouches[0].y
this.context = wx.createCanvasContext("myCanvas", this)
var arr = new Array();
this.data.curContexts[this.data.pathCount] = arr;
this.setData({
curContexts: this .data.curContexts,
contextCount: 0,
})
if (this.data.isClear) { //判斷是否啟用的橡皮擦功能 ture表示清除 false表示畫畫
this.context.setStrokeStyle('#ffffff') //設定線條樣式 此處設定為畫布的背景顏色 橡皮擦原理就是:利用擦過的地方被填充為畫布的背景顏色一致 從而達到橡皮擦的效果
this.context.setLineCap('round') //設定線條端點的樣式
this.context.setLineJoin('round') //設定兩線相交處的樣式
this.context.setLineWidth(20) //設定線條寬度
this.context.save(); //儲存當前座標軸的縮放、旋轉、平移資訊
this.context.beginPath() //開始一個路徑
this.context.arc(this.startX, this.startY, 5, 0, 2 * Math.PI, true); //新增一個弧形路徑到當前路徑,順時針繪製 這裡總共畫了360度 也就是一個圓形
this.context.fill(); //對當前路徑進行填充
this.context.restore(); //恢復之前儲存過的座標軸的縮放、旋轉、平移資訊
} else {
// 設定畫筆顏色
this.context.setStrokeStyle(this.data.penColor);
// 設定線條寬度
this.context.setLineWidth(this.data.lineWidth);
this.context.setLineCap('round') // 讓線條圓潤
this.context.beginPath()
}
},
/**
* 手指觸控後移動
*/
touchMove: function (e) {
var startX1 = e.changedTouches[0].x
var startY1 = e.changedTouches[0].y
if (this.data.isClear) { //判斷是否啟用的橡皮擦功能 ture表示清除 false表示畫畫
this.context.save(); //儲存當前座標軸的縮放、旋轉、平移資訊
this.context.moveTo(this.startX, this.startY); //把路徑移動到畫布中的指定點,但不建立線條
this.context.lineTo(startX1, startY1); //新增一個新點,然後在畫布中建立從該點到最後指定點的線條
this.context.stroke(); //對當前路徑進行描邊
this.context.restore(); //恢復之前儲存過的座標軸的縮放、旋轉、平移資訊
this.startX = startX1;
this.startY = startY1;
} else {
this.context.moveTo(this.startX, this.startY)
this.context.lineTo(startX1, startY1)
this.context.stroke()
this.startX = startX1;
this.startY = startY1;
}
//只是一個記錄方法呼叫的容器,用於生成記錄繪製行為的actions陣列。context跟<canvas/>不存在對應關係,一個context生成畫布的繪製動作陣列可以應用於多個<canvas/>
var actions = this.context.getActions();
this.data.curContexts[this.data.pathCount][this.data.contextCount] = actions;
this.setData ({
curContexts: this.data.curContexts
})
wx.drawCanvas({
canvasId: 'myCanvas',
reserve: true,
actions: actions // 獲取繪圖動作陣列
});
this.data.contextCount++;
},
/**
* 觸控結束
*/
touchEnd: function (e) {
this.touchMove(e);
this.setData({
pathCount: (this.data.pathCount + 1),
contextCount: 0
});
},
/**
* 畫筆選擇
*/
penSelect: function (options) {
var lineWidth = options.target.dataset.param;
console.log("lineWidth:" + lineWidth);
this.setData ({
isClear: false,
lineWidth: lineWidth,
});
},
/**
* 顏色選擇
*/
colorSelect: function (options) {
var penColor = options.target.dataset.param;
console.log("penColor:" + penColor);
this.setData({
isClear: false,
penColor: penColor,
});
},
/**
* 清除塗鴉資訊
*/
clearCanvas: function (options) {
console.log("clearCanvas");
this.setData({
isClear: true
});
},
/**
* 回退一步
*/
recoverCanvas: function (options) {
this.context.clearRect(0,0,750, 1280);
this.context.draw();
if (this.data.pathCount > 0) {
for (var i = 0; i < this.data.pathCount - 1; i++) {
for (var j = 0; j < this.data.curContexts[i].length; j++) {
wx.drawCanvas({
canvasId: 'myCanvas',
reserve: true,
actions: this.data.curContexts[i][j] // 獲取繪圖動作陣列
});
}
}
var pathCount = this.data.pathCount - 1;
this.data.curContexts[pathCount] = null;
this.setData({
pathCount: pathCount,
contextCount: 0,
});
}
}
})
回退其實採用的一種重繪製方法,效能上面不是很好,如果大家有更好的辦法,也請分享出來。