Open
Bug 1203873
Opened 9 years ago
Updated 2 years ago
Precision loss in CSS transforms due to use of 32-bit floats
Categories
(Core :: Layout, defect)
Tracking
()
UNCONFIRMED
People
(Reporter: ivan, Unassigned)
Details
Attachments
(1 file)
1.27 KB,
text/html
|
Details |
User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/38.1.0
Build ID: 20150711212448
Steps to reproduce:
Hi, LeafletJS dev here. We've been having a problem with our library (https://github.com/Leaflet/Leaflet/issues/3608) that we've tracked down to Firefox's management of pixel lengths inside CSS transforms.
Apparently Firefox is rounding big numbers inside CSS transforms. This is best explained with the following bit of Javascript:
<script>
var foo = document.createElement('div');
foo.style.transform = "translate3d(-11374952px, 21881153px, 0)";
console.log(foo.style.transform);
// Expected: "translate3d(-11374952px, 21881153px, 0)";
// Actual: "translate3d(-1.1375e+7px, 2.18812e+7px, 0px)"
</script>
Other browsers (e.g. Chrome) behave as expected, without losing precision. Scientific notation seems to trigger exactly at 10^7px.
This is similar to #470769, but applies to CSS lenghts inside transforms instead.
See also https://jsfiddle.net/dg6r5hhb/ - two opposite transforms should always negate each other perfectly.
![]() |
||
Comment 3•9 years ago
|
||
The transform is stored internally (and more importantly, represented by the graphics library) as a floating point number. A 32-bit float has only 7 digits of decimal precision, yes... The issue is not the scientific notation; that's just a serialization artefact.
Simple testcase showing the rounding during rendering, since again the graphics library works with 32-bit floats:
<!DOCTYPE html>
<style>
div { width: 100px; height: 100px; }
body { padding: 0; margin: 0; }
</style>
<div style="position: absolute; top: 11374952px; background: red"></div>
<div style="transform: translate(0, 11374952px); background: green"></div>
(note the thin stripe of red at the bottom).
Or is your library actually examining the serialized values and acting on those so you're losing more precision than that testcase shows?
Flags: needinfo?(ivan)
Summary: Precision loss in CSS transforms due to automatic scientific notation → Precision loss in CSS transforms due to use of 32-bit floats
(In reply to Boris Zbarsky [:bz] from comment #3)
> Or is your library actually examining the serialized values and acting on
> those so you're losing more precision than that testcase shows?
You can see our original issue here:
https://github.com/Leaflet/Leaflet/issues/3608
We use CSS transforms to pan the map around (move to another point on the earth without changing zoom level). If the pan is too big, the map turns into a grey <div>. Right now we've patched around the issue by resetting the state if a transform is bigger than 10^7px.
Flags: needinfo?(ivan)
![]() |
||
Comment 5•9 years ago
|
||
I still can't tell from that whether the issue is reading back the transform values and working with those numbers or whether the issue is just the transform being set (but not read) and then rendering incorrectly...
(In reply to Boris Zbarsky [:bz] from comment #5)
> I still can't tell from that whether the issue is reading back the transform
> values and working with those numbers or whether the issue is just the
> transform being set (but not read) and then rendering incorrectly...
The problem is incorrect rendering. Reading back different values is just a symptom.
Updated•2 years ago
|
Severity: normal → S3
You need to log in
before you can comment on or make changes to this bug.
Description
•