Disable pinch zoom in webkit (or electron) - javascript

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:
event.preventDefault() on javascript touchmove/mousemove events
meta viewport tags in HTML
-webkit-text-size-adjust in CSS
flags/config for electron
Is there any method either for webkit in general, or electron in particular?

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();
}
});

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!

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);
});

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.

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 !

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

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 });

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.

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.

Related

Is there a way to force two finger scrolling on mobile browsers?

I am currently working on a project where the dragging operation draws onto a canvas and so scrolling is not feasible with a single finger. I would like to be able to scroll using two fingers instead.
Having experimented with various touch-action values I found that pinch-zoom gets me close but unfortunately it also zooms the page. I tried various hacks to prevent the zoom functionality but it caused numerous problems. I also experimented with custom scrolling using the gesture events but the scrolling performance was very poor when compared with native scrolling.
Is there an elegant way to force two finger scrolling without pinch to zoom?
To prevent zoom use this:
Add in head =>
<meta name='viewport'
content='width=device-width, initial-scale=1.0, maximum-scale=1.0,
user-scalable=0' >
Also add to your addEventListeners =>
On begin of func.
e.preventDefault()
Use this for multi touch detect =>
https://github.com/zlatnaspirala/multi-touch-canvas-handler/blob/master/index.html
This is multi touch handler.
You need somewhere in draw or update func ->
if (CONTROL.MULTI_TOUCH_X1 !== 'undefined' &&
CONTROL.MULTI_TOUCH_X2 !== 'undefined'){
// Do it now ...
}
// Maybe typeof is not needed
if (CONTROL.MULTI_TOUCH_X1 !== 'undefined' &&
typeof CONTROL.MULTI_TOUCH_X2 == 'undefined'){
// Do something to prevent scroll
// if you need it
}
If you don't want to use multi-touch library then find second touch with:
document.addEventListener("touchstart",
function (event) {
var touch = event.touches[0];
// CONTROL.X = touch.pageX;
// CONTROL.Y = touch.pageY;
var touches_changed = event.changedTouches;
for (var i = 0; i < touches_changed.length; i++) {
if (i == 1) {
...
}
}
}

Prevent zooming using a touchscreen in a website (IE 11, Win 10)

I have a website created using jQuery Mobile. And I want to disable the zoom functionality or prevent the user from being able to zoom in using pinch zoom or tapping with 2 fingers simultaneously.
I was looking for an answer but I just can't find an answer that works.
I tried using the meta tag:
<meta name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
Also tried:
body { -ms-content-zooming: none },
html { -ms-content-zooming: none },
.ui-page { -ms-content-zooming: none }
None of those solutions work.
Try user-scalable = no instead of user-scalable = 0.
So after more research i finally found a solution to my problem. Not the most handsome one but it works for me. I had to add an additional Key to the Internet Explorer Registry(HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Zoom) to prevent any Zoom.
A full guide can be found HERE

Using .scrollTop animation with mobile device not working

I have a footer that appears when a user scrolls down on the bottom of the page, but for seem reason it doesn't appear to be working on mobile devices, particularly the ipad, and it seems finicky on there. Sometimes it works sometimes it doesn't and only when using the ipad vertically.
<script type="text/javascript">
var $window = jQuery(window);
var $document = jQuery(document);
var footer = jQuery('.footer');
footer.css({opacity: 0});
$window.on('scroll', function() {
if (($window.scrollTop() + $window.innerHeight()) == $document.height()) {
footer.stop(true).animate({opacity: 1}, 250);
}
else {
footer.stop(true).animate({opacity: 0}, 250);
}
});
</script>
Just fades in and out on the bottom of the page condition. I looked around and there seems to be several ways to go about doing this and I was wanting to know the most effective solution.
I thought I had found a jfiddle for a solution a while ago but can't seem to find that question anymore and it required me to dig quite a bit.
I'm not exactly sure all of the factors that go into mobile not being compatible with this solution I currently have, so it's hard for me to determine what needs adjusting. Thanks.
Actually figured out the issue is that it needs to be the exact document height if I'm using '==', in mobile devices the viewpoint doesn't trigger the script while moving or scrolling so I had t change the '==' to '>=' in my condition and then add height to my viewport.
if (($window.scrollTop() + $window.innerHeight()) >= $document.height())
And in my header viewport tag
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0">
And it works perfectly!

Mobile Safari: why is window.scrollTo(0, 0) not scrolling to (0, 0)?

I've built a small single-page web app using Bootstrap 3, Sammy.js and Knockout 3. I'm finding that when the page is scrolled down, I'm unable to get window.scrollTo(0, 0) to work on Mobile Safari when I also change location.hash - specifically on iOS 7 on an iPhone 5C (likely happens on other iPhone models though).
When I try something like this:
self.changeState = function() {
self.state(State.NewState);
location.hash = 'somevalue';
window.scrollTo(0, 0);
};
The page will scroll almost all the way to the top - it will usually be scrolled to Y = 12 or 13. It will never scroll to 0 if I call window.scrollTo(0, 0); when the user is scrolled to the bottom of the page (and the content is sufficiently high to warrant a scroll to top).
I've tried various StackOverflow answers/suggestions (e.g. The same old issue, .scrollTop(0) not working in Chrome & Safari); the usual remedies (wrap in a setTimeout) do not change the behavior - it still scrolls to somewhere near the top of the page, but not quite to the top.
Header style:
<div class="navbar navbar-default navbar-inverse navbar-static-top">
Viewport settings:
<meta name="viewport"
content="width=device-width,
height=device-height,
initial-scale=1.0,
maximum-scale=1.0,
target-densityDpi=device-dpi" />
Scroll attempts:
self.changeState = function() {
self.state(State.NewState);
location.hash = 'somevalue';
window.scrollTo(0, 0);
};
and:
self.changeState = function() {
self.state(State.NewState);
location.hash = 'somevalue';
window.setTimeout(function() {
window.scrollTo(0, 0);
}, 0);
};
I've dug into this with the Safari Web Inspector, and nothing seems out of place as far as the structure of the page. I'm just not sure what to look for here - any ideas?
Edit:
So far, I have not been able to reproduce this outside of my app's code. I'm trying to get this to break in a JSFiddle - in this one, it works correctly (e.g., it scrolls to 0,0 as it should): http://jsfiddle.net/rringham/n9evU/24/show.
I managed to recreate this issue by using height: 100vh or min-height: 100vh on elements. I changed my CSS to use 100% instead (which is a bit of a pain) and the problem disappeared.
Try setting scrollTo(-n, 0); "n" being any number lower than 0
One trick to achieve this:
window.scrollTo(0, 0);
setTimeout(() => { window.scrollTo(0, 0); }, 100);
In my case, same issue, but it were coming from the fact I was in an iframe.
So doing window.top.scrollTo(0,0) made it!!!!

Force page zoom at 100% with JS

I created a little game in Canvas, but I have a problem. Some users who have the default zoom set to something other than 100% can't see the entire game page.
I have tried using this CSS:
zoom: 100%;
This HTML
<meta name="viewport" content="initial-scale=1.0 , minimum-scale=1.0 , maximum-scale=1.0" />
And this JS:
style="zoom: 75%"
Any ideas how to programatically set the page zoom?
You can set zoom property on page load
document.body.style.zoom = 1.0
But, zoom is not a standard property for all browsers, I recommend using transform instead.
var scale = 'scale(1)';
document.body.style.webkitTransform = scale; // Chrome, Opera, Safari
document.body.style.msTransform = scale; // IE 9
document.body.style.transform = scale; // General
http://jsfiddle.net/5RzJ8/
You can reset the code with this:
$("input, textarea").focusout(function(){
$('meta[name=viewport]').remove();
$('head').append('<meta name="viewport" content="width=device-width, maximum-scale=1.0, user-scalable=0">');
$('meta[name=viewport]').remove();
$('head').append('<meta name="viewport" content="width=device-width, initial-scale=yes">' );
});
I think, this is very helpful answer how to detect page zoom level in all modern browsers. Then the answer to your question for IE:
document.body.style.zoom = screen.logicalXDPI / screen.deviceXDPI;
It is working in chrome 66 :
document.body.style.zoom = (window.innerWidth / window.outerWidth)
The only way I found that works natively is in designing my HTML/CSS with the units "vw" and "vh" (% relative to the viewport) instead of "px". You can use it everywhere you used to put "px" (font-size, width, height, padding, margin, etc...). Very useful for a page designed to be display full screen only (no scroll) or "Kiosk-style". "vw" and "vh" are not affected by browser zoom.
See: https://www.w3schools.com/cssref/css_units.asp
For mobile browsers, #Linden's answer worked the best for me on Chrome. However on mobile FF it needed some additional tweaks, I came to version that works in both browsers:
let restore = $('meta[name=viewport]')[0];
if (restore) {
restore = restore.outerHTML;
}
$('meta[name=viewport]').remove();
$('head').append('<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">');
if (restore) {
setTimeout(() => {
$('meta[name=viewport]').remove();
$('head').append(restore);
}, 100); // On Firefox it needs a delay > 0 to work
}
Also, the restored page viewport tag must have explicit maximum-scale to allow zooming on Firefox after resetting, so I set it initially to this:
<meta name="viewport" content="width=device-width, maximum-scale=10">
Tested on mobile Chrome 76.0 and mobile Firefox 68.1.
I'd try both solutions but the following is seems to be a bug in echarts which leads to cursor deviated.
document.body.style.zoom = 1.25; // work but not to be expected.
I wonder if there any solution for the browser to directly modify the zoom ratio just like what ctrl++/- effect.

Categories