canvas 是HTML5的元素,使用JavaScript 在網頁上繪製圖像。
canvas 擁有多種繪製路徑、矩形、圓形、字符以及添加圖像的方法。
而如果想實現畫筆在畫板塗畫畫筆在圖片上塗畫,橡皮擦可擦除塗畫,就需要兩個canvas畫布配合。
原理就是兩個一樣大小的canvas畫布重疊放置,並且都繪製這個圖畫,這樣只在上面的canvas塗畫、擦除,擦除時把下層canvas內容替換上層的canvas內容,達到模仿橡皮擦效果。
下面就是具體實現代碼:
1、先準備畫布和工具:
<canvas id="canvas1" width="600" height="500"></canvas>
<canvas id="canvas2" width="600" height="500"></canvas>
<div class="tooltip-pen">
<b>
<i class="ico ico-pen" title="鉛筆" onclick="changeTools('pen');"></i>
<i class="ico ico-eraser" title="橡皮檫" onclick="changeTools('eraser');"></i>
<i class="ico ico-save" title="保存" onclick="downloadImg();"></i>
</b>
</div>
2、畫布、工具樣式,以便正常顯示、使用:
<style>
#canvas1{position: absolute;background-image: url("./image/20200108173011.jpg");z-index: 997;}
#canvas2{position: absolute;background-image: url("./image/20200108173011.jpg");z-index: 998;}
.tooltip-pen{position: fixed;width: 40px;height: 125px;top: 5%;left: 650px;z-index: 999;background-color: #737373;border-radius: 5px;}
.ico{display: inline-block;width: 40px;height: 40px;}
.ico-pen {background-image: url("./image/pencil.png");background-size: 100% 100%;background-repeat: no-repeat;background-position: top center;}
.ico-eraser {background-image: url("./image/eraser.png");background-size: 100% 100%;background-repeat: no-repeat;background-position: top center;}
.ico-save{background-image: url("./image/save.png");background-size: 100% 100%;background-repeat: no-repeat;background-position: top center;}
</style>
3、重點是JS控制塗畫、擦除:
原理就是通過獲取鼠標移動軌跡(移動位置:x座標,y座標),在畫布上創建這段軌跡的線條。
<script>
var canvas1 = document.getElementById("canvas1");
var canvas2 = document.getElementById("canvas2");
var cs2Ctx = canvas2.getContext("2d");
var cs1Ctx = canvas1.getContext("2d");
// --------- 畫筆和橡皮擦功能實現 -------------
var flag = false; // 記錄鼠標按下和擡起事件,標記工具是否開始工作
var isEraser; // 判斷工具是畫筆還是橡皮擦
var lineWidth = 3; // 設置工具粗細
// 設置畫筆顏色
var theColor = "#FF0000";
theColor.onchange = function(){
cs2Ctx.strokeStyle = this.value;
}
// 切換工具
function changeTools(tname) {
if (tname == 'eraser') {
isEraser = true;
lineWidth = 30;
$(canvas2).css({ 'cursor': "url('./image/eraser_ss.png'),default" }); // 設置橡皮擦自定義鼠標樣式
} else if (tname == 'pen') {
isEraser = false;
lineWidth = 3;
$(canvas2).css({ 'cursor': 'crosshair' }); // 設置畫筆系統鼠標樣式(十字)
}
}
// onmousedown事件
canvas2.onmousedown=function(eva){
var eva = eva||window.event;
cs2Ctx.lineCap = "round";
cs2Ctx.lineJoin = "round";
var x = eva.offsetX;
var y = eva.offsetY;
cs2Ctx.beginPath();
cs2Ctx.moveTo(x,y);
flag = true;
cs2Ctx.lineWidth = lineWidth;
cs2Ctx.strokeStyle = "#FF0000";
}
// onmousemove事件
canvas2.onmousemove=function(eva){
if(flag){
if(isEraser){
var w = lineWidth;
// noinspection JSAnnotator
let pxs = cs1Ctx.getImageData(eva.offsetX-w/2, eva.offsetY-w/2, w, w);
cs2Ctx.putImageData(pxs, eva.offsetX-w/2, eva.offsetY-w/2);
} else{
var eva = eva||window.event;
var x = eva.offsetX;
var y = eva.offsetY;
cs2Ctx.lineTo(x,y);
cs2Ctx.stroke();
}
}
}
// onmouseup事件
canvas2.onmouseup = function(){
flag = false;
cs2Ctx.closePath();
}
// onmouseleave事件
canvas2.onmouseleave = function(){
flag = false;
cs2Ctx.closePath();
}
// --------- 畫筆和橡皮擦功能實現 -------------
// 保存畫布
function downloadImg() {
var canvas = document.getElementById('canvas1');
var alink = document.createElement("a");
var imgSrc = canvas.toDataURL("image/png");
alink.href = imgSrc;
alink.download = Date.now() + ".png";
alink.click();
}
</script>
4、可以把畫布保存成圖片:
原理就是將canvas內容轉成Base64格式,作爲圖片下載,當然也可以把Base64存儲到數據庫或其他地方,以後可加載它繪製到canvas畫布上。
<script>
// 保存畫布
function downloadImg() {
var canvas = document.getElementById('canvas2');
var alink = document.createElement("a");
var imgSrc = canvas.toDataURL("image/png");
alink.href = imgSrc;
alink.download = Date.now() + ".png";
alink.click();
}
</script>
5、效果如圖:
以上就是巧用canvas實現畫板功能,使用畫筆在圖片上塗畫,橡皮擦可擦除塗畫,並保持的實現。如有錯誤,請不吝指正。
另附:初始化畫布,繪製圖片代碼
$(function () {
var canvas1 = document.getElementById('canvas1');
var ctx1 = canvas1.getContext("2d");
var canvas2 = document.getElementById('canvas2');
var ctx2 = canvas2.getContext("2d");
var image = new Image();
image.src = "./image/canvas_demo.png";
image.onload = function(){
canvas1.width = this.width;
canvas1.height = this.height;
ctx1.drawImage(this, 0, 0);
canvas2.width = this.width;
canvas2.height = this.height;
ctx2.drawImage(this, 0, 0);
}
});