摘要:第二步,消除涂鴉鋸齒的辦法簡單的繪制和圖片保存完成了,但是在這種情況下,線條會有很明顯的鋸齒靈魂畫手來了。在經過搜索查閱之后,發現有一個繪制辦法可以降低鋸齒的問題。橡皮擦的原理是,將橡皮繪制的路徑覆蓋到原來的畫筆上。
第一步,我們先實現簡單的繪制,并且在繪制之后將圖片保存到本地
var canvas = document.getElementById("canvas"), ctx = canvas.getContext("2d"), iptColor = document.getElementById("iptColor"),//畫筆顏色 iptSize = document.getElementById("iptSize"),//畫筆大小 btnClear = document.getElementById("btnClear"), //清除按鈕 btnSave = document.getElementById("btnSave"),//保存按鈕 canvasWidth = 800, canvasHeight = 600; canvas.setAttribute("width",canvasWidth); canvas.setAttribute("height",canvasHeight); iptSize.oninput = function() { document.querySelector(".txt-size").innerHTML = iptSize.value } canvas.addEventListener("mousedown",function(e){ var e = e || window.event; ctx.lineWidth = iptSize.value; ctx.strokeStyle = iptColor.value; ctx.lineCap = "round"; ctx.lineJoin = "round"; ctx.beginPath(); ctx.moveTo(e.clientX - canvas.offsetLeft,e.clientY - canvas.offsetTop); //線條起始位置 document.onmousemove = function(e) { var e = e || window.event; ctx.lineTo(e.clientX - canvas.offsetLeft,e.clientY - canvas.offsetTop); ctx.stroke();//繪制線條 }; canvas.onmouseup = function() { document.onmousemove = null; document.onmouseup = null; }; }) //清除畫布 btnClear.addEventListener("click",function(){ ctx.clearRect(0, 0, canvasWidth, canvasHeight); }) //保存圖片到本地 btnSave.addEventListener("click",function(){ var imgData = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"); var filename = "圖片.png"; saveFile(imgData,filename) }) var saveFile = function(data, filename) { var save_link = document.createElementNS("http://www.w3.org/1999/xhtml", "a"); save_link.href = data; save_link.download = filename; var event = document.createEvent("MouseEvents"); event.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); save_link.dispatchEvent(event); };
這樣看起來雖然說好像沒問題,但是這一句有一些問題:
e.clientX - canvas.offsetLeft,e.clientY - canvas.offsetTop
如果頁面比較高,產生了滾動條,當滾動條向上滑的時候,繪圖的位置就不準確了,示例如:https://codepen.io/jianxiujiu...。
所以此處應該使用:
e.clientX - canvas.getBoundingClientRect().left,e.clientY - canvas.getBoundingClientRect().top
來替換。
第二步,消除涂鴉鋸齒的辦法簡單的繪制和圖片保存完成了,但是在這種情況下,線條會有很明顯的鋸齒(靈魂畫手來了)。
有一個簡單粗暴的方法,將線條的邊緣進行模糊:
ctx.shadowBlur = 1; ctx.shadowColor = iptColor.value;
示例:https://codepen.io/jianxiujiu...
加上邊緣模糊之后,線條明顯柔和了許多,但是還是有一個問題,就是在畫筆收筆的地方,線條會變?。`魂畫手又來了)。
在經過搜索查閱之后,發現有一個繪制辦法可以降低鋸齒的問題。
原理如圖:
繪制一個圓點,在下一個圓點之間,繪制一個矩形進行填充。這樣繪制出來的線條的銜接會是圓滑的。
var canvas = document.getElementById("canvas"), ctx = canvas.getContext("2d"), btnClear = document.getElementById("btnClear"), btnSave = document.getElementById("btnSave"), iptColor = document.getElementById("iptColor"), iptSize = document.getElementById("iptSize"), canvasWidth = 800, canvasHeight = 600; canvas.setAttribute("width",canvasWidth); canvas.setAttribute("height",canvasHeight); iptSize.oninput = function() { document.querySelector(".txt-size").innerHTML = iptSize.value } canvas.addEventListener("mousedown",function(e){ var e = e || window.event; var x1 = e.clientX - canvas.getBoundingClientRect().left, y1 = e.clientY - canvas.getBoundingClientRect().top; lineSize = iptSize.value; lineColor = iptColor.value; ctx.beginPath(); ctx.fillStyle = lineColor; ctx.lineCap = "round"; ctx.lineJoin = "round"; ctx.arc(x1, y1, lineSize, 0, 2 * Math.PI); ctx.fill(); ctx.closePath(); document.onmousemove = function(e) { var e = e || window.event; var x2 = e.clientX - canvas.getBoundingClientRect().left, y2 = e.clientY - canvas.getBoundingClientRect().top; var asin = lineSize * Math.sin(Math.atan((y2 - y1) / (x2 - x1))); var acos = lineSize * Math.cos(Math.atan((y2 - y1) / (x2 - x1))); //分別獲取矩形的四個點的xy軸位置 var x3 = x1 + asin; var y3 = y1 - acos; var x4 = x1 - asin; var y4 = y1 + acos; var x5 = x2 + asin; var y5 = y2 - acos; var x6 = x2 - asin; var y6 = y2 + acos; ctx.beginPath(); ctx.fillStyle = lineColor; ctx.arc(x2, y2, lineSize, 0, 2 * Math.PI); ctx.fill(); ctx.closePath(); ctx.beginPath(); ctx.fillStyle = lineColor; ctx.moveTo(x3, y3); ctx.lineTo(x5, y5); ctx.lineTo(x6, y6); ctx.lineTo(x4, y4); ctx.fill(); ctx.closePath(); x1 = x2; y1 = y2; }; canvas.onmouseup = function() { document.onmousemove = null; document.onmouseup = null; }; }) btnClear.addEventListener("click",function(){ ctx.clearRect(0, 0, canvasWidth, canvasHeight); }) btnSave.addEventListener("click",function(){ var imgData = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"); var filename = "圖片.png"; saveFile(imgData,filename) }) var saveFile = function(data, filename) { var save_link = document.createElementNS("http://www.w3.org/1999/xhtml", "a"); save_link.href = data; save_link.download = filename; var event = document.createEvent("MouseEvents"); event.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); save_link.dispatchEvent(event); };
DEMO:
https://codepen.io/jianxiujiu...
用這個方法,我們還可以加上橡皮擦。
橡皮擦的原理是,將橡皮繪制的路徑覆蓋到原來的畫筆上。
這里我們將用到canvas的一個屬性globalCompositeOperation,詳解參照:
http://www.w3school.com.cn/ta...
var canvas = document.getElementById("canvas"), ctx = canvas.getContext("2d"), btnClear = document.getElementById("btnClear"), btnSave = document.getElementById("btnSave"), btnRestore = document.getElementById("btnRestore"), iptColor = document.getElementById("iptColor"), iptSize = document.getElementById("iptSize"), eraser = document.getElementById("eraser") pen = document.getElementById("pen"), canvasWidth = 800, canvasHeight = 600, isClear = 0; canvas.setAttribute("width",canvasWidth); canvas.setAttribute("height",canvasHeight); iptSize.oninput = function() { document.querySelector(".txt-size").innerHTML = iptSize.value } eraser.addEventListener("click",function(){ isClear = 1; this.classList.add("cho"); pen.classList.remove("cho") }) pen.addEventListener("click",function(){ isClear = 0; this.classList.add("cho"); eraser.classList.remove("cho") }) canvas.addEventListener("mousedown",function(e){ var e = e || window.event; var x1 = e.clientX - canvas.getBoundingClientRect().left, y1 = e.clientY - canvas.getBoundingClientRect().top; lineSize = iptSize.value; if(isClear == 0){ lineColor = iptColor.value; ctx.beginPath(); ctx.fillStyle = lineColor; ctx.arc(x1, y1, lineSize, 0, 2 * Math.PI); ctx.fill(); ctx.closePath(); document.onmousemove = function(e) { draw(); }; btnClear.classList.remove("dis"); btnSave.classList.remove("dis"); }else{ ctx.strokeStyle = "rgba(250,250,250,0)"; document.onmousemove = function() { ctx.globalCompositeOperation = "destination-out"; draw(); ctx.globalCompositeOperation = "source-over" } } canvas.onmouseup = function() { document.onmousemove = null; document.onmouseup = null; }; draw = function(e){ var e = e || window.event, x2 = e.clientX - canvas.getBoundingClientRect().left, y2 = e.clientY - canvas.getBoundingClientRect().top, asin = lineSize * Math.sin(Math.atan((y2 - y1) / (x2 - x1))), acos = lineSize * Math.cos(Math.atan((y2 - y1) / (x2 - x1))), x3 = x1 + asin, y3 = y1 - acos, x4 = x1 - asin, y4 = y1 + acos, x5 = x2 + asin, y5 = y2 - acos, x6 = x2 - asin, y6 = y2 + acos; ctx.beginPath(); ctx.arc(x2, y2, lineSize, 0, 2 * Math.PI); ctx.fill(); ctx.closePath(); ctx.beginPath(); ctx.fillStyle = lineColor; ctx.moveTo(x3, y3); ctx.lineTo(x5, y5); ctx.lineTo(x6, y6); ctx.lineTo(x4, y4); ctx.fill(); ctx.closePath(); x1 = x2; y1 = y2; } }) // 清除 btnClear.addEventListener("click",function(){ ctx.clearRect(0, 0, canvasWidth, canvasHeight); this.classList.add("dis"); btnSave.classList.add("dis"); }) //保存圖片 btnSave.addEventListener("click",function(){ var imgData = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"); var filename = "圖片.png"; saveFile(imgData,filename); this.classList.add("dis"); }) var saveFile = function(data, filename) { var save_link = document.createElementNS("http://www.w3.org/1999/xhtml", "a"); save_link.href = data; save_link.download = filename; var event = document.createEvent("MouseEvents"); event.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); save_link.dispatchEvent(event); };
地址:https://codepen.io/jianxiujiu...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/89025.html
摘要:方案背景需求需要對圖片進行標注,導出圖片。對應方案用實現涂鴉圓形矩形的繪制,最終生成圖片編碼用于上傳大量圖片批量上傳很耗時間,為了提高用戶體驗,改為只實現圓形矩形繪制,最終保存成坐標,下次顯示時根據坐標再繪制。 方案背景 需求 需要對圖片進行標注,導出圖片。 需要標注N多圖片最后同時保存。 需要根據多邊形區域數據(區域、顏色、名稱)標注。 對應方案 用canvas實現涂鴉、圓形、...
摘要:撤銷清空等操作撤銷前進清空清空前后數據恢復到默認數據地址查看代碼 效果展示 showImg(https://segmentfault.com/img/bVHJXf?w=1550&h=846); Canvas API簡介 調用方法 getImageData() 返回ImageData對象,該對象為畫布上指定的矩形復制像素數據 putImageData() 把圖像數據(從指定的 Imag...
摘要:開啟掃描時需要設備處于配網狀態一分類配網子設備可以通過使用手機藍牙直接掃描獲取設備到設備基礎信息,再使用配網接口實現設備的本地配網。 ? (一)分類 ? (二)設備配置 ? (三)設備管理 ? ? 設備管理,大體分為兩類,mesh 和 其他 ? ? 獲取設備列表,給涂鴉sdk發送當前房間id...
閱讀 2235·2019-08-30 10:51
閱讀 789·2019-08-30 10:50
閱讀 1471·2019-08-30 10:49
閱讀 3135·2019-08-26 13:55
閱讀 1600·2019-08-26 11:39
閱讀 3417·2019-08-26 11:34
閱讀 1943·2019-08-23 18:30
閱讀 3385·2019-08-23 18:22