HTML 5 Canvas绘图线?

时间:2016-02-18 01:48:29

标签: javascript html canvas

大家好,我一直在两个不同功能之间比较画布上的画线。我意识到两个函数之间绘制的线条是不同的,但两个函数的代码逻辑似乎完全相同(对我而言)。

代码:

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');

var radius = 10;
var dragging = false;


canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
context.lineWidth = radius*2;

var putPoint = function(e){
  if(dragging){
    context.lineTo(e.clientX, e.clientY);
    context.stroke();
  }
}

var engage = function(e){
  dragging = true;
  putPoint(e);
}

var disengage = function(){
  dragging = false;
  context.beginPath();
}

canvas.addEventListener('mousedown', engage);
canvas.addEventListener('mousemove', putPoint);
canvas.addEventListener('mouseup', disengage);
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Canvas</title>
</head>
<body style="margin:0">
  <canvas style="display:block;" id="canvas">
    sorry this browser does not support HTML 5 Canvas!
  </canvas>
  <script src="main.js"></script>
</body>
</html>

从上述函数中提取的行:

enter image description here

如果我将上述函数putPoint()修改为以下内容:

var putPoint = function(e){
  if(dragging){
    context.lineTo(e.clientX, e.clientY);
    context.stroke();
    
    context.beginPath();
    context.moveTo(e.clientX, e.clientY);

  }
}

该行更改为:

enter image description here

我不明白为什么这两行在任何方面都应该有所不同(即使它确实如此)。

var putPoint = function(e){
      if(dragging){
        context.lineTo(e.clientX, e.clientY);
        context.stroke();
      }
    }

此函数绘制的线条比后面更平滑,因为每次调用函数时,线条将从上一个函数坐标的(x,y)绘制到下一个函数坐标的(x,y)时叫做。

var putPoint = function(e){
      if(dragging){
        context.lineTo(e.clientX, e.clientY);
        context.stroke();

        context.beginPath();
        context.moveTo(e.clientX, e.clientY);

      }
    }

这个函数对我来说是相同的,因为moveTo(x,y)会存储最新的(x,y)坐标。调用lineTo(x,y)时,将绘制moveTo(x,y)lineTo(x,y)坐标之间的线。虽然绘制了不同的线条,但这似乎与第一个函数完全相同。

请解释一下?

1 个答案:

答案 0 :(得分:1)

这是因为在第二个例子中,线未连接。 rending API有特殊的代码来填充渲染粗曲线时创建的间隙,通过欺骗很多小路径,你不允许这个代码做它的事情。

控制笔触渲染。

您可以使用ctx.lineJoinround和&#39; bevel&#39;来控制与miter属性相关联的行。如果您使用斜角(尖角),您可以通过将ctx.miterLimit的值设置为不应超过的像素数来控制缓和角在尖角上伸出的距离。

您还可以使用ctx.lineCapbuttround square属性ctx.lineCap = "round"属性来控制行结束.Bett具有在坐标处停止的平端该行的开头和结尾。 square将行宽的一半加到行的开头和结尾。

修复差距

要解决您的行问题,请设置class P_Light; class NP_Light; /* abstract class providing dispatching based on * whether Light objects interact with the position field */ class Light_Visiter{ virtual ~Light_Visiter(){} virtual void visit(NP_light&) = 0; virtual void visit(P_Light&) = 0; }; class Light{ virtual ~Light(){} virtual void visit(Light_Visitor&) = 0; // other methods }; class P_Light : public Light{ void visit(Light_Visitor& lv){lv.visit(*self);} // other methods }; /* Light objects which do not interact with the position * field inherit from NP_Light */ class NP_Light : public Light{ void visit(Light_Visitor& lv){lv.visit(*self);} // other methods }; ,它会在每个路径段的开头和结尾添加半个圆圈。圆的直径与线宽相同。这将填补您在第二行示例中看到的空白。