运行我的脚本时,浏览器中的javascript控制台没有响应

时间:2014-04-23 05:57:45

标签: javascript html5 canvas

我写了一个简单的脚本来在HTML5画布上绘制路径,但是当在chrome中运行javascript时:

路径增长的时间越长(就像我绘制的那样),页面响应越少,最终javascript控制台完全卡住,我注意到CPU几乎100%忙碌。你能给我一些提示吗?

这是我的代码:

<!DOCTYPE html>
<head>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
    <script>
        var clickX = new Array();
        var clickY = new Array();
        var clickDrag = new Array();
        var paint;
        var context;

        window.onload =function(){init();}; 

        function init(){
            context = document.getElementById("surface").getContext("2d");

            $('#surface').mousedown(function(e){
                var touchX = e.pageX - this.offsetLeft;
                var touchY = e.pageY - this.offsetTop;

                paint = true;
                addClick(touchX, touchY);
                redraw();
            });
            $('#surface').mousemove(function(e){
                if(paint){
                    addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop);
                    redraw();
                }
            });
            $('#surface').mouseup(function(e){
                paint = false;
            });
            $('#surface').mouseleave(function(e){
                paint = false;
            });
        };
        function addClick(x, y){
            clickX.push(x);
            clickY.push(y);
        }

        function redraw(){
            context.strokeStype = "#df4b26";
            context.lineJoin = "round";
            context.lineWidth = 5;

            console.log(clickX.length);
            context.beginPath();
            for(var i=0; i<clickX.length;i++){
                context.lineTo(clickX[i], clickY[i]);
                console.log(clickX[i]+", "+clickY[i]);
                context.stroke();
            }
            context.closePath();
        }
    </script>
</head>
<body>
    <canvas id="surface" style="border:1px solid #000000;"  width="800" height ="600"></canvas>
</body>

3 个答案:

答案 0 :(得分:1)

以下是我注意到的一些问题:

重构一些代码后的演示:http://jsfiddle.net/m1erickson/LStXc/

  • 重绘时出现拼写错误(strokeStype s / b strokeStyle

  • 如果您的项目不需要保存/重复使用用户的折线,则无需将鼠标位置保存在数组中。您可以通过在每个mousemove事件中添加.lineTo来连续绘制线条。

一些性能问题:

  • 调用外部函数(作为你的addClick)比内联命令慢,所以考虑将addClick代码移动到mousemove处理程序中。

  • 如果您的画布没有重新定位,您可以在草绘开始前计算一次偏移。

  • 设置上下文状态(.strokeStyle,.lineJoin,.lineWidth)在像鼠标处理程序这样非常活跃的函数中重复时相对昂贵。如果您的状态在草图中没有变化,那么在草绘开始之前设置一次

示例代码:

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

    var canvas=document.getElementById("surface");
    var context=canvas.getContext("2d");

    var canvasOffset=$("#surface").offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;

    context.strokeStyle = "#df4b26";
    context.lineJoin = "round";
    context.lineWidth = 5;

    var clickX = new Array();
    var clickY = new Array();
    var clickDrag = new Array();
    var paint;
    var context;


        $('#surface').mousedown(function(e){
            var touchX = e.clientX - offsetX;
            var touchY = e.clientY - offsetY;

            paint = true;
            clickX.push(e.clientX-offsetX);
            clickY.push(e.clientY-offsetY);
            lastX=touchX;
            lastY=touchY;
        });
        $('#surface').mousemove(function(e){
            if(paint){
                var x=e.clientX-offsetX;
                var y=e.clientY-offsetY;
                clickX.push(x);
                clickY.push(y);
                context.beginPath();
                context.moveTo(lastX,lastY)
                context.lineTo(x,y);
                context.stroke();
                context.closePath();
                lastX=x;
                lastY=y;
            }
        });
        $('#surface').mouseup(function(e){
            paint = false;
        });
        $('#surface').mouseleave(function(e){
            paint = false;
        });


}); // end $(function(){});
</script>
</head>
<body>
    <canvas id="surface" width=300 height=300></canvas>
</body>
</html>

答案 1 :(得分:0)

尝试以下代码。希望这对你有用

<head>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
    <script>
        var paint;
        var context;

        window.onload =function(){init();}; 

        function init(){
            context = document.getElementById("surface").getContext("2d");

            $('#surface').mousedown(function(e){
                var touchX =  e.pageX; //e.pageX - this.offsetLeft;
                var touchY = e.pageY; //e.pageY - this.offsetTop;

                paint = true;
                context.beginPath();
                redraw(touchX, touchY);
            });
            $('#surface').mousemove(function(e){
                if(paint){
                    var touchX =  e.pageX; //e.pageX - this.offsetLeft;
                    var touchY = e.pageY; //e.pageY - this.offsetTop;
                    redraw(touchX, touchY);
                }
            });
            $('#surface').mouseup(function(e){
                paint = false;
            });
            $('#surface').mouseleave(function(e){
                paint = false;
            });
        };

        function redraw(nextX,nextY){
            context.strokeStype = "#df4b26";
            context.lineJoin = "round";
            context.lineWidth = 5;

            console.log(clickX.length);

                context.lineTo(nextX, nextY);
                console.log(nextX+", "+nextY);
                context.stroke();
            //context.closePath();
        }
    </script>
</head>
<body>
    <canvas id="surface" style="border:1px solid #000000;"  width="800" height ="600"></canvas>
</body>

答案 2 :(得分:0)

您可以尝试使用此重绘功能:

var actClick = 0;
function redraw(){
    context.strokeStype = "#df4b26";
    context.lineJoin = "round";
    context.lineWidth = 5;

    console.log(clickX.length);
    context.beginPath();
    actClick = actClick - 2;
    for( ; actClick < clickX.length ; actClick++ ){
        context.lineTo(clickX[actClick], clickY[actClick]);
        context.stroke();
    }
    context.closePath();
}

您可以找到jsFiddle

问题在于你每个新点重绘wole图像,所以每个新点都会变慢。