最简单的方法来检测捏
这是一个WEB应用程序,而不是本机应用程序。 请不要Objective-C NS命令。
所以我需要检测iOS上的“捏”事件。 问题是我看到做手势或多点触摸事件的每一个插件或方法,通常是使用jQuery,并且是每一个阳光下的手势的一个额外的插件。 我的应用程序是巨大的,我对代码中的死木非常敏感。 我需要的只是检测一个捏,使用像jGesture的东西只是臃肿的方式,我的简单需求。
此外,我对如何手动检测夹点了解有限。 我可以得到两个手指的位置,似乎无法得到混合权利检测到这一点。 有没有人有一个简单的片段,只是检测捏?
您想要使用gesturechange
, gestureend
和gestureend
事件 。 这些触发任何时候有两个或更多的手指触摸屏幕。
根据你需要做的捏手势,你的方法将需要调整。 可以检查scale
乘数以确定用户的捏手势是多么戏剧化。 有关如何使用scale
属性的详细信息,请参阅Apple的TouchEvent文档 。
node.addEventListener('gestureend', function(e) { if (e.scale < 1.0) { // User moved fingers closer together } else if (e.scale > 1.0) { // User moved fingers further apart } }, false);
你也可以拦截这个gesturechange
事件来检测一个捏,如果你需要它来让你的应用程序感觉更响应的话。
想一想什么是pinch
事件:一个元素上的两个手指,彼此相向或相向移动。 就我所知,手势事件是一个相当新的标准,所以可能最安全的方法就是使用这样的触摸事件:
(ontouchstart事件)
if(e.touches.length == 2) { scaling = true; pinchStart(e); }
(ontouchmove事件)
if(scaling) { pinchMove(e); }
(ontouchend事件)
if(scaling) { pinchEnd(e); scaling = false; }
为了得到两个手指之间的距离,使用毕达哥拉斯定理:
var dist = Math.sqrt( (e.touches[0].xe.touches[1].x) * (e.touches[0].xe.touches[1].x) + (e.touches[0].ye.touches[1].y) * (e.touches[0].ye.touches[1].y));
Hammer.js一路! 它处理“变换”(捏)。 http://eightmedia.github.com/hammer.js/
但是如果你想自己实现,我认为杰弗里的回答是相当稳固的。
不幸的是,在浏览器中检测捏手势并不像人们希望的那么简单,但是HammerJS使它变得容易很多!
用HammerJS演示检查缩放和平移 。 这个例子已经在Android,iOS和Windows Phone上testing过了。
您可以在Pinch Zoom和HammerJS的Pan下find源代码。
为了您的方便,这里是源代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"> <title>Pinch Zoom</title> </head> <body> <div> <div style="height:150px;background-color:#eeeeee"> Ignore this area. Space is needed to test on the iPhone simulator as pinch simulation on the iPhone simulator requires the target to be near the middle of the screen and we only respect touch events in the image area. This space is not needed in production. </div> <style> .pinch-zoom-container { overflow: hidden; height: 300px; } .pinch-zoom-image { width: 100%; } </style> <script src="https://hammerjs.github.io/dist/hammer.js"></script> <script> var MIN_SCALE = 1; // 1=scaling when first loaded var MAX_SCALE = 64; // HammerJS fires "pinch" and "pan" events that are cumulative in nature and not // deltas. Therefore, we need to store the "last" values of scale, x and y so that we can // adjust the UI accordingly. It isn't until the "pinchend" and "panend" events are received // that we can set the "last" values. // Our "raw" coordinates are not scaled. This allows us to only have to modify our stored // coordinates when the UI is updated. It also simplifies our calculations as these // coordinates are without respect to the current scale. var imgWidth = null; var imgHeight = null; var viewportWidth = null; var viewportHeight = null; var scale = null; var lastScale = null; var container = null; var img = null; var x = 0; var lastX = 0; var y = 0; var lastY = 0; var pinchCenter = null; // We need to disable the following event handlers so that the browser doesn't try to // automatically handle our image drag gestures. var disableImgEventHandlers = function () { var events = ['onclick', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'ondblclick', 'onfocus', 'onblur']; events.forEach(function (event) { img[event] = function () { return false; }; }); }; // Traverse the DOM to calculate the absolute position of an element var absolutePosition = function (el) { var x = 0, y = 0; while (el !== null) { x += el.offsetLeft; y += el.offsetTop; el = el.offsetParent; } return { x: x, y: y }; }; var restrictScale = function (scale) { if (scale < MIN_SCALE) { scale = MIN_SCALE; } else if (scale > MAX_SCALE) { scale = MAX_SCALE; } return scale; }; var restrictRawPos = function (pos, viewportDim, imgDim) { if (pos < viewportDim/scale - imgDim) { // too far left/up? pos = viewportDim/scale - imgDim; } else if (pos > 0) { // too far right/down? pos = 0; } return pos; }; var updateLastPos = function (deltaX, deltaY) { lastX = x; lastY = y; }; var translate = function (deltaX, deltaY) { // We restrict to the min of the viewport width/height or current width/height as the // current width/height may be smaller than the viewport width/height var newX = restrictRawPos(lastX + deltaX/scale, Math.min(viewportWidth, curWidth), imgWidth); x = newX; img.style.marginLeft = Math.ceil(newX*scale) + 'px'; var newY = restrictRawPos(lastY + deltaY/scale, Math.min(viewportHeight, curHeight), imgHeight); y = newY; img.style.marginTop = Math.ceil(newY*scale) + 'px'; }; var zoom = function (scaleBy) { scale = restrictScale(lastScale*scaleBy); curWidth = imgWidth*scale; curHeight = imgHeight*scale; img.style.width = Math.ceil(curWidth) + 'px'; img.style.height = Math.ceil(curHeight) + 'px'; // Adjust margins to make sure that we aren't out of bounds translate(0, 0); }; var rawCenter = function (e) { var pos = absolutePosition(container); // We need to account for the scroll position var scrollLeft = window.pageXOffset ? window.pageXOffset : document.body.scrollLeft; var scrollTop = window.pageYOffset ? window.pageYOffset : document.body.scrollTop; var zoomX = -x + (e.center.x - pos.x + scrollLeft)/scale; var zoomY = -y + (e.center.y - pos.y + scrollTop)/scale; return { x: zoomX, y: zoomY }; }; var updateLastScale = function () { lastScale = scale; }; var zoomAround = function (scaleBy, rawZoomX, rawZoomY, doNotUpdateLast) { // Zoom zoom(scaleBy); // New raw center of viewport var rawCenterX = -x + Math.min(viewportWidth, curWidth)/2/scale; var rawCenterY = -y + Math.min(viewportHeight, curHeight)/2/scale; // Delta var deltaX = (rawCenterX - rawZoomX)*scale; var deltaY = (rawCenterY - rawZoomY)*scale; // Translate back to zoom center translate(deltaX, deltaY); if (!doNotUpdateLast) { updateLastScale(); updateLastPos(); } }; var zoomCenter = function (scaleBy) { // Center of viewport var zoomX = -x + Math.min(viewportWidth, curWidth)/2/scale; var zoomY = -y + Math.min(viewportHeight, curHeight)/2/scale; zoomAround(scaleBy, zoomX, zoomY); }; var zoomIn = function () { zoomCenter(2); }; var zoomOut = function () { zoomCenter(1/2); }; var onLoad = function () { img = document.getElementById('pinch-zoom-image-id'); container = img.parentElement; disableImgEventHandlers(); imgWidth = img.width; imgHeight = img.height; viewportWidth = img.offsetWidth; scale = viewportWidth/imgWidth; lastScale = scale; viewportHeight = img.parentElement.offsetHeight; curWidth = imgWidth*scale; curHeight = imgHeight*scale; var hammer = new Hammer(container, { domEvents: true }); hammer.get('pinch').set({ enable: true }); hammer.on('pan', function (e) { translate(e.deltaX, e.deltaY); }); hammer.on('panend', function (e) { updateLastPos(); }); hammer.on('pinch', function (e) { // We only calculate the pinch center on the first pinch event as we want the center to // stay consistent during the entire pinch if (pinchCenter === null) { pinchCenter = rawCenter(e); var offsetX = pinchCenter.x*scale - (-x*scale + Math.min(viewportWidth, curWidth)/2); var offsetY = pinchCenter.y*scale - (-y*scale + Math.min(viewportHeight, curHeight)/2); pinchCenterOffset = { x: offsetX, y: offsetY }; } // When the user pinch zooms, she/he expects the pinch center to remain in the same // relative location of the screen. To achieve this, the raw zoom center is calculated by // first storing the pinch center and the scaled offset to the current center of the // image. The new scale is then used to calculate the zoom center. This has the effect of // actually translating the zoom center on each pinch zoom event. var newScale = restrictScale(scale*e.scale); var zoomX = pinchCenter.x*newScale - pinchCenterOffset.x; var zoomY = pinchCenter.y*newScale - pinchCenterOffset.y; var zoomCenter = { x: zoomX/newScale, y: zoomY/newScale }; zoomAround(e.scale, zoomCenter.x, zoomCenter.y, true); }); hammer.on('pinchend', function (e) { updateLastScale(); updateLastPos(); pinchCenter = null; }); hammer.on('doubletap', function (e) { var c = rawCenter(e); zoomAround(2, cx, cy); }); }; </script> <button onclick="zoomIn()">Zoom In</button> <button onclick="zoomOut()">Zoom Out</button> <div class="pinch-zoom-container"> <img id="pinch-zoom-image-id" class="pinch-zoom-image" onload="onLoad()" src="https://hammerjs.github.io/assets/img/pano-1.jpg"> </div> </div> </body> </html>
这些答案都没有达到我所期望的,所以我自己写了一些东西。 我想用我的MacBook Pro触控板在我的网站上捏图像。 下面的代码(需要jQuery)似乎至less在Chrome和Edge中有效。 也许这对别人是有用的。
function setupImageEnlargement(el) { // "el" represents the image element, such as the results of document.getElementByd('image-id') var img = $(el); $(window, 'html', 'body').bind('scroll touchmove mousewheel', function(e) { //TODO: need to limit this to when the mouse is over the image in question //TODO: behavior not the same in Safari and FF, but seems to work in Edge and Chrome if (typeof e.originalEvent != 'undefined' && e.originalEvent != null && e.originalEvent.wheelDelta != 'undefined' && e.originalEvent.wheelDelta != null) { e.preventDefault(); e.stopPropagation(); console.log(e); if (e.originalEvent.wheelDelta > 0) { // zooming var newW = 1.1 * parseFloat(img.width()); var newH = 1.1 * parseFloat(img.height()); if (newW < el.naturalWidth && newH < el.naturalHeight) { // Go ahead and zoom the image //console.log('zooming the image'); img.css( { "width": newW + 'px', "height": newH + 'px', "max-width": newW + 'px', "max-height": newH + 'px' }); } else { // Make image as big as it gets //console.log('making it as big as it gets'); img.css( { "width": el.naturalWidth + 'px', "height": el.naturalHeight + 'px', "max-width": el.naturalWidth + 'px', "max-height": el.naturalHeight + 'px' }); } } else if (e.originalEvent.wheelDelta < 0) { // shrinking var newW = 0.9 * parseFloat(img.width()); var newH = 0.9 * parseFloat(img.height()); //TODO: I had added these data-attributes to the image onload. // They represent the original width and height of the image on the screen. // If your image is normally 100% width, you may need to change these values on resize. var origW = parseFloat(img.attr('data-startwidth')); var origH = parseFloat(img.attr('data-startheight')); if (newW > origW && newH > origH) { // Go ahead and shrink the image //console.log('shrinking the image'); img.css( { "width": newW + 'px', "height": newH + 'px', "max-width": newW + 'px', "max-height": newH + 'px' }); } else { // Make image as small as it gets //console.log('making it as small as it gets'); // This restores the image to its original size. You may want //to do this differently, like by removing the css instead of defining it. img.css( { "width": origW + 'px', "height": origH + 'px', "max-width": origW + 'px', "max-height": origH + 'px' }); } } } }); }
为了以防万一,我一直在为这种情况下完整的MVP,这里是开源的: