javascript - Canvas 和动画

标签 javascript html5-canvas

我试图使用 HTML 5 Canvas 创建一个示例绘画应用程序。然后我添加了一个按钮来重绘用户之前绘制的内容。我不确定我做错了什么或者可能完全错误。当我多次单击重绘按钮时,它会通过在各处绘制线条来生成一些神奇的动画。即使我记录每次绘制图像的起点都是相同的。

演示: http://jsfiddle.net/BW57H/6/

重现步骤:

通过单击鼠标并将其拖动到矩形框上来绘制一些圆形或矩形或其他东西。然后点击重置和重绘,然后点击重绘几次,看看结果。

我不确定我做了什么。我没有读过很多关于 Canvas 的文章。但我很想知道这里发生了什么。谢谢。

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

#paint{
    border: solid;
}

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

最佳答案

您没有任何类型的检查来查看您是否已经在绘图,因此这里是您的代码,其中注释了这些更改,以及真实像素位置修复( 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();
});

关于javascript - Canvas 和动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17159973/

相关文章:

javascript - onmouseover 并单击目标 div 并替换文本

javascript - 使用 Google Maps API 进行地理编码 - 更新现有标记而不是添加另一个标记

javascript - 使用 onBoundsChanged react 谷歌地图重新渲染问题

javascript - 无法使用现有 Canvas 元素添加新 Canvas 元素

javascript - Canvas 饼图中的标签

Javascript:使用 slice() 从数组中选择除一项以外的所有项?

javascript - 使用@ViewChild {读取: ElementRef } of component causes unit test to fail

javascript - 如何提高 HTML Canvas 绘制像素的性能

html - Chrome 上的 Canvas drawImage 类型错误

javascript - Jquery Onclick 事件函数第二次不起作用