javascript - HTML5 Canvas 油漆重画lineJoin不圆 Angular

标签 javascript html canvas

您好,我像使用撤消功能一样进行绘画,我将所有坐标写入数组,然后尝试撤消仅在没有最后一个坐标的情况下重绘,但在我重绘 Canvas 参数时出现问题。我使用 lineJoin = "roind" 但重画后我看到没有圆形..

在我绘图时,此结果具有圆线开头和线结尾: enter image description here

撤消函数后没有回合开始和行结束的结果: enter image description here

当我逐个坐标地重新绘制所有绘图时,我不知道我的圆线在哪里消失。

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 property .
+ 我修改了您的重绘函数以使用 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">

关于javascript - HTML5 Canvas 油漆重画lineJoin不圆 Angular ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28281637/

相关文章:

javascript - 将对象插入数组时保留对象键值顺序

javascript - 带直接数字输入的范围 slider

java - 我无法在 JSP 中导入 CSS 文件

javascript - 如何让多个球在点击时掉落?

javascript - HTML5历史禁用前进按钮

javascript - 如何在 Angular 表格的所有单元格中添加链接?

javascript - 无法解决 Ext.ux 的依赖关系

Javascript (Vue.js) 无法在移动设备和其他连接的设备上运行,但可以在运行本地主机的桌面上运行

javascript - KineticJS 与可重复鼠标事件的问题

c# - 如何获取设置为 'Auto' 的 Canvas 元素的宽度和高度?