简体   繁体   English

画布和动画

[英]Canvas and animation

I was trying to create a sample paint application using HTML 5 canvas. 我试图使用HTML 5 canvas创建一个示例绘画应用程序。 Then I added a button to redraw what user had drawn earlier. 然后,我添加了一个按钮以重绘用户之前绘制的内容。 I am not sure what I am doing wrong or may be completely wrong. 我不确定自己在做什么错或可能完全错了。 When I click redraw button multiple times it generates some magical animation by drawing lines all over. 当我多次单击重绘按钮时,它会通过在各处绘制线条来生成一些神奇的动画。 Even though if I log the starting point of drawing the image its same every time. 即使我每次都记录绘制图像的起点相同。

Demo: http://jsfiddle.net/BW57H/6/ Demo: http Demo: //jsfiddle.net/BW57H/6/

Steps to reproduce: 重现步骤:

Draw some circle or rectangle or something by clicking the mouse and dragging it on the rectangular box. 通过单击鼠标并将其拖动到矩形框上来绘制一些圆形或矩形或其他形状。 Then click reset and redraw , click redraw couple of times after that and see the result. 然后单击“重置并重绘”,然后单击“重绘”几次,然后查看结果。

I am not sure what I have done. 我不确定我做了什么。 I have not read a lot about Canvas. 我还没有阅读有关Canvas的很多文章。 But I am curious to know what is going on here. 但是我很好奇这是怎么回事。 Thanks. 谢谢。

html html

<body>
    <canvas id="paint" width="600px" height="300px"></canvas>


    <div id="controls">
        <button name="reset" id="reset">Reset</button>
        &nbsp;<button name="redraw" id="redraw">Re-Draw</button>
    </div>
</body>

css 的CSS

#paint{
    border: solid;
}

js js

$(document).ready(function(){


    var x, y, context, painter;

    var xCounter = 0 , yCounter = 0;
    var xarray = [];
    var yarray = [];

    function init(){
        while(document.getElementById("paint") === undefined){
            //do nothing
        }

        console.log("Loaded document now registering events for canvas");
        var canvas = document.getElementById("paint");

        context = canvas.getContext('2d'); 
        painter = new Painter();

        canvas.addEventListener('mousedown', capture, false);
        canvas.addEventListener('mouseup', capture, false);
        canvas.addEventListener('mousemove', capture, false);

        document.getElementById("reset").addEventListener("click",function(){ clearCanvas(canvas);}, false);

            document.getElementById("redraw").addEventListener("click",             function(){
                autoDraw();
            }, false);
    }

    function clearCanvas(canvas){
    context.save();

    // Use the identity matrix while clearing the canvas
    context.setTransform(1, 0, 0, 1, 0, 0);
    context.clearRect(0, 0, canvas.width, canvas.height);

    // Restore the transform
    context.restore();

    };

    function capture(event){

        if(event.which !== 1){
            return;
        }   

        x = event.layerX;
        y = event.layerY;

        switch(event.type){
            case 'mousedown':
                painter.startPaint(event);
                break;
            case 'mouseup':
                painter.endPaint(event);
                break;
            case 'mousemove':
                painter.paint(event);
                break;
        }


    };


    var Painter = function(){

        var self = this;
        self.paintStarted = false;

        self.startPaint  = function(event){
                self.resetRecordingParams();
                self.paintStarted = true;
                context.beginPath();
                context.moveTo(x,y);
                self.record(); 
        }

        self.endPaint = function(event){
                self.paintStarted = false;
                self.record();
                self.paint(event)
        }

        self.paint  = function(event){
            if(self.paintStarted){
                context.lineTo(x,y); 
                context.stroke(); 
                self.record();
            }
        }

        self.record = function(){
            xarray[xCounter++] = x;
            yarray[yCounter++] = y;
        }

        self.resetRecordingParams = function(){
            xarray = [];
            yarray = [];
            xCounter = 0;
            yCounter= 0;
        }

    return self;

    }


    function autoDraw(){
        context.beginPath();

        console.log('starting at: '+xarray[0]+','+yarray[0]);
        context.moveTo(xarray[0],yarray[0]);

        for (var i = 0; i < xarray.length; i++) {
            setTimeout(drawLineSlowly, 1000+(i*20), i); 
        }; 

    }

    function drawLineSlowly(i)
    {
        context.lineTo(xarray[i],yarray[i]); 
        context.stroke(); 

    }

    init();
});

Obviously you don't stop the previous timeout loop before you start a new... 显然,在开始新的超时循环之前,您不会停止前一个超时循环。

Use setInterval instead of setTimeout, and clearInterval by next push. 使用setInterval代替setTimeout,并在下一次推送时清除clearInterval。 So I think the problem is not with the canvas, just with your redraw animation. 因此,我认为问题不在于画布,而在于您的重绘动画。 Btw it is strange because there is some difference between the redraw and the original draw... 顺便说一句,这很奇怪,因为重画和原始画之间有些区别...

