[Safari / Chrome致命错误] HTML5画布不适用于特定情况,但Firefox表现不错

时间:2014-01-14 23:25:52

标签: javascript html5 google-chrome canvas safari

我使用html5 canvas来构建功能图软件。 有一个严重的错误,但我不知道发生了什么。

也就是说,当我打电话时:

yOFxGraph(plotFUNCinputYofX,-4,5,-4,4,"rgb(66,44,255)",1);

在Mac上的Firefox26 / Chrome32 / Safari7中一切正常。

但是,当我更改只有一个微小参数时,如:

yOFxGraph(plotFUNCinputYofX,-5,5,-4,4,"rgb(66,44,255)",1);
只是在Chrome / Safari中消失,但在Firefox中仍然有效

整个代码如下,请您告诉我如何解决?非常感谢你。 这个错误怎么会发生在主流浏览器上呢?无论代码如此简单。

<!doctype html>
<html>
<body onload="draw()">
    <script>
    function plotFUNCinputYofX(x) {return 1/Math.sin(x);}

    function draw() {
       yOFxGraph(plotFUNCinputYofX,-4,5,-4,4,"rgb(66,44,255)",1);
    }

    function yOFxGraph (func,xFrom,xTo,yFrom,yTo,color,thick) {
        var canvas = document.getElementById("canvas");
        var ctx=canvas.getContext("2d");
        ctx.lineWidth = thick;
        ctx.strokeStyle = color;

        var Xunit = canvas.width/(xTo-xFrom);
        var Yunit = canvas.height/(yTo-yFrom);
        var samplingX=(xTo-xFrom)/400;/*I only sample 400 points whatever the scale is.*/
        var xx = xFrom;
        ctx.beginPath();
        ctx.moveTo(0 , canvas.height-(func(xx)-yFrom)*Yunit);

        function pivoting(){
            xx+=samplingX;
            ctx.lineTo((xx-xFrom)*Xunit , canvas.height-(func(xx)-yFrom)*Yunit);
        }
        if(xFrom<xTo){while(xx<xTo){pivoting()}}
        else if(xFrom>xTo){while(xx>xTo){pivoting()}}
        ctx.stroke();
    }
    </script>
    <canvas id="canvas" width="500" height="500"></canvas>
</body>
</html>

2 个答案:

答案 0 :(得分:2)

似乎你发现浏览器在绘制时处理无穷大(或可能是巨大的值)的方式有所不同。

首先,让我们注意,通过使用-5到5,您允许精确值x = 0,这会导致1/sin(0) Infinity(或者有一些浮点舍入错误,可能是非常积极或消极的价值)。

FireFox显然忽略了这一点。也许它忽略了这一点,但继续冲击线的其余部分,好像它不在那里,或者它可能将它留在线上(我认为NaNs的正确,直观行为)。

但是在Chrome和Safari中,这个无限或巨大的数字会导致整个笔画无效,因此它不会绘制任何笔画。

简单的解决方法是确保您的价值是理智的。这是一个检查,它将它限制在边界:(你可能想要使用更宽的边界,或处理不同的屏幕外)

var yy = func(xx);
if(!(yy>yFrom))yy=yFrom;
if(!(yy<yTo))yy=yTo;
ctx.lineTo((xx-xFrom)*Xunit , canvas.height-(yy-yFrom)*Yunit);

我已经确认这可以解决您在Chrome中遇到的问题。我认为它也适用于Safari。

答案 1 :(得分:0)

根据Dave的想法,我最终编辑了我的代码如下:

/*Safari7 & Chrome32 canvas bug*/
var Y=canvas.height-(func(xx)-yFrom)*Yunit;
if(0<=Y&&Y<=canvas.height){ctx.moveTo(0 , Y);}
else if(Y>canvas.height){Y=canvas.height+1;ctx.moveTo(0 , Y);}
else if(Y<0){Y=-1;ctx.moveTo(0 , Y);}
/*Safari7 & Chrome32 canvas bug*/
function pivoting(){
    xx+=samplingX;
    /*Safari7 & Chrome32 canvas bug*/
    Y=canvas.height-(func(xx)-yFrom)*Yunit;
    if(0<=Y&&Y<=canvas.height){ctx.lineTo((xx-xFrom)*Xunit , Y);}
    else if(Y>canvas.height){Y=canvas.height+1;ctx.lineTo((xx-xFrom)*Xunit , Y);}
    else if(Y<0){Y=-1;ctx.lineTo((xx-xFrom)*Xunit , Y);}
    /*Safari7 & Chrome32 canvas bug*/
}

现在一切正常!!

谢谢Dave。