views:

149

answers:

2

In a simple canvas test I created for performance and quality measurement purposes, a canvas is painted with randomised colors and images during an unlimited period.

A sample is shown here: http://litterific.com/minisite/

Warning: Only open this in Opera or Chrome, the script is pretty heavy can hang up on slow computers, don't leave the script running while you are getting coffee ;)) It is just a rough prototype and did not optimize it.

What I noticed here is that the results as painted by the script (js/asset.js) are different in various browsers. Especially in Opera there is much more "green" in the painting than in Chrome

alt text

code is found here: http://litterific.com/minisite/js/asset.js

My question is:

How this is caused. Different random seeds? Different rounding or different color behavior in Opera?

Note: It is exactly the same script in both browsers, so perhaps you could have a look at it in both Chrome and Opera.

+1  A: 

As you guessed, Math.random starts with a different seed in each case. There is unfortunately no way to provide a fixed seed to the Math.random function. If you really need that, you will have to find one or implement it yourself.

I have noticed that different canvas implementations do vary slightly when drawing partially opaque objects, but that is a minor issue compared to your differing random sequences!

Btw, your script does produce nice looking output :)

andrewmu
I've tested with plain numbers... still producing the output different, also in a loop.
Caspar Kleijne
Thanks for testing anyway ;)
Caspar Kleijne
+4  A: 

It's not random numbers causing the problems, it's "funny" pixel data. Here's the change:

for (i = 0, n = pixels.data.length; i < n; i += 4){
  pixels.data[i + 0] = Math.max(0, Math.min(255, Math.floor(r * f)));
  pixels.data[i + 1] = Math.max(0, Math.min(255, Math.floor(g * f)));
  pixels.data[i + 2] = 0;
  pixels.data[i + 3] = pixels.data[i + 3]; 
}

If you ensure that the pixel values are integers in the right range, Opera works fine.

Oh also, and this is probably obvious, it goes a lot faster if you hoist those multiplications out of the loop.

Pointy
I suspected something like this. that means that all values above 255 in pixels.data[0] are put in pixels.data[1] (and multiplied by 255) ? so { pixels.data[0] = 300 } would be the same as { pixels.data[0] = 255, pixels.data[1] = 45 } ? That makes sense since Javascript does not know numeric types between 0 and 255 but only "integers". (in opera's case that makes the array pretty useless, since in opera only the first pixeldata needs to be filled, bit like colors in C# or PHP.) but is somewhat "fixed" in Chrome. I also dumped this question at Opera, perhaps it's some sort of unfinished issue.
Caspar Kleijne
I'm not sure what happens; you may be correct that the value "spills" into other color cells, but it's hard to say exactly. (I suppose you could figure it out by experimentation.)
Pointy
yeah, you're right, going to look after that. thanks for your efforts anyway, much appreciated. Tested it a bit and, you confirmed my suspicion. Bounty will apply in 17 hours from now ;)
Caspar Kleijne