我有这个画布绘图应用程序示例,我需要帮助理解代码的某些部分。该应用程序绘制一个非常流畅的线条,就像一个钢笔绘图工具。
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);
这是代码的最后一部分,使得绘制线条非常流畅和高效。这部分代码我不明白以及它与它有何关联。
请解释整个功能背后的代码逻辑以及它与每个功能的关系。
谢谢
答案 0 :(得分:1)
该功能的概念很简单:要绘制“平滑”线,您基本上必须首先画一条普通的“粗糙”线,然后用圆圈结束。
打破它,你这样做:
绘制“粗略”行:
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);
这两行只是确保下次调用该函数时,已经设置了起始点。