绘制画布后淡出线条?

Posted

技术标签:

【中文标题】绘制画布后淡出线条?【英文标题】:fade out lines after drawing canvas? 【发布时间】:2014-08-07 21:55:53 【问题描述】:

好的,我正在画布对象上绘制笔触线,它工作正常我想做的是删除线条或在一段时间后将它们淡出我一直在阅读有关保存状态和刷新的信息,但是我似乎无法让它工作我还尝试将画布上下文存储到一个数组中,并在它超过一定长度时从其中拼接项目,但再次没有运气...... 这是我的代码(很大,所以我设置了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);
  ;

);`

感谢任何花时间研究此问题的人。 克里斯

【问题讨论】:

【参考方案1】:

Live Demo

就我个人而言,我将fillStyle 设置为 RGBA,并将 alpha 设置为低于 1 的值,例如 0.2。

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

每次你填充画布时,你都会慢慢擦除之前在画布上绘制的内容。在下面的示例中,该函数每 200 毫秒调用一次,但您可以使用 alpha 值或超时值来获得所需的渐变速度。

这是设置为 100 毫秒和 0.3 alpha 填充时的效果。

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();

【讨论】:

【参考方案2】:

每个画布元素有 1-and-only-1 上下文,因此在数组中保存多个上下文不会做任何事情 - 它只是多次保存 1 个上下文。

这是绘制“消失”线的一种方法:

将每个鼠标坐标(来自 mousemove)保存在点数组中。

创建一个绘制函数,将这些点绘制为一条线。

在动画循环中执行绘制函数。

随着动画的每次循环,不要从点数组的开头绘制另一个点。

示例代码和演示: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; 
    #canvasborder: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>

【讨论】:

以上是关于绘制画布后淡出线条?的主要内容,如果未能解决你的问题,请参考以下文章

Canvas-橡皮擦在画布保存为图像后在画布上绘制黑色线条

当使用洪水填充算法填充颜色后绘制线条时,填充颜色消失

如何在画布上动画绘制线条

canvas绘制线条怎么改变线条长度

Java jFrame画布绘制点而不是线条

在画布 (HTML5) 上绘制好看的(如在 Flash 中)线条 - 可能吗?