3

Ok I'm drawing stroke lines on a canvas object which is working ok what I'd like to do is to remove the lines or fade them out after a certain time I've been reading about saving the state and refreshing but I can't seem to get it to work I've also tried storing the canvas context to a array and splicing the items from it when it get's over a certain length but again to no luck... here's my code (which is huge so I've set up a plunkr):

`var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
     $scope.canvas = $('#spiro')[0];
    $scope.canvascanvasContext =  $scope.canvas.getContext("2d");
    //interval
    $scope.timerId = 0;

    console.log($scope.canvas);
//MOUSE OVER
/*
$scope.getMousePos = function getMousePos(evt) {
    var rect = $scope.canvas.getBoundingClientRect();
    
      $scope.mouseX = evt.clientX - rect.left;
      $scope.mouseY = evt.clientY - rect.top;
      $scope.canvascanvasContext.fillStyle = "rgb("+$scope.red+", "+$scope.green+", "+$scope.blue+")";
      $scope.canvascanvasContext.fillRect($scope.mouseX, $scope.mouseY, 4, 4);
    

    console.log(evt.clientX);
}
  */
  $scope.clearit = function clearit(){
    // Store the current transformation matrix
  //  $scope.canvascanvasContext.save();

    // Use the identity matrix while clearing the canvas
    $scope.canvascanvasContext.setTransform(1, 0, 0, 1, 0, 0);
    $scope.canvascanvasContext.clearRect(0, 0, $scope.width, $scope.height);
    $scope.canvas.width = $scope.canvas.width;
  };
  $scope.randomColor = function randomColor(num) {return Math.floor(Math.random() * num);}
  $scope.canvascanvasContextArray = [];

  $scope.draw = function draw(e){
    $scope.now = new Date();
    $scope.sec = $scope.now.getMilliseconds();
    $scope.min = $scope.now.getMinutes();
    $scope.hr  = $scope.now.getHours();
        $scope.canvascanvasContext.beginPath();
        
        $scope.canvascanvasContext.arc(350, $scope.canvas.width/2,  $scope.canvas.width/2 ,0, 2 * Math.PI, true);

        $scope.canvascanvasContext.clip();


        $scope.canvascanvasContext.beginPath();


        $scope.Xmove = Math.floor((Math.random() * 345) - 1);
        $scope.Ymove = Math.floor((Math.random() * 345) - 1);
        $scope.quadracpx = Math.floor((Math.random() * 700) + 1);
        $scope.quadracpy = Math.floor((Math.random() * 700) + 1);
        $scope.quadrax = Math.floor((Math.random() * 700) + 1);
        $scope.quadray = Math.floor((Math.random() * 700) + 1);
        $scope.red = $scope.randomColor(255);
        $scope.green = $scope.randomColor(255);
        $scope.blue = $scope. randomColor(255);
        $scope.grd = $scope.canvascanvasContext.createLinearGradient($scope.quadracpx,$scope.quadracpy,$scope.quadrax,$scope.quadray);
          // Create color gradient
        $scope.grd.addColorStop(0,    "rgba("+$scope.red+", "+$scope.green+", "+$scope.blue+", 0)");
        $scope.grd.addColorStop(0.15, "rgba("+$scope.red+", "+$scope.green+", "+$scope.blue+", 0.1)");
        $scope.grd.addColorStop(0.33, "rgba("+$scope.red+", "+$scope.green+", "+$scope.blue+", 0.1)");
        $scope.grd.addColorStop(0.49, "rgba("+$scope.red+", "+$scope.green+", "+$scope.blue+", 0.2)");
        $scope.grd.addColorStop(0.67, "rgba("+$scope.red+", "+$scope.green+", "+$scope.blue+", 0.3)");
        $scope.grd.addColorStop(0.84, "rgba("+$scope.red+", "+$scope.green+", "+$scope.blue+", 0.6)");
        $scope.grd.addColorStop(1,    "rgba("+$scope.red+", "+$scope.green+", "+$scope.blue+" , 1)");
        $scope.canvascanvasContext.strokeStyle = $scope.grd;
        $scope.canvascanvasContext.fillStyle = $scope.grd;
        $scope.canvascanvasContext.lineCap = 'round';
        $scope.canvascanvasContext.shadowBlur = 10;
        $scope.canvascanvasContext.shadowColor = "rgb("+$scope.red+", "+$scope.green+", "+$scope.blue+")";



     //   $scope.canvascanvasContext.moveTo(350,350);
        
     //         arc(x,y,r,start,stop)
      // Move registration point to the center of the canvas

     
      $scope.canvascanvasContext.translate($scope.canvas.width/2, $scope.canvas.width/2);
       $scope.canvascanvasContext.rotate(Math.PI/90);
        $scope.canvascanvasContext.translate(-$scope.canvas.width/2, -$scope.canvas.width/2);
        
     $scope.canvascanvasContext.arc(350, $scope.canvas.width/4,  $scope.canvas.width/10 ,350, 2 * Math.PI, true);
     
     

     //   $scope.canvascanvasContext.arc($scope.quadray, $scope.quadrax, $scope.quadracpy , $scope.Ymove, $scope.Xmove, true);
       // $scope.canvascanvasContext.arc($scope.Ymove, $scope.Xmove, $scope.quadracpy , $scope.quadracpx, $scope.quadray, true);

       // $scope.canvascanvasContext.quadraticCurveTo($scope.quadracpx,$scope.quadracpy,$scope.quadrax,$scope.quadray);



        $scope.canvascanvasContext.stroke();



        $scope.canvascanvasContextArray.push($scope.canvascanvasContext);

        
        
      if($scope.canvascanvasContextArray.length> 4){
        $scope.canvascanvasContext.save();
          var indexToRemove = 0;
          var numberToRemove = 1;

          $scope.canvascanvasContextArray.splice(indexToRemove, numberToRemove);
          $scope.canvascanvasContextArray[0].globalAlpha = 0;
        $scope.canvascanvasContext.restore();
      }

        console.log($scope.canvascanvasContextArray);
        console.log($scope.sec)

  };

  $scope.drawit = function drawit(){
    $scope.timerId = setInterval($scope.draw, 20);
    setInterval($scope.rotate, 40);


  };
$scope.rotate = function rotate(){
      /*$scope.canvascanvasContext.translate($scope.Xmove, $scope.Ymove);
        $scope.canvascanvasContext.rotate(Math.PI/45);
        $scope.canvascanvasContext.translate(-$scope.Xmove, -$scope.Ymove);*/
} 
  $scope.stopit = function stopit(){
      clearInterval($scope.timerId);
  };

});`

