title: Using nearest-neighbor with CSS zoom on canvas (and img)
body: <p>When using the CSS <code>zoom</code> property, how can I convince the browser to use "nearest neighbor", instead of "bilinear" or any other more advanced zooming algorithms?</p>
  
  <p>My setup is a div that contains a canvas, and the div gets its zoom set via JavaScript to be <code>&lt;div style="zoom:3200%"&gt;...&lt;/div&gt;</code> and to get nearest neighbor, I am using <code>image-rendering: -webkit-optimize-contrast</code> in my CSS. The app is available <a href="http://www.lovetopixel.com">here</a> ('z' zooms in, 'shift-z' zooms back out), and my css is <a href="http://www.lovetopixel.com/ltp.css">here</a></p>
  
  <p>Here is the desired effect in Chrome on OSX (zoom is set to 3200%):
  <img src="https://i.stack.imgur.com/JMpbI.png" alt="zoom on OSX/Chrome using nearest neighbor"></p>
  
  <p>But here is the same thing in Chrome on Windows 7:
  <img src="https://i.stack.imgur.com/NdY5w.png" alt="zoom on Windows/Chrome not using nearest neighbor"></p>
  
  <p>In both cases it is "vanilla" Chrome (version 15.x.x) out of the box, no experimental flags are turned on.</p>
  
  <p><strong>How can I convince Chrome on Windows to use nearest neighbor? For that matter, how can I convince all browsers?</strong> Safari also does not use nearest neighbor (so far the app only works in WebKit based browsers)</p>
  
  <p>The CSS <code>image-rendering</code> property does affect Chrome/OSX and gives me the desired effect. But Chrome/Windows and Safari(5.1)/OSX both seem to completely ignore it. Something tells me I'm just out of luck, but I figured I'd ask.</p>
  
  <p>Using <code>zoom</code> on the div container is so simple and works beautifully in Chrome/OSX, if I must resort to scaling my canvases internally, I can do that too. But would prefer the literally one line of code solution if possible!</p>
  
  <p><strong>UPDATE:</strong> I have found the use of <code>image-rendering: optimizeSpeed</code> helps. However it seems finicky in Chrome/Windows. If I set it on too many elements (I initially tried, my containers and all canvases), it doesn't take effect. But if I apply it to just <code>canvas</code>, I get 98% of the way there.</p>
  
  <p>Now my problem is the first time I draw while zoomed in, it works perfectly, all other subsequent drawing actions are fuzzy while they are taking place, then revert to the correct nearest-neighbor afterwards (my app draws into a scratch canvas first, then applies the drawing to the real canvas). There is something odd about the scratch canvas where Chrome insists on using bilinear. I think with some digging I can resolve that.</p>
  
  <p><strong>UPDATE2:</strong> It seems like <code>image-rendering</code> on Chrome/Windows just isn't implemented well and is a bit buggy. I can now confirm that the values <code>optimizeSpeed</code> and <code>optimizeQuality</code> are not supported on Chrome/Windows. If you set image-rendering to them, Chrome will ignore the set. Chrome/Windows does recognize <code>-webkit-optimize-contrast</code>, however it does not use it consistently. Chrome will flip between what looks to be a bilinear scaling algorithm and nearest-neighbor almost at random. I've not been able to consistently get Chrome to use nearest-neighbor.</p>
  
  <p>I tried a build of Chromium 17 on Windows and it behaves the same way.</p>
  
  <p>Firefox (8.0.1) is looking pretty promising though as it does seem to honor <code>-moz-crisp-edges</code> quite well. Originally I was targeting Chrome as my "ideal browser" for this app, I might just switch over to Firefox.</p>
  
  <p>In the end, it seems like proper support for <code>image-rendering</code> is in the pipeline for Chrome, just not quite there yet. WebKit itself claims to fully support all image-rendering values, but I'm guessing the build of WebKit that Chrome uses hasn't quite updated to this new fix.</p>