想象一下,用幾行代碼就能創造出如此逼真的圖像和動畫,仿佛將藝術與科技完美融合,前端開發的Canvas技術正是這個數字化時代中最具魔力的一環,它不僅僅是網頁的一部分,更是一個無限創意的畫布,一個讓你的想象力自由馳騁的平臺。
目錄
基礎頁面搭建
繪畫操作
按鈕點擊事件
最后總結
基礎頁面搭建
接下來借助canvas實現一個簡易的畫版操作,首先這里我們設置一下畫布的一些基礎布局樣式:
<body><canvas id="canvas" width="800" height="600" style="border: 1px solid #ccc;"></canvas><hr><button id="boldBtn" type="button">粗線條</button><button id="thinBtn" type="button">細線條</button><button id="saveBtn" type="button">保持簽名</button><input type="color" name="" id="color" value=""><button class="clearBtn">橡皮擦</button><button id="nullBtn">清空畫布</button>
</body>
實現的效果如下所示,一個比較簡陋的畫布,以及一些基礎操作的按鈕:
繪畫操作
接下來我們開始實現繪畫操作的功能,通過監聽鼠標不同情況的事件來實現畫布上書寫內容的操作,首先這里我們先繪制畫布以及獲取對應的dom元素進行操作:
<script>// 獲取canvas畫布繪制上下文對象以及獲取2d畫筆對象let canvas = document.getElementById("canvas"); let ctx = canvas.getContext("2d");ctx.lineJoin = 'round'; // 線條連接處為圓角ctx.lineCap = 'round'; // 線條端點為圓角// 獲取DOM元素let boldBtn = document.getElementById("boldBtn");let thinBtn = document.getElementById("thinBtn");let saveBtn = document.getElementById("saveBtn");let color = document.getElementById("color");let clearBtn = document.getElementsByClassName("clearBtn")[0];let nullBtn = document.getElementById("nullBtn");
</script>
接下來開始開始監聽鼠標的按下、彈起、移動以及離開畫布的四種情況的操作,完整代碼如下:
<script>// 獲取canvas畫布繪制上下文對象以及獲取2d畫筆對象let canvas = document.getElementById("canvas"); let ctx = canvas.getContext("2d");ctx.lineJoin = 'round'; // 線條連接處為圓角ctx.lineCap = 'round'; // 線條端點為圓角// 獲取DOM元素let boldBtn = document.getElementById("boldBtn");let thinBtn = document.getElementById("thinBtn");let saveBtn = document.getElementById("saveBtn");let color = document.getElementById("color");let clearBtn = document.getElementsByClassName("clearBtn")[0];let nullBtn = document.getElementById("nullBtn");// 設置是否開始繪畫的變量let isDraw = false;// 鼠標按下去函數canvas.onmousedown = function(e) {isDraw = true; // 開始繪畫ctx.beginPath(); // 開始路徑// 獲取鼠標點擊的坐標let x = e.pageX - canvas.offsetLeft; let y = e.pageY - canvas.offsetTop; ctx.moveTo(x, y); // 移動到當前點}// 鼠標移動函數canvas.onmousemove = function(e) {if (isDraw) { // 如果開始繪畫let x = e.pageX - canvas.offsetLeft; let y = e.pageY - canvas.offsetTop; ctx.lineTo(x, y); // 繪制ctx.stroke()}}// 鼠標彈起函數canvas.onmouseup = function(e) {isDraw = false; // 結束繪畫ctx.closePath(); // 結束路徑}// 鼠標離開畫布函數canvas.onmouseleave = function(e) {isDraw = false; // 結束繪畫ctx.closePath(); // 結束路徑}
</script>
最終呈現的效果如下所示:
按鈕點擊事件
接下來給畫布下方的按鈕設置對應的點擊事件,讓其能夠實現對應的功能,如下:
粗線條:這里設置點擊事件函數如下,遮蓋策略設置在現有畫布上下文之上繪制新圖形,點擊之后寬度增加到20,并添加對應激活類名active,刪除其他按鈕可能存在的active類名:
// 粗線條函數
boldBtn.onclick = function(e) {ctx.globalCompositeOperation = 'source-over'; ctx.lineWidth = 20boldBtn.classList.add("active");thinBtn.classList.remove("active");clearBtn.classList.remove("active");
}
細線條:這里設置點擊事件函數如下,遮蓋策略設置在現有畫布上下文之上繪制新圖形,點擊之后寬度減少到2,并添加對應激活類名active,刪除其他按鈕可能存在的active類名:
// 細線條函數
thinBtn.onclick = function(e) {ctx.globalCompositeOperation = 'source-over'; ctx.lineWidth = 2thinBtn.classList.add("active");boldBtn.classList.remove("active");clearBtn.classList.remove("active");
}
保存簽名:獲取圖片數據并創建一個a標簽進行文件下載:
// 保存簽名函數
saveBtn.onclick = function(e) {let urlData = canvas.toDataURL(); // 獲取圖片數據// let img = new Image()// img.src = urlData; // 圖片地址// document.body.appendChild(img); // 添加圖片到bodylet downloadA = document.createElement("a"); // 創建a標簽downloadA.setAttribute("download", "簽名"); // 設置下載文件名downloadA.href = urlData; // 設置a標簽的地址downloadA.click(); // 點擊a標簽
}
修改顏色:設置監聽函數,動態修改canvas顏色:
// 顏色選擇函數
color.onchange = function(e) {ctx.strokeStyle = color.value; // 設置線條顏色
}
橡皮擦:這里設置點擊事件函數如下,遮蓋策略設置現有內容保持在新圖形不重疊的地方,點擊之后區域呈現空白,并添加對應激活類名active,刪除其他按鈕可能存在的active類名:
// 橡皮擦函數
clearBtn.onclick = function(e) {// 清除畫布ctx.globalCompositeOperation = 'destination-out';ctx.lineWidth = 30clearBtn.classList.add("active");boldBtn.classList.remove("active");thinBtn.classList.remove("active");
}
清空畫布:調用canvas函數直接清除整個畫布的內容:
// 清空畫布函數
nullBtn.onclick = function(e) {ctx.clearRect(0, 0, 800, 600);
}
最終呈現的效果如下所示:
最后總結
本次代碼實現了一個簡單的畫板功能,讓用戶可以在網頁上繪制、調整線條粗細、選擇顏色、保存簽名等操作。以下是代碼的實現思路:
1)HTML結構部分:
在<body>中包含一個 <canvas> 元素,用于繪制圖形。
一組按鈕和一個顏色選擇器,用于控制畫筆的粗細、顏色以及清除和保存繪制的功能。
2)CSS部分:
定義了一個按鈕的樣式 .active,用于表示當前選中狀態,例如粗線條、細線條、橡皮擦等按鈕會根據點擊狀態變化背景顏色。
3)JavaScript部分:
《1》獲取元素:
使用 document.getElementById 和 document.getElementsByClassName 獲取 <canvas> 和各種控制按鈕。
《2》繪圖相關事件:
canvas.onmousedown:鼠標按下時開始繪畫,記錄起始點。
canvas.onmousemove:鼠標移動時,如果正在繪畫(isDraw為真),則根據當前鼠標位置繪制線條。
canvas.onmouseup 和 canvas.onmouseleave:鼠標抬起或離開畫布時結束繪畫路徑。《3》功能按鈕事件:
粗線條 (boldBtn) 和 細線條 (thinBtn):設置線條寬度,并通過 classList 控制按鈕的選中狀態。
保存簽名 (saveBtn):使用 canvas.toDataURL() 獲取繪制內容的DataURL,創建一個下載鏈接,允許用戶保存簽名。
顏色選擇 (color):通過 color.onchange 設置繪制線條的顏色。
橡皮擦 (clearBtn):使用 ctx.globalCompositeOperation = 'destination-out' 實現擦除效果,清除畫布上的內容。
清空畫布 (nullBtn):使用 ctx.clearRect() 清除整個畫布的內容。《4》繪圖上下文:
使用 getContext('2d') 獲取 Canvas 2D 渲染上下文對象 ctx,設置線條的樣式(圓角連接和端點)。
這段代碼整合了 HTML、CSS 和 JavaScript,提供了一個簡單而功能豐富的在線繪圖工具,用戶可以通過點擊不同的按鈕和操作來繪制、擦除、保存簽名等。完整代碼如下:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>button.active {color: #fff;background-color: orange;}</style>
</head><body><canvas id="canvas" width="800" height="600" style="border: 1px solid #ccc;"></canvas><hr><button id="boldBtn" type="button">粗線條</button><button id="thinBtn" type="button">細線條</button><button id="saveBtn" type="button">保存簽名</button><input type="color" name="" id="color" value=""><button class="clearBtn">橡皮擦</button><button id="nullBtn">清空畫布</button>
<script>// 獲取canvas畫布繪制上下文對象以及獲取2d畫筆對象let canvas = document.getElementById("canvas"); let ctx = canvas.getContext("2d");ctx.lineJoin = 'round'; // 線條連接處為圓角ctx.lineCap = 'round'; // 線條端點為圓角// 獲取DOM元素let boldBtn = document.getElementById("boldBtn");let thinBtn = document.getElementById("thinBtn");let saveBtn = document.getElementById("saveBtn");let color = document.getElementById("color");let clearBtn = document.getElementsByClassName("clearBtn")[0];let nullBtn = document.getElementById("nullBtn");// 設置是否開始繪畫的變量let isDraw = false;// 鼠標按下去函數canvas.onmousedown = function(e) {isDraw = true; // 開始繪畫ctx.beginPath(); // 開始路徑// 獲取鼠標點擊的坐標let x = e.pageX - canvas.offsetLeft; let y = e.pageY - canvas.offsetTop; ctx.moveTo(x, y); // 移動到當前點}// 鼠標移動函數canvas.onmousemove = function(e) {if (isDraw) { // 如果開始繪畫let x = e.pageX - canvas.offsetLeft; let y = e.pageY - canvas.offsetTop; ctx.lineTo(x, y); // 繪制ctx.stroke()}}// 鼠標彈起函數canvas.onmouseup = function(e) {isDraw = false; // 結束繪畫ctx.closePath(); // 結束路徑}// 鼠標離開畫布函數canvas.onmouseleave = function(e) {isDraw = false; // 結束繪畫ctx.closePath(); // 結束路徑}// 粗線條函數boldBtn.onclick = function(e) {ctx.globalCompositeOperation = 'source-over'; ctx.lineWidth = 20boldBtn.classList.add("active");thinBtn.classList.remove("active");clearBtn.classList.remove("active");}// 細線條函數thinBtn.onclick = function(e) {ctx.globalCompositeOperation = 'source-over'; ctx.lineWidth = 2thinBtn.classList.add("active");boldBtn.classList.remove("active");clearBtn.classList.remove("active");}// 保存簽名函數saveBtn.onclick = function(e) {let urlData = canvas.toDataURL(); // 獲取圖片數據// let img = new Image()// img.src = urlData; // 圖片地址// document.body.appendChild(img); // 添加圖片到bodylet downloadA = document.createElement("a"); // 創建a標簽downloadA.setAttribute("download", "簽名"); // 設置下載文件名downloadA.href = urlData; // 設置a標簽的地址downloadA.click(); // 點擊a標簽}// 顏色選擇函數color.onchange = function(e) {ctx.strokeStyle = color.value; // 設置線條顏色}// 橡皮擦函數clearBtn.onclick = function(e) {// 清除畫布ctx.globalCompositeOperation = 'destination-out';ctx.lineWidth = 30clearBtn.classList.add("active");boldBtn.classList.remove("active");thinBtn.classList.remove("active");}// 清空畫布函數nullBtn.onclick = function(e) {ctx.clearRect(0, 0, 800, 600);}
</script>
</body>
</html>