簡體   English   中英

HTML5畫布繪制重繪線連接未舍入

[英]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'將使重新繪制的線的末端變圓。

還有兩個想法:

  1. 您應該考慮畫布從文檔左上角的偏移位置。 否則,如果畫布不在文檔的左上方,則prevX和prevY的位置將略有偏離。

  2. 如果只允許對起點和終點線帽進行四舍五入,而對所有臨時線帽進行對接,則您將獲得一條更清晰的線條(減少“凸起”)。 將線連接保留為斜接的默認設置。

這是示例代碼和演示:

 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM