简体   繁体   English

在画布上绘画并自动删除(HTML5)

[英]Painting On A Canvas And Deleting It Automatically (HTML5)

Here's my objective. 这是我的目标。 I want to literally paint on a canvas element then automatically erase it in a quick gradual manner. 我想在画布元素上绘画,然后以快速渐进的方式自动擦除它。 The similar implementation is somewhat like this: http://mario.ign.com/3D-era/super-mario-sunshine 类似的实现有点像这样: http//mario.ign.com/3D-era/super-mario-sunshine

I want to make it simple. 我想简单一点。 I just simply want to paint and then erase the recently painted stroke. 我只是想画画然后擦掉最近画过的笔画。 Where do I start? 我从哪里开始? Is there a simple approach on painting on a canvas without using any kind of plugin? 是否有一种简单的方法在画布上绘画而不使用任何类型的插件? I am currently using wPaint.js and it's not really what I want. 我目前正在使用wPaint.js,这不是我想要的。 Is there a way of painting on a canvas and undoing without too much complex code? 有没有一种方法可以在画布上绘画并在没有太多复杂代码的情况下撤消?

Here is how to let the user draw a self-disappearing line: 以下是如何让用户绘制一条自我消失的线:

Create a polyline by saving points to an array when the user drags the mouse. 当用户拖动鼠标时,通过将点保存到数组来创建折线。

In an animation loop, clear the screen and redraw that polyline. 在动画循环中,清除屏幕并重绘该折线。

But each loop, leave out the earliest points (making the earliest points “disappear”). 但是每个循环都会遗漏最早的点(使最早的点“消失”)。

Here is code and a Fiddle: http://jsfiddle.net/m1erickson/LT6Ln/ 这是代码和小提琴: 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>

[ Update: Using complex effects instead of a simple line ] [更新:使用复杂效果而不是简单的线条]

Sure. 当然。 You can use a spraypaint effect instead of a line. 您可以使用喷涂效果而不是线条。

However, this effect requires some expensive processing! 但是,这种效果需要一些昂贵的处理!

The spraypaint effect is often created by drawing multiple random 1x1 pixels around a centerpoint. 通常通过围绕中心点绘制多个随机1x1像素来创建喷涂效果。

Assuming 10 droplets per “spray”, every point along your polyline requires: 假设每个“喷雾”有10个液滴,沿着折线的每个点都需要:

  • 10 X fillRect(x,y,1,1) draws on the canvas (instead of 1 X lineTo for the simple line). 10 X fillRect(x,y,1,1)在画布上绘制(而不是简单线的1 X lineTo)。
  • 20 X Math.random, 20 X Math.random,
  • 10 X Math.cos and 10 X Math.cos和
  • 10 X Math.sin. 10 X Math.sin。

Here's an example fiddle of a “spraypaint” effect: http://jsfiddle.net/m1erickson/zJ2ZR/ 这是一个“喷雾”效果的例子: http//jsfiddle.net/m1erickson/zJ2ZR/

Keep in mind that all this processing must take place within the small time allowed by requestAnimationFrame (often 16-50 milliseconds per frame). 请记住,所有这些处理必须在requestAnimationFrame允许的较小时间内进行(通常每帧16-50毫秒)。

Doing the expensive spraypaint on each of 20-50 accumulated points along the polyline will likely not fit inside the time of an RAF frame. 沿着折线在20-50个累积点中的每一个上进行昂贵的喷涂可能不适合RAF框架的时间。

To make spraypainting fit inside the time allowed by RAF, you will need to “cache” the effect: 要在RAF允许的时间内完成喷涂,您需要“缓存”效果:

  1. Create 1 random “spray” in a 10px by 10px offscreen canvas. 在10px x 10px的屏幕外画布上创建1个随机“喷雾”。
  2. Create an image from that canvas using canvas.toDataURL. 使用canvas.toDataURL从该画布创建图像。
  3. Add that image to an array. 将该图像添加到数组中。
  4. Repeat step #1 maybe a dozen times (to get a good variety of random spray images) 重复步骤#1可能十几次(以获得各种各样的随机喷雾图像)

Then instead of context.lineTo or spraypainting on-the-fly, just do this: 然后,而不是context.lineTo或动态喷涂,只需这样做:

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

Use Kinetic.js . 使用Kinetic.js。 Its is very easy to learn. 它很容易学习。 By this you can add or remove any painted stroke very easly. 通过这种方式,您可以非常轻松地添加或删除任何绘制的笔划。 See the working of it from here : http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-batch-draw/ 从这里查看它的工作: http//www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-batch-draw/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM