我正在用html画布开发一个草图工具。
为此,我使用了一个常见的算法,它使用mousedown、mousemove、mouseup事件。
按下i beginPath()和moveTo(// the mouse coordinates)。
mousemove我画lineTo(// the mouse coordinates),然后是stoke(// the line to render it)
我什么都不做,,// closePath()
我注意到,在不首先调用closePath或beginPath的情况下调用笔画方法将重新绘制或重新绘制所有以前的路径或行,这使得它们看起来比定义的颜色更厚。
没有透明的颜色,它几乎不明显,但颜色确实比他们应该看到的更厚。
但是在颜色透明的情况下,例如,rgba()。最近的路径或线尊重颜色的透明度,但由于重绘,透明的彩色线重叠,导致先前的线条在顺序或顺序上变得更厚。
有什么办法可以避免不要发生这种行为。提前谢谢。样品在下面,试着画得真快!
var cvs = document.querySelector("canvas");
cvs.width = cvs.parentElement.clientWidth;
var colorInput = document.querySelector("input");
var ctx = cvs.getContext("2d");
ctx.strokeStyle = "rgba(0, 0, 0, 0.4)"
ctx.lineWidth = 20;
onDraw(cvs, {
penDown: function(e) {
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
ctx.strokeStyle = colorInput.value;
ctx.beginPath();
ctx.moveTo(x, y);
},
penMove: function(e) {
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
ctx.lineTo(x, y);
ctx.stroke();
},
penUp: function() {
// ctx.closePath;
}
});
function onDraw(node, drawHandler, beginHandler, endHandler, outOfBoundHandler, sticky) {
var mouseDown = false, mouseOut = false;
if( typeof drawHandler === "object" ) {
var drawEvents = drawHandler;
drawHandler = get(drawEvents.penMove);
beginHandler = get(drawEvents.penDown);
endHandler = get(drawEvents.penUp);
outOfBoundHandler = get(drawEvents.penOff);
sticky = drawEvents.sticky;
}
function get(name) {
return typeof name === "string" ? drawEvents[ name ] : name;
}
node.addEventListener('mousedown', function(e) {
mouseDown = true;
beginHandler&&beginHandler.call(this, e);
});
node.addEventListener('mousemove', function(e) {
mouseDown&&drawHandler&&drawHandler.call(this, e);
});
node.addEventListener('mouseup', function(e) {
mouseDown = false;
endHandler&&endHandler.call(this, e);
});
node.addEventListener('mouseout', function(e) {
mouseDown&&outOfBoundHandler&&outOfBoundHandler.call(this, e);
if( !sticky ) {
mouseDown = false;
}
});
}.wrapper { border: 1px solid #aaa }<div class="wrapper">
<canvas border="1" width="600" hieght="400">Canvas is not supported</canvas>
<input type="text" value="rgba(0, 0, 0, 0.3)" placeholder="rgba(#, #, #, #)">
</div>
发布于 2017-09-02 10:16:23
如果没有将Path参数传递给stroke和fill方法,它们将使用当前使用上下文的绘图方法声明的路径。
const ctx = c.getContext('2d');
// starts Path declaration
ctx.moveTo(20, 20);
ctx.lineTo(30, 80);
ctx.stroke(); // first rendering
setTimeout(() => {
ctx.clearRect(0, 0, 300, 150); // even if we clear the canvas
ctx.lineTo(70, 20); // this will continue path declaration
setTimeout(() => {
ctx.stroke(); // and this will draw everything
}, 1000);
}, 1000);<canvas id="c"></canvas>
启动新路径声明(第一条路径声明除外)的唯一方法是重置整个上下文(不好),或者使用beginPath方法。
const ctx = c.getContext('2d');
// starts Path declaration
ctx.moveTo(20, 20);
ctx.lineTo(30, 80);
ctx.stroke(); // first rendering
setTimeout(() => {
ctx.clearRect(0, 0, 300, 150);
ctx.beginPath(); // start a new Path declaration
ctx.moveTo(30, 80); // we need to move to the previous coords
ctx.lineTo(70, 20); // this will be alone
ctx.stroke(); // and this will draw only the new path
}, 1000);<canvas id="c"></canvas>
关于closePath,它只是一个lineTo(last_point_in_current_path_declaration),不以任何方式结束路径声明。
因此,对于您的问题,您可以采用以下两种策略:
就我个人而言,我更喜欢第二个,它允许一些撤销-重做,例如改变你的笔的风格。
https://stackoverflow.com/questions/46012407
复制相似问题