[英]HTML5 canvas paint redrawing lineJoin not rounded
您好,我做的像帶撤消功能的畫圖,我將所有坐標寫入數組,然后嘗試撤消,僅重繪而沒有最后一個坐標,但是在我重畫畫布參數不正確時出現問題。 我使用lineJoin = "roind"
但是重lineJoin = "roind"
后我看不到圓角。
在繪制時此結果以圓線開始和線結束:
撤消功能后沒有回合開始和行結束的結果:
我不知道在逐個坐標重畫所有圖紙時消失的圓線。
var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var points = []; var size = 10; var prevX = 0; var prevY = 0; var isCanDraw = false; $("#canvas").on("mousedown", function(e) { isCanDraw = true; prevX = e.clientX; prevY = e.clientY; points.push({x: prevX, y: prevY, size: size, mode: "begin"}); }); $("#canvas").on("mousemove", function(e) { if(isCanDraw) { stroke(e.clientX, e.clientY); points.push({x: prevX, y: prevY, size: size, mode: "draw"}); } }); $("#canvas").on("mouseup", function(e) { isCanDraw = false; points.push({x: prevX, y: prevY, size: size, mode: "end"}); }); $("#canvas").on("mouseleave", function(e) { isCanDraw = false; }); $("#undo").on("click", function(e) { deleteLast(); redraw(); }); function deleteLast() { if(points.length != 0) { var i = points.length - 1; while(points[i].mode != "begin") { i--; points.pop(); } points.pop(); } } function redraw() { ctx.clearRect(0, 0, canvas.width, canvas.height); if(points.length != 0) { for(var i=0; i < points.length; i++) { var pt = points[i]; var begin=false; if(size != pt.size) { size = pt.size; begin=true; } if(pt.mode == "begin" || begin) { ctx.moveTo(pt.x, pt.y) } ctx.lineTo(pt.x, pt.y) if( pt.mode == "end" || (i == points.length-1) ) { ctx.lineJoin = "round"; ctx.stroke() } } } } function stroke(x,y) { ctx.lineWidth = size; ctx.lineJoin = "round"; ctx.beginPath(); ctx.moveTo(prevX, prevY); ctx.lineTo(x, y); ctx.closePath(); ctx.stroke(); prevX = x; prevY = y; }
#canvas { border: 1px solid #000; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <canvas id="canvas" width="500" height="300"></canvas> <input type="button" id="undo" value="undo">
我認為您正在尋找ctx。 lineCap
屬性 。
+我修改了您的重繪函數,以使用switch
而不是使if語句混亂:
function redraw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.lineCap = "round";
ctx.beginPath();
for(var i=0; i < points.length; i++) {
var pt = points[i];
switch(pt.mode){
case "begin" : ctx.moveTo(pt.x, pt.y);
case "draw" : ctx.lineTo(pt.x, pt.y);
case "end" : ctx.stroke();
}
}
}
var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var points = []; var size = 10; var prevX = 0; var prevY = 0; var isCanDraw = false; var rect = canvas.getBoundingClientRect(); $("#canvas").on("mousedown", function(e) { isCanDraw = true; prevX = e.clientX; prevY = e.clientY; points.push({ x: prevX, y: prevY, size: size, mode: "begin" }); ctx.beginPath(); ctx.arc(prevX, prevY, size/2, 0, Math.PI*2); ctx.fill(); }); $("#canvas").on("mousemove", function(e) { if (isCanDraw) { stroke(e.clientX - rect.left, e.clientY - rect.top); points.push({ x: prevX, y: prevY, size: size, mode: "draw" }); } }); $("#canvas").on("mouseup", function(e) { isCanDraw = false; points.push({ x: prevX, y: prevY, size: size, mode: "end" }); }); $("#canvas").on("mouseleave", function(e) { isCanDraw = false; }); $("#undo").on("click", function(e) { deleteLast(); redraw(); }); function deleteLast() { if (points.length != 0) { var i = points.length - 1; while (points[i].mode != "begin") { i--; points.pop(); } points.pop(); } } function redraw() { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.lineCap = "round"; ctx.beginPath(); for (var i = 0; i < points.length; i++) { var pt = points[i]; switch (pt.mode) { case "begin": ctx.moveTo(pt.x, pt.y); case "draw": ctx.lineTo(pt.x, pt.y); case "end": ctx.stroke(); } } } function stroke(x, y) { ctx.lineWidth = size; ctx.lineJoin = "round"; ctx.beginPath(); ctx.moveTo(prevX, prevY); ctx.lineTo(x, y); ctx.closePath(); ctx.stroke(); prevX = x; prevY = y; } // debounce our rect update func var scrolling = false; function scrollHandler(){ rect = canvas.getBoundingClientRect(); scrolling = false; } $(window).on('scroll resize', function(e){ if(!scrolling){ requestAnimationFrame(scrollHandler); } });
#canvas { border: 1px solid #000; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <canvas id="canvas" width="500" height="300"></canvas> <input type="button" id="undo" value="undo">
@Kaiido正確回答了,應用lineCap='round'
將使重新繪制的線的末端變圓。
還有兩個想法:
您應該考慮畫布從文檔左上角的偏移位置。 否則,如果畫布不在文檔的左上方,則prevX和prevY的位置將略有偏離。
如果只允許對起點和終點線帽進行四舍五入,而對所有臨時線帽進行對接,則您將獲得一條更清晰的線條(減少“凸起”)。 將線連接保留為斜接的默認設置。
這是示例代碼和演示:
var canvas=document.getElementById("canvas"); var ctx=canvas.getContext("2d"); var cw=canvas.width; var ch=canvas.height; var $canvas=$("#canvas"); var canvasOffset=$canvas.offset(); var offsetX=canvasOffset.left; var offsetY=canvasOffset.top; var points = []; var size = 10; var prevX = 0; var prevY = 0; var isCanDraw = false; $("#canvas").on("mousedown", function(e) { isCanDraw = true; prevX = e.clientX-offsetX; prevY = e.clientY-offsetY; points.push({x: prevX, y: prevY, size: size, mode: "begin"}); }); $("#canvas").on("mousemove", function(e) { if(isCanDraw) { stroke(e.clientX-offsetX, e.clientY-offsetY); points.push({x: prevX, y: prevY, size: size, mode: "draw"}); } }); $("#canvas").on("mouseup", function(e) { isCanDraw = false; points.push({x: prevX, y: prevY, size: size, mode: "end"}); }); $("#canvas").on("mouseleave", function(e) { isCanDraw = false; }); $("#undo").on("click", function(e) { deleteLast(); redraw(); }); function deleteLast() { if(points.length != 0) { var i = points.length - 1; while(points[i].mode !== "begin") { i--; points.pop(); } points.pop(); } } function redraw() { ctx.clearRect(0, 0, canvas.width, canvas.height); var savedFillStyle=ctx.fillStyle; ctx.fillStyle=ctx.strokeStyle; var i=0; while(i<points.length){ var p=points[i]; // draw "begin" as circle instead of line ctx.beginPath(); ctx.arc(px,py,p.size/2,0,Math.PI*2); ctx.closePath(); ctx.fill(); // draw "draw" ctx.lineWidth=p.size; ctx.beginPath(); ctx.moveTo(px,py); i++; while(i<points.length && points[i].mode!='end'){ var p=points[i]; ctx.lineTo(px,py); i++; } ctx.stroke(); // draw "end" as circle instead of line var p=points[i]; ctx.beginPath(); ctx.arc(px,py,p.size/2,0,Math.PI*2); ctx.closePath(); ctx.fill(); i++; } ctx.fillStyle=savedFillStyle; } function stroke(x,y) { ctx.lineWidth = size; ctx.lineJoin = "round"; ctx.beginPath(); ctx.moveTo(prevX, prevY); ctx.lineTo(x, y); ctx.closePath(); ctx.stroke(); prevX = x; prevY = y; }
body{ background-color: ivory; padding:10px; } #canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <canvas id="canvas" width="500" height="300"></canvas> <input type="button" id="undo" value="undo"> </body>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.