var drawInterval = null;

function autoDraw(){
    if (drawInterval) {
        //here your can reset the previous - still running - redraw
        clearInterval(drawInterval);
    }

    context.beginPath();

    console.log('starting at: '+xarray[0]+','+yarray[0]);
    context.moveTo(xarray[0],yarray[0]);

    var i=0;
    setInterval(function (){
        ++i;
        if (i<xarray.length)
            drawLineSlowly(i);
        else
            clearInterval(drawInterval);
    },20);

}

note: There is still bug in the redraw, but at least it does not kill the browser... Btw the strange "animation" is because you does not check by redraw if you are currently drawing or not, so you start draw and redraw together and they interfere... You have to stop redraw when you start drawing. 注意:重绘中仍然存在错误,但是至少它不会杀死浏览器...奇怪的是,“动画”是因为您不通过重绘来检查当前是否正在绘制,因此开始绘制并重绘在一起,它们会相互干扰...开始绘制时必须停止重绘。

You don't have any kind of check to see whether or not you are already drawing, so here is your code with those changes commented, as well as the real-pixel-location fixes ( http://jsfiddle.net/upgradellc/htJXy/1/ ): 您无需进行任何检查即可查看是否已在绘制图形,因此这是注释了这些更改的代码以及实际像素位置修复程序( http://jsfiddle.net/upgradellc/ htJXy / 1 / ):

$(document).ready(function(){
    var x, y, context, painter, canvas;

    var xCounter = 0 , yCounter = 0;
    var xarray = [];
    var yarray = [];

    function init(){
        while(document.getElementById("paint") === undefined){
            //do nothing
        }

        console.log("Loaded document now registering events for canvas");
        canvas = document.getElementById("paint");

        context = canvas.getContext('2d'); 
        painter = new Painter();

        canvas.addEventListener('mousedown', capture, false);
        canvas.addEventListener('mouseup', capture, false);
        canvas.addEventListener('mousemove', capture, false);

        document.getElementById("reset").addEventListener("click",function(){ clearCanvas(canvas);}, false);

            document.getElementById("redraw").addEventListener("click", function(){
                autoDraw();
            }, false);
    }

    function clearCanvas(canvas){
    context.save();

    // Use the identity matrix while clearing the canvas
    context.setTransform(1, 0, 0, 1, 0, 0);
    context.clearRect(0, 0, canvas.width, canvas.height);

    // Restore the transform
    context.restore();

    };

    function capture(event){  
        if(event.which !== 1){
            return;
        }   

        tempPos = getMousePos(canvas, event);
        x = tempPos.x;
        y = tempPos.y;

        switch(event.type){
            case 'mousedown':
                painter.startPaint(event);
                break;
            case 'mouseup':
                painter.endPaint(event);
                break;
            case 'mousemove':
                painter.paint(event);
                break;
        }

    };


    var Painter = function(){
        var self = this;
        self.paintStarted = false;
        //this keeps track of whether or not we are currently auto drawing
        self.currentlyAutoDrawing = false;

        self.startPaint  = function(event){
                self.resetRecordingParams();
                self.paintStarted = true;
                context.beginPath();
                context.moveTo(x,y);
                self.record(); 
        }

        self.endPaint = function(event){
                self.paintStarted = false;
                self.record();
                self.paint(event);
        }

        self.paint  = function(event){
            if(self.paintStarted){
                context.lineTo(x,y); 
                context.stroke(); 
                self.record();
            }
        }

        self.record = function(){
            xarray[xCounter++] = x;
            yarray[yCounter++] = y;
        }

        self.resetRecordingParams = function(){
            xarray = [];
            yarray = [];
            xCounter = 0;
            yCounter= 0;
        }

    return self;

    }


    function autoDraw(){
        context.beginPath();
        //If we are already auto-drawing, then we should just return instead of starting another drawing loop cycle
        if(painter.currentlyAutoDrawing){
            console.log("painter is already auto drawing");
            return;
        }
        painter.currentlyAutoDrawing = true;
        console.log('starting at: '+xarray[0]+','+yarray[0]);
        context.moveTo(xarray[0],yarray[0]);

        for (var i = 0; i < xarray.length; i++) {
            setTimeout(drawLineSlowly, 1000+(i*20), i); 
        }; 

    }

    function drawLineSlowly(i)
    {
        //when we reach the last element in the array, update painter with the fact that autodrawing is now complete
        if(xarray.length == i+1){
            painter.currentlyAutoDrawing=false;
        }
        console.log(xarray.length+" "+i);
        context.lineTo(xarray[i],yarray[i]); 
        context.stroke(); 

    }

    function getMousePos(canv, evt) {
        var rect = canv.getBoundingClientRect();
        return {
          x: evt.clientX - rect.left,
          y: evt.clientY - rect.top
        };
    }

    init();
});

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

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