Thank you to anybody who takes the time to look into this.. Chris

Community
  • 1
  • 1
vimes1984
  • 1,684
  • 3
  • 26
  • 59

2 Answers2

11

Live Demo

Personally how I do it is I set the fillStyle to RGBA and set the alpha to something under 1, like 0.2 for example.

ctx.fillStyle = "rgba(255,255,255,0.2)";

Every time you then fill the canvas you are slowly erasing what was drawn on it prior. In the example below the function is called every 200ms but you can play with the alpha value, or the timeout value to get the fade speed you need.

This is how the effect looks when set to 100ms, and 0.3 alpha fill.

enter image description here

var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d"),
    painting = false,
    lastX = 0,
    lastY = 0;

canvas.width = canvas.height = 600;

canvas.onmousedown = function (e) {
    painting = !painting;

    lastX = e.pageX - this.offsetLeft;
    lastY = e.pageY - this.offsetTop;
};

canvas.onmousemove = function (e) {
    if (painting) {
        mouseX = e.pageX - this.offsetLeft;
        mouseY = e.pageY - this.offsetTop;

        ctx.beginPath();
        ctx.moveTo(lastX, lastY);
        ctx.lineTo(mouseX, mouseY);
        ctx.stroke();

        lastX = mouseX;
        lastY = mouseY;
    }
}

function fadeOut() {
    ctx.fillStyle = "rgba(255,255,255,0.1)";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    setTimeout(fadeOut,200);
}

fadeOut();
Freek de Bruijn
  • 3,552
  • 2
  • 22
  • 28
Loktar
  • 34,764
  • 7
  • 90
  • 104
4

There is 1-and-only-1 context per canvas element so saving multiple contexts in an array won't do anything--it just saves the 1 context multiple times.

Here's one way of drawing a "disappearing" line:

  • Save each mouse coordinate (from mousemove) in a points array.

  • Create a draw function that draws those points as a line.

  • Execute the draw function in an animation loop.

  • With each loop through the animation, leave out drawing another point from the start of the points array.

Example code and a Demo: http://jsfiddle.net/m1erickson/LSL68/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
    body{ background-color: ivory; }
    #canvas{border:1px solid red;}
</style>
<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    ctx.lineCap = "round";
    ctx.lineJoin = "round";
    ctx.lineWidth=4;
    ctx.strokeStyle="blue";

    var $canvas=$("#canvas");
    var canvasOffset=$canvas.offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;
    var scrollX=$canvas.scrollLeft();
    var scrollY=$canvas.scrollTop();

    var isDown=false;
    var startX;
    var startY;

    var points=[];
    var s=0;
    animate();

    function drawLatestLines(){
        s+=0.50;   
        var ss=parseInt(s);
        if(s>points.length-2){return;}
        ctx.clearRect(0,0,canvas.width,canvas.height);
        ctx.beginPath();
        ctx.moveTo(points[ss].x,points[ss].y);
        for(var i=ss;i<points.length;i++){
            ctx.lineTo(points[i].x,points[i].y);        
        }
        ctx.stroke();
    }

    function animate(){
        requestAnimationFrame(animate);
        drawLatestLines();
    }

    function handleMouseDown(e){
      e.preventDefault();
      e.stopPropagation();

      startX=parseInt(e.clientX-offsetX);
      startY=parseInt(e.clientY-offsetY);

      // Put your mousedown stuff here
      points.length=0;
      points.push({x:startX,y:startY});
      s=0;
      isDown=true;

    }

    function handleMouseUp(e){
      e.preventDefault();
      e.stopPropagation();

      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);

      // Put your mouseup stuff here
      isDown=false;
    }

    function handleMouseOut(e){
      e.preventDefault();
      e.stopPropagation();

      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);

      // Put your mouseOut stuff here
      isDown=false;
    }

    function handleMouseMove(e){
      if(!isDown){return;}
      e.preventDefault();
      e.stopPropagation();

      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);

      points.push({x:mouseX,y:mouseY});

    }

    $("#canvas").mousedown(function(e){handleMouseDown(e);});
    $("#canvas").mousemove(function(e){handleMouseMove(e);});
    $("#canvas").mouseup(function(e){handleMouseUp(e);});
    $("#canvas").mouseout(function(e){handleMouseOut(e);});

}); // end $(function(){});
</script>
</head>
<body>
    <h4>drag the mouse quickly to draw disappearing line.</h4>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
markE
  • 102,905
  • 11
  • 164
  • 176