petabytekr / explorercanvas

Automatically exported from code.google.com/p/explorercanvas
Apache License 2.0
0 stars 0 forks source link

drawImage(img, x, y, w, h) is translated for NON-rotated transforms #56

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
The following lines are required to render a image correctly.

    var w = this.img.width  * s;
    var h = this.img.height * s;

>>  if(this.rotation==0.000)
>>    this.rotation = 0.001; // FIX for MSIE, positions it correctly

    ctx.translate(this.xCenter, this.yCenter);
    ctx.rotate(this.rotation / 180 * Math.PI);
    ctx.drawImage(this.img, -w/2, -h/2, w, h);

Without it, the image is shifted (~16px??) to the right.

Original issue reported on code.google.com by henk.jan...@gmail.com on 17 Nov 2009 at 2:58

GoogleCodeExporter commented 9 years ago
I forgot to add that I ran this code in MSIE8.

The following shows that the image is shifted off-center, and the cross is 
exactly 
at the right position (xCenter, yCenter)

    // render image around origin

    if(this.rotation==0.0)
      this.rotation = 0.001; // for MSIE

    ctx.translate(this.xCenter, this.yCenter);
    ctx.rotate(this.rotation / 180 * Math.PI);
    ctx.drawImage(this.img, -w/2, -h/2, w, h);

    // render cross, which should be centered

    ctx.strokeStyle = '#fff';
    ctx.lineWidth   = 1;

    ctx.beginPath();
    ctx.moveTo(-16,0);
    ctx.lineTo(+16,0);
    ctx.stroke();

    ctx.beginPath();
    ctx.moveTo(0,-16);
    ctx.lineTo(0,+16);
    ctx.stroke();

Original comment by henk.jan...@gmail.com on 17 Nov 2009 at 3:01

GoogleCodeExporter commented 9 years ago
A much simpler testcase: tested under both MSIE7 and MSIE8

Take an image of 400x600, render it like this:

   ctx.drawImage(img, 0, 0);
   ctx.drawImage(img, 400, 0); // displayed at 436px

You'll see a gap of ~36px between the two images, if you prepend
   ctx.rotate(0.0001);
the gap disappears, but you pay a serious performance penalty.

Original comment by henk.jan...@gmail.com on 19 Nov 2009 at 10:59

GoogleCodeExporter commented 9 years ago
I have also encountered this problem.

A Scale will also fix the translation issue, but also with the performance 
penalty
from using filters to render the images:

ctx.scale(0.00001,0.00001);

I set about finding out where the difference comes from, and discovered that 
close to
the origin the offset was small, and increased as the x,y of the image 
increased.
Using trial and error I found the relationship between the true x,y and the
translated x,y of the image to be 0.91. So if you multiply the image's x and y
coordinates by 0.91 then the translation is correct.

For all images you can modify line 567 in drawImage:
vmlStr.push('top:', mr(d.y*0.91 / Z), 'px;left:', mr(d.x*0.91 / Z), 'px;');

I have tried to look for where this 0.91 comes from, but no avail.

Original comment by tins.jer...@gmail.com on 24 Nov 2009 at 4:22

GoogleCodeExporter commented 9 years ago
I got this problem also. Workaround from comment 3 almost works, but my project
reqires precise tiling of "sprites", and sometimes there is 1 pixel overlap,
sometimes 1 pixel gap.

Original comment by bni....@gmail.com on 6 Mar 2010 at 2:42

GoogleCodeExporter commented 9 years ago
I see a 1-pixel gap or over-sized image by one pixel too.

but work-around don't work. they place the image at 0,0 instead of where it 
should

first I use
ctx.drawImage(frame, 0, 0);
and then paste a sclice of it on top it (to refresh only part of it)
ctx.drawImage(frame, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
// look at slicing 
https://developer.mozilla.org/en/Canvas_tutorial/Using_images#Slicing

and then I see a 1-pixel move to the right but also the sliced image is blurred 
so I think it is oversized

an example that behave like that 
<!DOCTYPE html>

<html>
    <head>
        <meta chartset="utf-8">
        <!--[if lt IE 9]><script src="excanvas.js"></script><![endif]-->
        <script type="text/javascript">
            function draw() {
                canvas = document.getElementById('mycanvas');
                    if (canvas.getContext){
                                        ctx = canvas.getContext('2d');
                    frame = new Image();
                    frame.onload = function(){
                        ctx.drawImage(frame, 0, 0);
                        mywidth = 33;
                        ctx.drawImage(frame, 24, 0, mywidth, 140, 24, 0, mywidth, 140);
                    }
                    frame.src = "frame.png";
                }
            }
        window.onload = draw;
        </script>
    </head>
    <body>
        <canvas id="mycanvas" width="720" height="140"></canvas>
    </body>
</html>

you have to make a frame.png. Mine was 720x140

BUT the bug happens for mywidth < 34 ! not for mywidth= 34, = 35 ... 
WTF !

Original comment by solstice.dhiver@gmail.com on 28 Jun 2010 at 5:59

GoogleCodeExporter commented 9 years ago
a screenshot of what the above html look in IE8 (inside virtualbox)

look carefully at the left of image. the first column is slightly blurred

Original comment by solstice.dhiver@gmail.com on 28 Jun 2010 at 6:05

Attachments: