haxiomic / firefox-multi-touch-zoom

Smoothly zoom in and out with the multi-touch pinch gesture
MIT License
154 stars 16 forks source link

Smooth Multi-Touch Zoom Extension for Firefox

Add to Firefox

Update 2020: This feature is arriving natively in firefox! It's expected to be enabled by default in Firefox 83, so this extension will no longer required :)

This extension adds support for smooth zooming with the pinch gesture on a trackpad or touch screen. It's been designed to match the behavior of Chrome and Safari.

Non-multi-touch users can still smooth zoom by scrolling and holding down the Shift key

Zoom can be reset by pressing + 0 on macOS or Ctrl + 0 on Windows

Requires Firefox 55 or greater

Motivation

Firefox is still missing smooth multi-touch zoom support, an issue has been sitting in Bugzilla for the last 6 7 8 9 years gathering comments

Given we live in a time with MacBook trackpads as big as a tablet, I've become so used to the pinch-to-zoom feature while browsing in Safari and Chrome that its absence was a deal breaker for me when trying to switch to the new Firefox Quantum. I put this together to try and bring the feature to Firefox

It turned out to be tricker to implement than I thought! There are a number of little hacks required to get it to work and to achieve a smooth user experience. I've explained the implementation below and hopefully this could help someone else trying to achieve high-performance scalling with CSS

Implementation Details and Hacks

No 'real' multi-touch trackpad gesture events in Firefox for Desktop

In-spite of having PointerEvents, TouchEvents and even a 'MozMagnifyGesture' event, none of these will fire when the user performs multi-touch gestures on a desktop trackpad. However, there's a trick to capturing a pinch action: Since Firefox 55.0 the pinch gesture maps to the 'wheel' event with the ctrlKey flag artificially set to true. It's an ugly hack, but it lets us distinguish between mouse-wheel + ctrl and pinch by keeping track of the real ctrlKey state and comparing (this is only true on macOS).

We'd really want to capture pinch-start and pinch-end events to enable the best user experience but unfortunately I'm not aware of any technique to enable this.

Just setting scaleX() and scaleY() isn't enough for acceptable performance

The page can be magnified by setting a CSS scale transform on the root element, this works for magnification but experience is anything but smooth - even with the new WebRender enabled the experience is essentially the same: janky. To work around the performance problems I found a few tricks:

Quirks mode breaks scroll positions

When a site doesn't specify a modern docType, Firefox falls back into 'quirks mode' rendering. In this mode Firefox enables a long list of historic bugs. Foruntately we can detect quirks mode rendering and work around this.

Known Issues

Please report any webpages that have issues and I'll see if it's possible to fix them!

Other Notes

Meta tags

Pages may have meta tags to configure the behavior of 'magnifying-glass' zoom on tablets. These tags let a page disable zoom and set the mininum and maximum zoom. So far, all desktop browser seem to ignore these, citing that a page shouldn't have a say on whether or not the user is allowed to zoom. I've decided to match the behavior of other browser and ignore them too but I'd love to hear from users if this should change