大家好,我一直在两个不同功能之间比较画布上的画线。我意识到两个函数之间绘制的线条是不同的,但两个函数的代码逻辑似乎完全相同(对我而言)。
代码:
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>
从上述函数中提取的行:
如果我将上述函数putPoint()
修改为以下内容:
var putPoint = function(e){
if(dragging){
context.lineTo(e.clientX, e.clientY);
context.stroke();
context.beginPath();
context.moveTo(e.clientX, e.clientY);
}
}
该行更改为:
我不明白为什么这两行在任何方面都应该有所不同(即使它确实如此)。
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)
坐标之间的线。虽然绘制了不同的线条,但这似乎与第一个函数完全相同。
请解释一下?
答案 0 :(得分:1)
这是因为在第二个例子中,线未连接。 rending API有特殊的代码来填充渲染粗曲线时创建的间隙,通过欺骗很多小路径,你不允许这个代码做它的事情。
控制笔触渲染。
您可以使用ctx.lineJoin
,round
和&#39; bevel&#39;来控制与miter
属性相关联的行。如果您使用斜角(尖角),您可以通过将ctx.miterLimit
的值设置为不应超过的像素数来控制缓和角在尖角上伸出的距离。
您还可以使用ctx.lineCap
,butt
和round
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
};
,它会在每个路径段的开头和结尾添加半个圆圈。圆的直径与线宽相同。这将填补您在第二行示例中看到的空白。