我有那个绘图逻辑:

Draw = function(canvas, ctx, mousePosition) {

    var grad = ctx.createLinearGradient(0, 0, canvas[0].width, 0);
    grad.addColorStop(0, currentLineColor);
    grad.addColorStop(1, currentLineColor);

    ctx.lineWidth = currentLineWidth;
    ctx.strokeStyle = grad;
    ctx.lineCap = 'round';
    ctx.lineJoin = 'round';
    ctx.globalAlpha = 0.4;

    ctx.beginPath();
    ctx.moveTo(lastMousePosition.x, lastMousePosition.y);
    ctx.lineTo(mousePosition.x, mousePosition.y);
    ctx.stroke();
};


当我在此代码中设置globalAlpha设置不透明度时,在绘制的线条中看到了点。此逻辑附加到mosemove事件。

最佳答案

是的,这是可以预期的,因为每条线在连接点上都被覆盖,并且它们的Alpha数据将累加。

我建议采用以下方法,并在最后附加一个概念验证演示,请随时在您的项目中采用该代码:


创建两个画布,一个主画布和一个草稿在顶部
使用CSS(不透明度)直接在顶部元素上设置Alpha,并始终保持globalAlpha=1
对于每个笔划(向下笔,向上笔),在草稿画布上绘制(在每个点之间使用线)
在笔上,在主画布上设置globalAlpha等于顶部画布的CSS不透明度
使用drawImage()将顶部画布绘制到主画布。
清除顶层画布,吃饭,睡觉,重复(从3开始)。


概念验证



var draft = document.getElementById("draft");
var main = document.getElementById("main");
var ctx = draft.getContext("2d");
var mctx = main.getContext("2d");
var isDown = false, prev, alpha = 0.4;

// setup pen
ctx.strokeStyle = "rgb(0,200,127)";
ctx.lineWidth = 16;
ctx.lineCap = "round";                              // important to make lines cont.

// set up alpha
draft.style.opacity = alpha;                        // CSS alpha for draft
mctx.globalAlpha = alpha;                           // context alpha for main

draft.onmousedown = function(e){
  isDown = true;
  prev = getXY(e);                                  // set prev. point as start
};

window.onmousemove = function(e){
  if (!isDown) return;
  var point = getXY(e);
  ctx.beginPath();                                  // new path
  ctx.moveTo(prev.x, prev.y);                       // start at prev. point
  ctx.lineTo(point.x, point.y);                     // line to new point
  ctx.stroke();                                     // stroke
  prev = point;                                     // update prev. point
};

window.onmouseup = function(){
  isDown = false;                                   // when up:
  mctx.drawImage(draft, 0, 0);                      // copy drawing to main
  ctx.clearRect(0, 0, draft.width, draft.height);   // clear draft
};

function getXY(e) {
  var r = draft.getBoundingClientRect();
  return {x: e.clientX - r.left, y: e.clientY - r.top}
}

#draft {cursor:crosshair}
.sandwich {position:relative}
.sandwich>canvas {position:absolute;left:0;top:0}

<div class="sandwich">
  <canvas id="main" width=600 height=600></canvas>
  <canvas id="draft" width=600 height=600></canvas>
</div>

关于javascript - 在 Canvas 上用不透明度(点线)进行绘制,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29072686/

10-15 04:52