15

Im doing a very slow transition of a background image (a view of space that slides slowly to the left). My problem is while it looks beautiful on Firefox, it looks horrible on Chrome. I get a "jittery" effect due to Chrome's lack of subpixel rendering, and the image just snaps to the next pixel. I cannot speed the image up because it will destroy the effect Im trying to achieve. I have tried using TranslateZ() tricks, I have tried every CSS3 effect I could think of to make it look better, Ive tried Kinetic.js, Ive even tried Babylon.js hoping that WebGL would fix my problem.

At this point Im at a loss and I might just have to give Chrome users a static background and cater more to the Firefox users in regards to the neat little things I can do for the UI UX, and then just put a disclaimer on my site saying that the page is best viewed in FF.

I REALLY dont want to do this. Is there ANY work around at all?

JSArrakis
  • 777
  • 1
  • 9
  • 22
  • Please provide a working demo or a jsfiddle – Vangel Tzo Feb 28 '14 at 14:21
  • http://jsfiddle.net/yrwA9/ The funny thing is too, when I use Chrome Portable here at my workplace, the browser is rendering subpixel just fine, however at home on my gaming computer with the most updated version of chrome, it does not render subpixel. – JSArrakis Feb 28 '14 at 14:31
  • It's seems to be fine @JSArrakis .. maybe it's a graphic card issue. – Vangel Tzo Feb 28 '14 at 14:33
  • 2
    It looks jittery on my version of firefox. (A CSS transistion might have better results) – Matthew Wilcoxson Feb 28 '14 at 14:39
  • What about a X2 or X4 larger canvas that you fit to size with ccs width/height ? – GameAlchemist Feb 28 '14 at 14:42
  • 1
    You could use WebGL on canvas to *force* antialiasing, although support and consistency across browsers/hardware will be a bit iffy. – monners May 29 '14 at 03:31
  • @monners I had considered this, and it still might be an option. For right now though I was able to figure this out with CSS3 Transitions. I was able to change the scale of the div to subpixel and with a little playing around I was able to find the right combinations: -webkit-transform: scale(0.996, 0.996) translate3d(-100%, 0%, 1px); – JSArrakis May 30 '14 at 13:41
  • @JSArrakis Does this mean you have your answer? If so, please write this as an answer and mark it correct. If not, what's up? :) – Reed Spool Jun 02 '14 at 01:53
  • To me it looks great in Chrome. The only jitter effect appears at the image's border. There it "jumps" by pixels. Within the image it is looking subpixel transformed. – Möhre Jun 02 '14 at 09:44
  • Looks jittery to me with FF on my Mac and looks great with Chrome on the same Mac. I don't think it's a browser issue as I am getting the opposite result as you are. – KnightHawk Jun 02 '14 at 16:44
  • @ReedSpool Its not quite a correct answer as there is still a small "wave" in the image motion when you look closely at it. Id say my 'solution' is more patchwork than anything and not an actual solution. – JSArrakis Jun 03 '14 at 12:58

1 Answers1

23

You can force subpixel rendering by applying a small transformation:

#container {
    transform: rotate(-0.0000000001deg);
    -webkit-transform: rotate(-0.0000000001deg);
}

But instead of using JS to make the animation work, why not use CSS3 animations? If you use transform: translate() browsers will use subpixel-rendering by default.

Also since the performance is better you shouldn't get your jittery/wave motion.

More info on performance here: http://www.paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft/

I've put together a simple demo here: http://jsfiddle.net/yrwA9/6/ (For the sake of simplicity I only used the -webkit- vendor prefixes)

hichris123
  • 10,145
  • 15
  • 56
  • 70
Victor
  • 749
  • 5
  • 7
  • 1
    Interesting to note: this does subpixel anti-aliasing in the 3D context, not in the 2D context (i.e. not in the 2D rasterization of the element before it is transformed in 3D space). There seems to be a separate aliasing algorithm that happens first, when the element is drawn, then that texture is sent to the 3D context where anti-aliasing of that texture happens. See http://stackoverflow.com/questions/39963699 for examples. The only way to introduce subpixel aliasing (not subpixel anti-aliasing) is by zooming in (try zooming in on the examples and then you'll see a size difference). – trusktr Oct 11 '16 at 00:54