React 實現 2D 畫板功能
阿新 • • 發佈:2019-01-05
在移動端或者PC端我們來模擬畫板的實現, 支援清除和匯出功能,此處簡單實現,僅作開發參考。
效果演示
主要程式碼演示
/* 此模組用於實現簽名繪圖功能 */
// 需要用到的變數定義
let clickX = new Array();
let clickY = new Array();
let clickDrag = new Array();
let paint;
let point = {notFirst:false};
let canvasDiv = null; // 初始化畫布父盒子
let canvas = document.createElement('canvas'); // 建立畫板
let context = canvas.getContext("2d"); // 建立2d畫布
let canvasWidth = 0; // 初始化畫布寬度
let canvasHeight = 0; // 初始化畫布高度
// 可匯出圖片的標識
let _exportable = false;
/* ------------ 需要用到的一些功能函式 ------------ */
function addClick(x, y, dragging) {
clickX.push(x);
clickY.push(y);
clickDrag.push(dragging);
}
function draw (){
_exportable = true;
while (clickX.length > 0 ) {
point.bx = point.x;
point.by = point.y;
point.x = clickX.pop();
point.y = clickY.pop();
point.drag = clickDrag.pop();
context.beginPath();
if (point.drag && point.notFirst) {
context.moveTo(point.bx, point.by);
} else {
point.notFirst = true;
context.moveTo(point.x - 1, point.y);
}
context.lineTo(point.x, point.y);
context.closePath();
context.stroke();
}
}
/* 建立畫布背景和畫筆 */
function create() {
// 以下是建立畫布背景
context.rect(0, 0, canvasWidth, canvasHeight);
context.fillStyle="#f2f2f2"; // 圖片北京色是灰色,此處去除會變黑色
context.fill();
// 設定畫筆屬性
context.strokeStyle = "#666";
context.lineJoin = "round";
context.lineWidth = 2;
// 預設值清理
clickX = new Array();
clickY = new Array();
clickDrag = new Array();
_exportable = false;
}
export default {
/* 初始化 */
init(canvasDivDom, classname) {
canvasDiv = canvasDivDom; // 傳入畫布父盒子
canvasWidth = canvasDiv.clientWidth; // 獲取父盒子寬度
canvasHeight = canvasDiv.clientHeight; // 獲取父盒子高度
// 設定屬性並追加元素
canvas.setAttribute('width', canvasWidth);
canvas.setAttribute('height', canvasHeight);
canvasDiv.appendChild(canvas);
// 建立畫布背景和畫筆
create();
// 開始監控畫圖
this.listen(classname);
},
/* 畫圖時的監控 */
listen(classname) {
// 獲取盒子需要的引數
let left = canvas.getBoundingClientRect().left;
let top = canvas.getBoundingClientRect().top;
// 支援 移動端
canvasDiv.addEventListener("touchstart", function(e){
paint = true;
classname && (this.className = classname);
(e.touches) && (e = e.touches[0]);
addClick(e.pageX - left, e.pageY - top);
draw();
});
canvasDiv.addEventListener("touchmove", function(e){
if(!paint) {
return;
}
(e.touches) && (e = e.touches[0]);
addClick(e.pageX - left, e.pageY - top, true);
draw();
});
canvasDiv.addEventListener("touchend", function(e){
paint = false;
});
// 支援 PC 端
canvasDiv.addEventListener("mousedown", function(e){
paint = true;
classname && (this.className = classname);
addClick(e.pageX - left, e.pageY - top);
draw();
});
canvasDiv.addEventListener("mousemove", function(e){
if(!paint) {
return;
}
addClick(e.pageX - left, e.pageY - top, true);
draw();
});
canvasDiv.addEventListener("mouseup", function(e){
paint = false;
});
canvasDiv.addEventListener("mouseleave", function(e){
paint = false;
});
},
/* 清理 */
clear() {
// 使用此方式來清理畫布
canvas.width = canvas.width;
canvas.height = canvas.height;
create(); // 重新建立畫布背景和畫筆
_exportable = false; // 清理之後無法匯出
},
/* 匯出圖片 */
exportImg() {
if(!_exportable) {
return -1; // 說明此處無法匯出圖片
}
return canvas.toDataURL("image/png");
}
}
支援平臺
- 移動端
- PC端