HTML 5 Canvas绘制一条直线的例子?

时间:2016-02-16 07:14:10

标签: javascript html5 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();
    context.beginPath();
    context.arc(e.clientX, e.clientY, radius, 0, Math.PI*2);
    context.fill();
    context.beginPath();
    context.moveTo(e.clientX, e.clientY);
  }
}

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>

我想提请注意这部分我无法理解的JS代码:

var putPoint = function(e){
  if(dragging){
    context.lineTo(e.clientX, e.clientY);
    context.stroke();
    context.beginPath();
    context.arc(e.clientX, e.clientY, radius, 0, Math.PI*2);
    context.fill();
    context.beginPath();
    context.moveTo(e.clientX, e.clientY);
  }
}

我只是不明白该代码的各个部分是如何相互关联的,最终会创建一条非常流畅的线条。

打破代码:

context.lineTo(e.clientX, e.clientY);
context.stroke();

这段代码非常简单,因为它将前一个坐标与一条线连接起来。然而,线条不平滑,看起来粗糙。

context.beginPath();
context.arc(e.clientX, e.clientY, radius, 0, Math.PI*2);
context.fill();

这部分只打印一个圆圈,但如果我快速移动鼠标,圆圈就不会相互连接。

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

这是代码的最后一部分,使得绘制线条非常流畅和高效。这部分代码我不明白以及它与它有何关联。

请解释整个功能背后的代码逻辑以及它与每个功能的关系。

谢谢

1 个答案:

答案 0 :(得分:1)

该功能的概念很简单:要绘制“平滑”线,您基本上必须首先画一条普通的“粗糙”线,然后用圆圈结束。

打破它,你这样做:

  1. 绘制“粗略”行:

    context.lineTo(e.clientX, e.clientY);
    context.stroke();
    

    看起来像这样:

    line

  2. 添加一个圆圈以使线条“平滑”:

    context.beginPath();
    context.arc(e.clientX, e.clientY, radius, 0, Math.PI*2);
    context.fill();
    

    这会改变前一行:

    smooth line

    在这里你可能想知道:你说“结束它有一个圆圈”,那么为什么在行的开头有一个圆圈?嗯,实际上有更多的圈子。每次调用该函数时,都会将该行从鼠标的上一个已知位置绘制到下一个,因此在开始时绘制一条长度为零的线,并绘制一个圆。然后鼠标继续移动,并且在它们的末尾添加更多非常小的片段。绘制所有以圆圈结尾的(几乎无限的)小段创建一个很好的直线。

    这也意味着线条的平滑度仅取决于绘制线条的分辨率。调用函数每秒的次数越多,鼠标越慢,行就越平滑。

  3. 将路径的当前位置移动到鼠标位置

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

    这两行只是确保下次调用该函数时,已经设置了起始点。