首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >HTML :透明颜色的ctx.stroke restroke行为

HTML :透明颜色的ctx.stroke restroke行为
EN

Stack Overflow用户
提问于 2017-09-02 09:33:46
回答 1查看 596关注 0票数 1

我正在用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()。最近的路径或线尊重颜色的透明度,但由于重绘,透明的彩色线重叠,导致先前的线条在顺序或顺序上变得更厚。

有什么办法可以避免不要发生这种行为。提前谢谢。样品在下面,试着画得真快!

代码语言:javascript
复制
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;
			}
		});
	}
代码语言:javascript
复制
.wrapper { border: 1px solid #aaa }
代码语言:javascript
复制
<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>

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-09-02 10:16:23

如果没有将Path参数传递给strokefill方法,它们将使用当前使用上下文的绘图方法声明的路径。

代码语言:javascript
复制
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);
代码语言:javascript
复制
<canvas id="c"></canvas>

启动新路径声明(第一条路径声明除外)的唯一方法是重置整个上下文(不好),或者使用beginPath方法。

代码语言:javascript
复制
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);
代码语言:javascript
复制
<canvas id="c"></canvas>

关于closePath,它只是一个lineTo(last_point_in_current_path_declaration),不以任何方式结束路径声明。

因此,对于您的问题,您可以采用以下两种策略:

  • 只保留最后的坐标,在每个摩丝表情处, ctx.beginPath();ctx.moveTo(lastX,lastY);ctx.lineTo(nextX,nextY);
  • 将所有坐标保存在一个数组中,每次都重新绘制所有坐标。 ctx.clearRect(0,0,canvas.width,canvas.height);ctx.beginPath();coords.forEach(pt => ctx.lineTo(pt.x,pt.y));

就我个人而言,我更喜欢第二个,它允许一些撤销-重做,例如改变你的笔的风格。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46012407

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档