Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 4 of 4
  1. #1
    Regular Coder
    Join Date
    Sep 2007
    Location
    AZ, USA
    Posts
    685
    Thanks
    6
    Thanked 46 Times in 46 Posts

    IE "Object Expected" Error

    I'm developing a UI using the <canvas> element and google's IE hack. Here comes the familiar line: The code works beautiful in FF but doesn't work in IE. I'm 90% sure that its not a problem with the canvas or google's hack. The error is "Object Expected" and the line number always is the line with my <body> tag. Here are the codes, but what I really need is some info on the error. What causes it? How to fix it? I could debug the code but I don't really have a ton of info.

    Code:
    <html>
     <head>
    <!--[if IE]><script type="text/javascript" src="excanvas.js"></script><![endif]-->
    <script type="application/x-javascript">
    function getInterval(start, end, num)
    {
    var difference;
    var interval;
    difference=end-start;
    interval=difference/(num-1);
    return interval;
    }
    
    function gradient(r1,g1,b1,r2,g2,b2,px)
    {
    var colors=new Array();
    rInt=getInterval(r1,r2,px);
    gInt=getInterval(g1,g2,px);
    bInt=getInterval(b1,b2,px);
    rC=r1;
    gC=g1;
    bC=b1;
    for(i=0;i<px;i++)
    {
    colors[i]=new Array(rC,gC,bC);
    rC+=Math.round(rInt);
    gC+=Math.round(gInt);
    bC+=Math.round(bInt);
    }
    colors[colors.length-1][0]=r2;colors[colors.length-1][1]=g2;colors[colors.length-1][2]=b2;
    return colors;
    }
    
    function left(gr1,gg1,gb1,gr2,gg2,gb2,gl,go1,go2,sr,sg,sb,so1,so2,sl,innerw,outerw,innero,outero,h,innerr,innerg,innerb,outerr,outerg,outerb)
    {
     var canvas = document.createElement("canvas");
     canvas.id="left";
     canvas.width=innerw+outerw+gl+sl;
     canvas.height=h;
    document.body.appendChild(canvas);
     var ctx = canvas.getContext("2d");
    
    grInt=getInterval(gr1,gr2,gl);
    ggInt=getInterval(gg1,gg2,gl);
    gbInt=getInterval(gb1,gb2,gl);
    goInt=getInterval(go1,go2,gl);
    soInt=getInterval(so1,so2,sl);
    grC=gr1;
    ggC=gg1;
    gbC=gb1;
    goC=go1;
    soC=so1;
    
    ctx.fillStyle = "rgba("+innerr+","+innerg+","+innerb+","+innero+")";
    ctx.fillRect (canvas.width-innerw, 0, innerw, canvas.height);
    
    for(i=1;i<=gl;i++)
    {
    ctx.fillStyle = "rgba("+grC+","+ggC+","+gbC+","+goC+")";
    ctx.fillRect (canvas.width-(i+innerw), 0, 1, canvas.height);
    grC+=Math.round(grInt);
    ggC+=Math.round(ggInt);
    gbC+=Math.round(gbInt);
    goC+=goInt;
    }
    
    ctx.fillStyle = "rgba("+outerr+","+outerg+","+outerb+","+outero+")";
    ctx.fillRect (canvas.width-(innerw+gl+outerw), 0, outerw, canvas.height);
    
    for(i=1;i<=sl;i++)
    {
    ctx.fillStyle = "rgba("+sr+","+sg+","+sb+","+Math.round(soC*100)/100+")";
    ctx.fillRect (canvas.width-(innerw+gl+outerw+i), 0, 1, canvas.height);
    soC+=soInt;
    }
    
    }
      </script>
     </head>
    <body onload="left(202,206,212,233,236,239,15,0.75,0.75,0,0,0,0.75,0,12,2,2,0.75,0.75,300,132,135,138,172,175,180);">
     </body>
    </html>
    Yes, the HTML doesn't validate, but I haven't gotten to that step in the design process.

    I googled the forum and the internet, I came up with that it could be caused by referencing an item in the document before it exists. Is there a problem in IE with using createElement+appendchild?
    Last edited by binaryWeapon; 06-20-2008 at 04:09 AM.

  • #2
    Regular Coder
    Join Date
    Jun 2007
    Location
    USA
    Posts
    527
    Thanks
    26
    Thanked 74 Times in 72 Posts
    I kind of got it to work. The colors in IE are not crisp like when loaded in firefox.

    The canvas code I used is here http://me.eae.net/projects/iecanvas/

    Code:
    <html>
    <head>
    <script type="text/javascript" src="iecanvas.js"></script>
    <script type="text/javascript">
    
    function Color(r, g, b, a) {
      if(arguments[0] instanceof Color) {
        this.r = arguments[0].r;
        this.g = arguments[0].g;
        this.b = arguments[0].b;
        this.a = arguments[0].a;
      }
      else {
        this.r = r;
        this.g = g;
        this.b = b;
        this.a = a !== undefined
          ? a
          : 1
      }
    }
    Color.prototype = {
      toString: function() {
        return [this.r, this.g, this.b, this.a].join(',');
      }
    };
    
    function getInterval(start, end, num) {
      var difference;
      var interval;
      difference = end - start;
      interval = difference / (num - 1);
      return interval;
    }
    
    function gradient(c1, c2, px) {
      var colors = [];
      var cInt = new Color(
          Math.round( getInterval(c1.r, c2.r, px) )
        , Math.round( getInterval(c1.g, c2.g, px) )
        , Math.round( getInterval(c1.b, c2.b, px) )
      )
      var currC = new Color(c1);
      for(var i = 0; i < px; i++) {
        colors[i] = new Color(currC);
        currC.r += cInt.r;
        currC.g += cInt.g;
        currC.b += cInt.b;
      }
      currC = colors[colors.length - 1];
      currC.r = r2;
      currC.g = grad2;
      currC.b = b2;
      return colors;
    }
    
    function left(
          grad1
        , grad2 
        , shadow
        , inner
        , outer
        , gradLen, shadowLen,  shadowAlphaEnd, innerW, outerW, height
      ) {
      var canvas = document.createElement("canvas");
      canvas.width = innerW + outerW + gradLen + shadowLen;
      canvas.height = height;
      canvas.id = "left";
      document.body.appendChild(canvas);
      ieCanvasInit("iecanvas.htc");
      setTimeout(function() {
        canvas = document.getElementById("left");
        canvas.width = innerW + outerW + gradLen + shadowLen;
        canvas.height = height;
        var ctx = canvas.getContext("2d");
        var gradInt = new Color(
            Math.round( getInterval(grad1.r, grad2.r, gradLen) )
          , Math.round( getInterval(grad1.g, grad2.g, gradLen) )
          , Math.round( getInterval(grad1.b, grad2.b, gradLen) )
          , getInterval(grad1.a, grad2.a, gradLen)
        );
        var gradC = new Color(grad1);
        for(var i = 1; i <= gradLen; i++) {
          ctx.fillStyle = "rgba(" + gradC + ")";
          ctx.fillRect(
              canvas.width - (i + innerW)
            , 0
            , 1
            , canvas.height
          );
          gradC.r += gradInt.r;
          gradC.g += gradInt.g;
          gradC.b += gradInt.b;
          gradC.a += gradInt.a;
        }
    
        shadow = new Color(shadow);
        var shadowAlphaInt = getInterval(shadow.a, shadowAlphaEnd, shadowLen);
        for(var i = 1; i <= shadowLen; i++) {
          ctx.fillStyle = "rgba(" + shadow +")";
          ctx.fillRect(
            canvas.width - (innerW + gradLen + outerW + i)
            , 0
            , 1
            , canvas.height
          );
          shadow.a += shadowAlphaInt;
        }
    
        ctx.fillStyle = "rgba(" + inner + ")";
        ctx.fillRect(
            canvas.width - innerW
          , 0
          , innerW
          , canvas.height
        );
    
        ctx.fillStyle = "rgba(" + outer + ")";
        ctx.fillRect(
            canvas.width - (innerW + gradLen + outerW)
          , 0
          , outerW
          , canvas.height
        );
      }, 1);
    }
    
    window.onload = function() {
      left(
          new Color(202, 206, 212, .75)
        , new Color(233, 236, 239, .75)
        , new Color(0, 0, 0, 0.75)
        , new Color(132, 135, 138, 0.75)
        , new Color(172, 175, 180, 0.75)
        , 15, 12, 0, 2, 2, 300
      );
    }
    </script>
    </head>
    <body>
    </body>
    </html>
    Last edited by Trinithis; 06-20-2008 at 06:14 AM.
    Trinithis

  • Users who have thanked Trinithis for this post:

    binaryWeapon (06-20-2008)

  • #3
    Regular Coder
    Join Date
    Sep 2007
    Location
    AZ, USA
    Posts
    685
    Thanks
    6
    Thanked 46 Times in 46 Posts
    I tried your canvas library, didn't work for me. I also checked out the canvas demo on the iecanvas site. Didn't work in either case. Also in both cases, I could highlight a shape that was the exact shape that the canvas should be. Nothing was rendered on the canvas however. Also, the object expected error was gone, but now I was getting an error with the ctx.getContext("2d") line. I did some research and found this comment on a blog post:
    Has anyone tried using this with dynamically created canvases? I am creating a canvas using document.createElement on demand, which works in Safari and Firefox, but in IE the canvas doesn’t work … it seems canvas.context is defined and something like canvas.context.fillStyle has the correct inital value, but neither the canvas nor the context have methods so canvas.getContext() doesn’t work (for instance). After doing document.createElement(’canvas’), the behaviour is not applied for some non-trivial amount of time so called getContext is invalid until the behaviour has been applied. Not sure if the thread of execution blocks this until control is returned to the browser or not. In any case, by redesigning so my canvas is created early on, and the context is retrieved at some later time, it works.
    After that I found another blog post, which said this:

    Normally, the canvas elements are initialized when the page is loaded but if you want to create canvas elements on the fly (or use them before the page has loaded) the following code should work:
    Code:
    var c = document.createElement("canvas");
    document.body.appendChild(c);
    // we need to init this for IE
    if (typeof G_vmlCanvasManager != "undefined") {
      G_vmlCanvasManager.initElement(c);
    }
    There is one more quirk. The canvas elements are recreated when initialized so do not store a reference to them before they are actually used.
    I implemented this along with the excanvas.js file from their site, and everything worked beautifully.

    Thank you so much for redesigning my codes (and putting up with my terrible naming conventions ), I wouldn't have been able to get this far without that. Everything worked exactly right, except for one bug I had run into previously in which the opacity value had too many decimal places, which was stopping the borders from being rendered. I just added a line to round it to 5 decimal places, which should be far more than enough.

    Here were my final codes:
    Code:
    <html>
    <head>
    <!--[if IE]><script type="text/javascript" src="excanvas.js"></script><![endif]-->
    <script type="text/javascript">
    
    function Color(r, g, b, a) {
      if(arguments[0] instanceof Color) {
        this.r = arguments[0].r;
        this.g = arguments[0].g;
        this.b = arguments[0].b;
        this.a = arguments[0].a;
      }
      else {
        this.r = r;
        this.g = g;
        this.b = b;
        this.a = a !== undefined
          ? a
          : 1
      }
    }
    Color.prototype = {
      toString: function() {
        return [this.r, this.g, this.b, this.a].join(',');
      }
    };
    
    function getInterval(start, end, num) {
      var difference;
      var interval;
      difference = end - start;
      interval = difference / (num - 1);
      return interval;
    }
    
    function gradient(c1, c2, px) {
      var colors = [];
      var cInt = new Color(
          Math.round( getInterval(c1.r, c2.r, px) )
        , Math.round( getInterval(c1.g, c2.g, px) )
        , Math.round( getInterval(c1.b, c2.b, px) )
      )
      var currC = new Color(c1);
      for(var i = 0; i < px; i++) {
        colors[i] = new Color(currC);
        currC.r += cInt.r;
        currC.g += cInt.g;
        currC.b += cInt.b;
      }
      currC = colors[colors.length - 1];
      currC.r = r2;
      currC.g = grad2;
      currC.b = b2;
      return colors;
    }
    
    function left(
          grad1
        , grad2 
        , shadow
        , inner
        , outer
        , gradLen, shadowLen,  shadowAlphaEnd, innerW, outerW, height
      ) {
      var canvas = document.createElement("canvas");
      document.body.appendChild(canvas);
      canvas.width = innerW + outerW + gradLen + shadowLen;
      canvas.height = height;
      canvas.id = "left";
    if (typeof G_vmlCanvasManager != "undefined") {
      G_vmlCanvasManager.initElement(canvas);
    }
      if(navigator.appname=="Microsoft Internet Explorer"){ieCanvasInit("iecanvas.htc");}
      setTimeout(function() {
        canvas = document.getElementById("left");
        canvas.width = innerW + outerW + gradLen + shadowLen;
        canvas.height = height;
        var ctx = canvas.getContext("2d");
        var gradInt = new Color(
            Math.round( getInterval(grad1.r, grad2.r, gradLen) )
          , Math.round( getInterval(grad1.g, grad2.g, gradLen) )
          , Math.round( getInterval(grad1.b, grad2.b, gradLen) )
          , getInterval(grad1.a, grad2.a, gradLen)
        );
        var gradC = new Color(grad1);
        for(var i = 1; i <= gradLen; i++) {
          ctx.fillStyle = "rgba(" + gradC + ")";
          ctx.fillRect(
              canvas.width - (i + innerW)
            , 0
            , 1
            , canvas.height
          );
          gradC.r += gradInt.r;
          gradC.g += gradInt.g;
          gradC.b += gradInt.b;
          gradC.a += gradInt.a;
        }
        shadow = new Color(shadow);
        var shadowAlphaInt = getInterval(shadow.a, shadowAlphaEnd, shadowLen);
        for(var i = 1; i <= shadowLen; i++) {
          ctx.fillStyle = "rgba("+ shadow +")";
          ctx.fillRect(
            canvas.width - (innerW + gradLen + outerW + i)
            , 0
            , 1
            , canvas.height
          );
          shadow.a += shadowAlphaInt;shadow.a = Math.round(shadow.a*100000)/100000;
        }
    
        ctx.fillStyle = "rgba(" + inner + ")";
        ctx.fillRect(
            canvas.width - innerW
          , 0
          , innerW
          , canvas.height
        );
    
        ctx.fillStyle = "rgba(" + outer + ")";
        ctx.fillRect(
            canvas.width - (innerW + gradLen + outerW)
          , 0
          , outerW
          , canvas.height
        );
      }, 1);
    }
    
    window.onload = function() {
      left(
          new Color(202, 206, 212, .75)
        , new Color(233, 236, 239, .75)
        , new Color(0, 0, 0, 0.75)
        , new Color(132, 135, 138, 0.75)
        , new Color(172, 175, 180, 0.75)
        , 15, 12, 0, 2, 2, 300
      );
    }
    </script>
    </head>
    <body>
    </body>
    </html>
    Tested in IE7, Opera 9.5, FF2.0.14, NS9, and Safari 3.1.2, all works like a charm.

    Thanks again!

    ~bW
    Last edited by binaryWeapon; 06-20-2008 at 07:02 PM.

  • #4
    Regular Coder
    Join Date
    Jun 2007
    Location
    USA
    Posts
    527
    Thanks
    26
    Thanked 74 Times in 72 Posts
    I bet you can take out the setTimeout I placed the code in. I kinda suspected the
    behaviour is not applied for some non-trivial amount of time
    so that's why I put in the timeout. Perhaps with the
    Code:
    if (typeof G_vmlCanvasManager != "undefined") {
      G_vmlCanvasManager.initElement(c);
    }
    you won't need it anymore.
    Trinithis


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •