Постепенно очищать контекст canvas (след мыши?)

#javascript #canvas #html5-canvas #mouseevent

#javascript #холст #html5-canvas #mouseevent

Вопрос:

Если вы увидите фрагмент кода run, который у меня есть, вы увидите этот html-рисунок на холсте, который сегментирован, чтобы раскрасить дуги градиентом.

Я пытаюсь выяснить, как постепенно очищать контекст от старых «дуг» в конце рисунка, аналогично эффекту «след мыши», возможно, аналогично этому:https://imgur.com/a/2Lr9IYq

Я думаю, возможно, что каким-то образом, как только total счетчик превысит segment значение count, он очистится сам, но я не совсем уверен, как это сделать.

Благодарен, если кто-нибудь может указать мне правильное направление!

 var c = document.querySelector("canvas"),
        ctx = c.getContext("2d"),
        colors = [
          {r: 0, g: 0, b: 0, a:1},
          {r: 255, g: 255, b: 255, a:1},
        ],
        cIndex = 0, maxColors = colors.length,
        total = 0, segment = 1000,
        isDown = false, px, py;


    setSize();
          
    c.onmousedown = c.ontouchstart = function(e) {
      isDown = true;
      var pos = getPos(e);
      px = pos.x;
      py = pos.y;
    };

    c.onmousemove = c.ontouchmove = function(e) {if (isDown) plot(e)};
    c.onmouseup = c.ontouchend = function(e) {
      e.preventDefault();
      isDown = false
    };

    function getPos(e) {
      // e.preventDefault();
      if (e.touches) e = e.touches[0];
      var r = c.getBoundingClientRect();
      return {
        x: e.clientX - r.left,
        y: e.clientY - r.top
      }
    }

    function plot(e) {
      var pos = getPos(e);
      plotLine(ctx, px, py, pos.x, pos.y);
      px = pos.x;
      py = pos.y;
    }

    function plotLine(ctx, x1, y1, x2, y2) {

      var diffX = Math.abs(x2 - x1),
          diffY = Math.abs(y2 - y1),
          dist = Math.sqrt(diffX * diffX   diffY * diffY),
          step = dist / 50,
          i = 0,
          t, b, x, y;
      
      while (i < dist) {
        t = Math.min(1, i / dist);

        x = x1   (x2 - x1) * t;
        y = y1   (y2 - y1) * t;



        // ctx.shadowBlur = 500;
        // ctx.shadowOffsetX = 0;
        // ctx.shadowOffsetY = 0;
        // ctx.shadowColor = getColor();

        // console.log(getColor())
        ctx.fillStyle = getColor();
        ctx.beginPath();
        ctx.arc(x, y, 25, 0, Math.PI*2);

        ctx.fill();
        i  = step;
      }
      
      function getColor() {
      
        var r, g, b, a, t, c1, c2;
        
        c1 = colors[cIndex];
        c2 = colors[(cIndex   1) % maxColors];
        t = Math.min(1, total / segment);
        
        if (  total > segment) {
          total = 0;
          if (  cIndex >= maxColors) cIndex = 0;
        }
      
        r = c1.r   (c2.r - c1.r) * t;
        g = c1.g   (c2.g - c1.g) * t;
        b = c1.b   (c2.b - c1.b) * t;
        a = c1.a   (c2.a - c1.a) * t;
        

        return "rgb("   (r|0)   ","   (g|0)   ","   (b|0)   ","   (a)   ")";
      }
    }

    window.onresize = setSize;
    function setSize() {
      c.width = window.innerWidth;
      c.height = window.innerHeight;
    }  
 html, body {
      margin:0;
      padding:0;
    }

 
    body {
      padding: 0px;
    }  
 <canvas id="myCanvas" ></canvas>  

Комментарии:

1. Холст не хранит ранее нарисованные контуры, только текущий цвет пикселей. Если вы хотите впоследствии изменить свой путь, способ сделать это — стереть холст и перерисовать части пути, которые вы хотите сохранить. Если вы сохраняете координаты пути в массиве, помещая новые координаты путей в конец массива и сдвигая старые координаты с начала массива. Вы можете повторно отобразить элементы в массиве после очистки canvas для достижения желаемого эффекта.

2. Простым способом сделать это было бы использовать это ctx.fillStyle = "rgba(255,255,255,.2)"; ctx.fillRect(0,0,c.width,c.height) в начале plotLine . Объяснение: если вы используете это rgb(255,255,255) вместо rgba(255,255,255,.2) , это очистит холст, поскольку вы закрываете все предыдущие рисунки белым прямоугольником размером с холст. Если вы используете полупрозрачный белый цвет, предыдущий рисунок будет постепенно закрываться, в результате чего холст, по-видимому , постепенно очистится.

3. круто! да, это в некоторой степени делает то, чего я пытался достичь

4. Проблема с методом, который предоставляет @enxaneta, заключается в том, что alpha(0.2) alpha(0.2) alpha(0.2) ... никогда не доходит до alpha(1) . У вас всегда будет призрак ваших предыдущих рисунков.

5. @Kaiido да, я тоже это понял. у вас есть предложения?