简体   繁体   English

HTML 5 Canvas绘制直线平滑示例的例子?

[英]HTML 5 Canvas drawing a straight smooth line example?

I got this canvas drawing app example and I need help understanding certain parts of the code. 我得到了这个画布绘图应用程序示例,我需要帮助来理解代码的某些部分。 The app draws a really smooth line just like a pen drawing tool. 该应用程序就像笔绘图工具一样绘制一条真正平滑的线条。

 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> 

I would like to draw attention to this part of the JS code which I am having trouble understanding: 我想提请注意我难以理解的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);
  }
}

I just don't understand how parts of that code relate to each other and ultimately creates a really smooth line. 我只是不了解该代码的各个部分之间如何相互联系,最终形成了一条非常流畅的界线。

Breaking that code down: 分解代码:

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

This piece of code is straightforward as it connects the previous coordinate with a line. 这段代码很简单,因为它将前一个坐标与一条直线相连。 However the line is not smooth and looks rough. 但是,线条不平滑,看起来很粗糙。

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

This part just prints a circle but if I move my mouse really quickly the circles don't connect to each other. 这部分仅打印一个圆圈,但是如果我快速移动鼠标,圆圈将不会相互连接。

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

This is the final part of the code that makes drawing a line really smooth and efficient. 这是代码的最后一部分,它使绘制线条真正平滑而有效。 This part of the code I don't understand and how it relates in any way. 我不了解这部分代码,以及它们之间的关系。

Please explain the code logic behind the whole function and how it relates to each. 请说明整个函数背后的代码逻辑以及它与每个函数的关系。

Thanks 谢谢

The concept in that function is simple: to draw a "smooth" line you basically have to first draw a normal "rough" line, and then end it with a circle. 该功能的概念很简单:要绘制“平滑”线,基本上必须首先绘制一条正常的“粗糙”线,然后以圆结束。

Breaking it down, you are doing this: 分解,您正在执行以下操作:

  1. Draw a "rough" line: 画一条“粗”线:

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

    Which would look like this: 看起来像这样:

    线

  2. Add a circle to make the line "smooth": 添加一个圆圈以使线条“平滑”:

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

    Which transforms the previous line in something like this: 它以如下形式转换上一行:

    流畅的线条

    Here you might wonder: you said " end it with a circle", so why is there a circle at the beginning of the line? 在这里,您可能会想:您说过“以一个圆结束 ”,那么为什么在行的开头有一个圆呢? Well, actually there are way more circles. 好吧,实际上还有更多的圈子。 Every time the function is called, the line is drawn from the previous known position of the mouse to the next one, so at the beginning the line is drawn with a length of zero, and a circle is made. 每次调用该函数时,都会从鼠标的先前已知位置到下一个位置画一条线,因此在开始时以0的长度画线,并画一个圆。 Then the mouse continues moving, and more very small segments are added with circles at the end of them. 然后,鼠标继续移动,并在它们的末尾添加了更多非常小的段并带有圆圈。 Drawing down all those (almost infinite) small segments ending with circles creates a nice straight line. 画出所有以圆圈结尾的(几乎无限的)小段,可以创建一条漂亮的直线。

    This also means that the smoothness of the line only depends on the resolution at which it's drawn. 这也意味着线条的平滑度仅取决于画线的分辨率。 The more times per second the function is called and the slower the mouse goes, the smoother the line will be. 每秒调用该函数的次数越多,鼠标移动的速度越慢,则线条越平滑。

  3. Move the current position of the path to the mouse position 将路径的当前位置移到鼠标位置

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

    These two lines just make sure the next time the function is called, the beginning point will already be set. 这两行只是确保下次调用该函数时,已经设置了起点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM