Drawing on canvas with opacity (dots in line) javascript

前端 未结 1 1575
忘掉有多难
忘掉有多难 2021-01-07 09:35

I have that drawing logic:

Draw = function(canvas, ctx, mousePosition) {

    var grad = ctx.createLinearGradient(0, 0, canvas[0].width, 0);
    grad.addColo         


        
1条回答
  •  时光说笑
    2021-01-07 10:25

    Yes, that is to be expected as each line is overdrawn at the connection points, and their alpha data will add up.

    I would suggest the following approach and attach a proof-of-concept demo at the end, feel free to adopt that code to your project:

    1. Create two canvases, one main and one draft on top
    2. Set the alpha directly on the top element using CSS (opacity) and always keep globalAlpha=1
    3. For each stroke (pen down, pen up) draw on draft canvas (use lines between each point)
    4. On pen up, set globalAlpha on main canvas equal the CSS opacity of top canvas
    5. Draw top canvas to main canvas using drawImage().
    6. Clear top canvas, eat, sleep, repeat (from 3).

    Proof-of-concept

    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}

    0 讨论(0)
提交回复
热议问题