Calder White
Calder White

Reputation: 1326

Html5-canvas Bug

So I'm testing my skills with the <canvas> tag, and I decided to make a graphing function on a simple and css scarce webpage. Here's my code.

<html>
    <head>
        <script>
function graph(equation){
    var c = document.getElementById("myCanvas");
    var ctx = c.getContext("2d");
    ctx.clearRect(0-c.width/2, 0-c.height/2, c.width, c.height);
    ctx.translate(c.width/2,c.height/2);
    ctx.strokeStyle = "red";
    ctx.moveTo(0-c.width/2,0);
    ctx.beginPath();
    for(i=0-c.width/2;i<=c.width;i++){
        ctx.lineTo(i,eval(equation.replace(/x/g,i.toString()))*-1);
    };
    ctx.stroke()
    ctx.closePath();
}
        </script>
    </head>
    <body>
        <canvas id="myCanvas" width="700" height="550" style="border:1px solid #d3d3d3;">
            Your browser does not support the HTML5 canvas tag.
        </canvas>
        <textarea id="graphi" height="16px" width="200"></textarea>
        <button onclick="graph(document.getElementById('graphi').value);">graph</button>
    </body>
</html>

My problem is whenever I graph it twice it changes the position of (0,0), and I can't change it back unless I entirely reset the page. So my question really is what problem is going on with my function and how do I fix it? Thanks in advance.

Upvotes: 0

Views: 77

Answers (2)

Alnitak
Alnitak

Reputation: 339776

You should .save the context's state before you translate it. This will also have the advantage of simplifying your clearRect call:

ctx.clearRect(0, 0, c.width, c.height);  // simplified
ctx.save();                              // save the current state
ctx.translate(c.width/2,c.height/2);
ctx.strokeStyle = "red";
ctx.moveTo(0-c.width/2,0);
ctx.beginPath();
for(i=0-c.width/2;i<=c.width;i++){
    ctx.lineTo(i,eval(equation.replace(/x/g,i.toString()))*-1);
};
ctx.stroke();
ctx.closePath();
ctx.restore();                           // to back to the original (untranslated) state

Upvotes: 0

fdreger
fdreger

Reputation: 12495

getContext does not create a new context, it returns the same one every time. After getting the context you translate it, and it just stays translated.

To fix, either translate the context only once or translate it back after using, at the end of your function.

By the way, a simple way not to change the context geometry (translating, rotating, scaling) is to use context#save at the beginning of your function and context#restore at the end. The bonus here is that context maintains a stack of states, so if you call a function inside your function, it can safely use the save / restore pair as well.

Upvotes: 1

Related Questions