37

Is there any way to disable pinch zoom in an electron app?

I can't get it to work from inside the web-view with normal javascript methods as described here: https://stackoverflow.com/a/23510108/665261

It seems the --disable-pinch flag is not supported by electron.

I have experimented with various methods using:

  1. event.preventDefault() on javascript touchmove/mousemove events
  2. meta viewport tags in HTML
  3. -webkit-text-size-adjust in CSS
  4. flags/config for electron

Is there any method either for webkit in general, or electron in particular?

Community
  • 1
  • 1
Billy Moon
  • 57,113
  • 24
  • 136
  • 237

9 Answers9

30

UPDATE 2:

Use webFrame.setZoomLevelLimits (v0.31.1+) in render process (Differences Between Main Process and Renderer Process). Because smart zoom on mac still work with document.addEventListener.

Example require('electron').webFrame.setZoomLevelLimits(1, 1)


UPDATE:

deltaY property for pinch zoom has float value, but normal scroll event return int value. Now solution has no problem with ctrl key.

Demo 2.

document.addEventListener('mousewheel', function(e) {
  if(e.deltaY % 1 !== 0) {
    e.preventDefault();
  }
});

Using Chromium monitorEvents(document) I found that is responsible for this event mousewheel. I don't know, why mousewheel triggered with pinch zoom. Next step, find difference between normal scroll and pinch zoom.

Pinch zoom has an attribute e.ctrlKey = true, and normal scroll event has e.ctrlKey = false. But if you hold down ctrl key and scroll a page, e.ctrlKey equal true.

I couldn't find a better solution. :(

Demo

document.addEventListener('mousewheel', function(e) {
  if(e.ctrlKey) {
    e.preventDefault();
  }
});
artanik
  • 2,599
  • 15
  • 24
  • 3
    Combining this with a keydown/keyup event to check if ctrlKey is set by the actual key using a global flag could possibly solve the differentiation problem. –  May 01 '15 at 20:34
3

It seems very difficult for desktop browser to prevent pinch zoom.

Here are some ideas though!

1) By using some gestures javascript like hammer.js, detect Pinch event and try to prevent it using e.preventDefault

OR

2) Design everything using "%" in css, or use newer units like "vm" etc, (if possible). This way, even page will be zoomed, but content will stay the same for any zoom level.

All the best!

Billy Moon
  • 57,113
  • 24
  • 136
  • 237
Sandeep
  • 107
  • 1
  • 9
  • thanks for the suggestions. I tried both solutions. Hammer, awesome as it is, does not seem to help with this. It seems to add recognisers as a level on top of events, I think I need something that helps to access more low level functionality. The second one seemed to have no effect when I put font size as percent rule on body, html, paragraph etc... – Billy Moon May 06 '15 at 17:44
2

Answer from GitHub:

"If you are looking for a way how to prevent zoom from main process, you can use:"

const webContents = mainWindow.webContents;
webContents.on('did-finish-load', () => {
  webContents.setZoomFactor(1);
  webContents.setVisualZoomLevelLimits(1, 1);
  webContents.setLayoutZoomLevelLimits(0, 0);
});

mainWindow is variable where you have new BrowserWindow, e.g.:

const mainWindow = new BrowserWindow({
  width: 440,
  height: 750,
  // ...
});

const webContents = mainWindow.webContents;
webContents.on("did-finish-load", () => {
  webContents.setZoomFactor(1);
  webContents.setVisualZoomLevelLimits(1, 1);
  webContents.setLayoutZoomLevelLimits(0, 0);
});
michal
  • 1,534
  • 5
  • 28
  • 62
1

Is there a reason why you can't use:

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>

Put that in the header and it keeps devices from zooming.

Billy Moon
  • 57,113
  • 24
  • 136
  • 237
cawney
  • 37
  • 4
  • Oh. That is my trick when I want to disable zooming on mobile. Never had to worry about disabling zooming when I'm on a desktop. – cawney May 05 '15 at 14:46
1

I searched so long and hard for a simple solution to this problem with no avail...but later I discovered a plugin called fullpage.js that was able to prevent pinch zoom while still allowing touch gestures. Through the process of js/css elimination, I discovered a very simple solution:

touch-action: none;

Adding this to my full page element successfully prevented pinch zoom but allowed me to scale fabricjs objects with pinching. Hooray !

J. Barca
  • 538
  • 6
  • 19
1
var app = require('electron')
app.commandLine.appendSwitch('disable-pinch');

Solution found by mixing these two links:

1 - https://github.com/electron/electron/issues/8793#issuecomment-289791853

2 - https://github.com/electron/electron/blob/master/docs/api/chrome-command-line-switches.md

Carlos Oliveira
  • 846
  • 10
  • 23
1

I had to set { passive: false } to make it work. Don't ask me why.

window.addEventListener('wheel', (e) => {
  if(e.ctrlKey) e.preventDefault();
}, { passive: false });
Motla
  • 1,092
  • 12
  • 19
0

meta tag should have worked. Try using the minimum-scale=1.0

<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, user-scalable=no">

And if it also not works then add both the minimum and maximum scale

<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">

P.S. : It will disable zooming on mobile phones only.

Kapil Garg
  • 462
  • 1
  • 5
  • 17
0

I got the easiest fix for this, in the index.html or similar file for your project, within the script tag, include electron and configure zoom level as below,

<script>
const electron = require('electron'); // Include electron
electron.webFrame.setZoomLevelLimits(1, 1); // Set min max zoom level as 1
const { ipcRenderer } = electron;
...
</script>

This works perfectly fine across devices. The viewport meta tag approach doesn't work well on desktop, only fixes issue on mobile devices.

Krishna Modi
  • 377
  • 2
  • 12