ARTICLE AD BOX
I have a page with a couple of SVG elements employing svg-pan-zoom, as well as text and images in the same page.
I have successfully used hammer.js to implement a pinch-zoom on the SVG elements.
On a touch screen (e.g. smart phone) I would like to be able to scroll down the page with a two-finger swipe, but as soon as this gets to an SVG element then it pans the content.
Is it possible to get a two-finger gesture to scroll the page while keeping one-finger gestures for panning an SVG element?
I have tried disabling some of the hammer.js operations using: set({enable: false})
naively expecting the page-level event handling to take over, but it does not change anything. I currently have only 'pan' and 'pinch' enabled. The following example is modified from http://bumbu.me/svg-pan-zoom/demo/mobile.html
<!DOCTYPE html> <html> <head> <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"> <script src="https://parallaxviewpoint.com/SVGcode/svg-pan-zoom.js"></script> <script src="http://bumbu.me/svg-pan-zoom/demo/hammer.js"></script> </head> <!-- Modified from http://bumbu.me/svg-pan-zoom/demo/mobile.html --> <body> <p> Of on affixed civilly moments promise explain fertile in. Assurance advantage belonging happiness departure so of. Now improving and one sincerity intention allowance commanded not. Oh an am frankness be necessary earnestly advantage estimable extensive. Five he wife gone ye. Mrs suffering sportsmen earnestly any. In am do giving to afford parish settle easily garret. </p><p> Up unpacked friendly ecstatic so possible humoured do. Ample end might folly quiet one set spoke her. We no am former valley assure. Four need spot ye said we find mile. Are commanded him convinced dashwoods did estimable forfeited. Shy celebrated met sentiments she reasonably but. Proposal its disposed eat advanced marriage sociable. Drawings led greatest add subjects endeavor gay remember. Principles one yet assistance you met impossible. </p><p> Spoke as as other again ye. Hard on to roof he drew. So sell side ye in mr evil. Longer waited mr of nature seemed. Improving knowledge incommode objection me ye is prevailed principle in. Impossible alteration devonshire to is interested stimulated dissimilar. To matter esteem polite do if. </p><p> It if sometimes furnished unwilling as additions so. Blessing resolved peculiar fat graceful ham. Sussex on at really ladies in as elinor. Sir sex opinions age properly extended. Advice branch vanity or do thirty living. Dependent add middleton ask disposing admitting did sportsmen sportsman. </p> <div id="mobile-div" style="width: 602px; height: 420px; border:1px solid black; "> <svg id="mobile-svg" xmlns="http://www.w3.org/2000/svg" style="display: inline; width: inherit; min-width: inherit; max-width: inherit; height: inherit; min-height: inherit; max-height: inherit;" version="1.1"> <defs> <linearGradient id="linear-gradient" x1="0%" y1="0%" x2="0%" y2="100%"> <stop offset="0%" style="stop-color:rgb(56,121,217);stop-opacity:1" /> <stop offset="100%" style="stop-color:rgb(138,192,7);stop-opacity:1" /> </linearGradient> </defs> <g fill="none"> <g stroke="#000" fill="#FFF"> <rect x="5" y="5" width="240" height="240" fill="url(#linear-gradient)"/> <path d="M 5 5 L 245 245 Z"/> </g> </g> </svg> </div> <p> Of on affixed civilly moments promise explain fertile in. Assurance advantage belonging happiness departure so of. Now improving and one sincerity intention allowance commanded not. Oh an am frankness be necessary earnestly advantage estimable extensive. Five he wife gone ye. Mrs suffering sportsmen earnestly any. In am do giving to afford parish settle easily garret. </p><p> Up unpacked friendly ecstatic so possible humoured do. Ample end might folly quiet one set spoke her. We no am former valley assure. Four need spot ye said we find mile. Are commanded him convinced dashwoods did estimable forfeited. Shy celebrated met sentiments she reasonably but. Proposal its disposed eat advanced marriage sociable. Drawings led greatest add subjects endeavor gay remember. Principles one yet assistance you met impossible. </p><p> Spoke as as other again ye. Hard on to roof he drew. So sell side ye in mr evil. Longer waited mr of nature seemed. Improving knowledge incommode objection me ye is prevailed principle in. Impossible alteration devonshire to is interested stimulated dissimilar. To matter esteem polite do if. </p><p> It if sometimes furnished unwilling as additions so. Blessing resolved peculiar fat graceful ham. Sussex on at really ladies in as elinor. Sir sex opinions age properly extended. Advice branch vanity or do thirty living. Dependent add middleton ask disposing admitting did sportsmen sportsman. </p> <script> // Don't use window.onLoad like this in production, because it can only listen to one function. window.onload = function() { var eventsHandler = { haltEventListeners: ['touchstart', 'touchend', 'touchmove', 'touchleave', 'touchcancel'], init: function(options) { var instance = options.instance, initialScale = 1, pannedX = 0, pannedY = 0; // Initialse Hammer // Listen only for pointer and touch events this.hammer = Hammer(options.svgElement, { inputClass: Hammer.SUPPORT_POINTER_EVENTS ? Hammer.PointerEventInput : Hammer.TouchInput }); this.hammer.get('doubletap').set({enable: false}); this.hammer.get('tap').set({enable: false}); this.hammer.get('press').set({enable: false}); this.hammer.get('swipe').set({enable: false}); this.hammer.get('pan').set({enable: true}); // Enable pinch (disabled by default) this.hammer.get('pinch').set({enable: true}); // Handle pan events this.hammer.on('panstart panmove', function(ev) { // On pan start reset panned variables if (ev.type === 'panstart') { pannedX = 0; pannedY = 0; } // Pan only the difference instance.panBy({x: ev.deltaX - pannedX, y: ev.deltaY - pannedY}); pannedX = ev.deltaX; pannedY = ev.deltaY; }) // Handle pinch events this.hammer.on('pinchstart pinchmove', function(ev) { // On pinch start remember initial zoom if (ev.type === 'pinchstart') initialScale = instance.getZoom(); const rect = options.svgElement.getBoundingClientRect(); const pos = { x: (ev.center.x - rect.left), y: (ev.center.y - rect.top) }; instance.zoomAtPoint(initialScale * ev.scale, {x: pos.x, y: pos.y}); }) // Prevent moving the page on some devices when panning over SVG options.svgElement.addEventListener('touchmove', function(e){ e.preventDefault(); }); }, destroy: function() { this.hammer.destroy(); } } // Expose to window namespace for testing purposes window.panZoom = svgPanZoom('#mobile-svg', { zoomEnabled: true, panEnabled: true, controlIconsEnabled: true, dblClickZoomEnabled: false, controlIconsEnabled: true, // preventMouseEventsDefault: false, fit: true, center: true, minZoom: 0.5, maxZoom: 10, customEventsHandler: eventsHandler }); }; </script> </body> </html>