javascript - 在 Canvas 上绘画并自动删除它 (HTML5)

标签 javascript html canvas

这是我的目标。我想在 Canvas 元素上进行绘画,然后以快速渐进的方式自动删除它。类似的实现有点像这样:http://mario.ign.com/3D-era/super-mario-sunshine

我想让事情变得简单。我只是想画画然后删除最近画的笔画。我从哪说起呢?是否有一种无需使用任何插件即可在 Canvas 上绘画的简单方法?我目前正在使用 wPaint.js,但它并不是我真正想要的。有没有一种方法可以在 Canvas 上绘画并撤消,而无需太多复杂的代码?

最佳答案

以下是如何让用户绘制一条自动消失的线:

当用户拖动鼠标时,通过将点保存到数组来创建折线。

在动画循环中,清除屏幕并重新绘制多段线。

但是每次循环都会忽略最早的点(使最早的点“消失”)。

这是代码和 fiddle :http://jsfiddle.net/m1erickson/LT6Ln/

<!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(){

    window.requestAnimFrame = (function(callback) {
      return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
      function(callback) {
        window.setTimeout(callback, 1000 / 60);
      };
    })();


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

    var canvasOffset=$("#canvas").offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;
    var isDown=false;
    var points=[];
    var minPoint=0;
    var PI2=Math.PI*2
    var radius=20;
    var fps = 20;
    var lastTime=0;

    animate();

    function animate() {
      setTimeout(function() {

        requestAnimFrame(animate);

        // draw a polyline using the saved points array
        // but start later in the array each animation loop
        if(minPoint<points.length){
            ctx.clearRect(0,0,canvas.width,canvas.height)
            ctx.beginPath();
            ctx.moveTo(points[minPoint].x,points[minPoint.y]);
            for(var i=minPoint+1;i<points.length;i++){
                var pt=points[i];
                ctx.lineTo(pt.x,pt.y);
            }
            ctx.stroke();
            minPoint++;
        }
      }, 1000 / fps);

    }

    function handleMouseDown(e){
      isDown=true;
    }

    function handleMouseUp(e){
      isDown=false;
    }

    function handleMouseOut(e){
      isDown=false;
    }

    function handleMouseMove(e){
        if(!isDown){return;}
        mouseX=parseInt(e.clientX-offsetX);
        mouseY=parseInt(e.clientY-offsetY);
        // accumulate points for the polyline but throttle 
        // the capture to prevent clustering of points
        if(Date.now()-lastTime>20){
            points.push({x:mouseX,y:mouseY});
            lastTime=Date.now();
        }
    }

    $("#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>
    <h3>Drag to create a self-clearing line.</h3>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

[更新:使用复杂的效果而不是简单的线条]

当然。您可以使用喷漆效果而不是线条。

但是,这种效果需要一些昂贵的处理!

喷漆效果通常是通过围绕中心点绘制多个随机 1x1 像素来创建的。

假设每次“喷雾”有 10 个液滴,沿多段线的每个点都需要:

  • 10 X fillRect(x,y,1,1) 在 Canvas 上绘制(而不是 1 X lineTo 的简单线条)。
  • 20 X Math.random,
  • 10 X Math.cos 和
  • 10 X Math.sin。

这是一个“喷漆”效果的示例:http://jsfiddle.net/m1erickson/zJ2ZR/

请记住,所有这些处理必须在 requestAnimationFrame 允许的短时间内进行(通常每帧 16-50 毫秒)。

沿着折线对 20-50 个累积点进行昂贵的喷漆可能无法在 RAF 框架的时间内完成。

为了使喷漆在 RAF 允许的时间内完成,您需要“缓存”效果:

  1. 在 10 像素 x 10 像素的离屏 Canvas 中创建 1 个随机“喷雾”。
  2. 使用 canvas.toDataURL 从该 Canvas 创建图像。
  3. 将该图像添加到数组中。
  4. 重复步骤 #1 大约十几次(以获得各种随机喷雾图像)

然后,不要使用 context.lineTo 或即时喷涂,只需执行以下操作:

context.drawImage(myCachedSprays[nextSprayIndex],point.x,point.y);

关于javascript - 在 Canvas 上绘画并自动删除它 (HTML5),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19975917/

相关文章:

javascript - 如何在 HTML5 Canvas 中平滑缩放图案图像?

android - canvas.drawBitmap() 在平铺位图时第一次绘制位图需要更多时间

javascript - 无法删除 leaflet.js 中带有簇的图层

javascript - 如何克隆数组并将新值推送到链中?

html - 我希望背景图片模糊

php - 解析 html 表 tr 标签丢失

javascript - 如何在此示例中添加 ondrag 鼠标事件

javascript - 表格图像表格对齐问题

javascript - 根据子 DOM 元素的值应用不同的类

javascript - 我想让关键帧的动画从单击按钮开始