style img attribute javascript jquery ios mobile-safari

javascript - attribute - img html title



La forma más simple de detectar una pizca (6)

Esta es una APLICACIÓN WEB no una aplicación nativa. Por favor, no hay comandos de Objective-NS NS.

Entonces necesito detectar eventos ''pellizcos'' en iOS. El problema es que cada complemento o método que veo para hacer gestos o eventos multitáctiles, es (generalmente) con jQuery y es un complemento adicional para cada gesto bajo el sol. Mi aplicación es enorme, y soy muy sensible a la madera muerta en mi código. Todo lo que necesito es detectar un pellizco, y usar algo como jGesture es solo una forma de hincharse para mis necesidades simples.

Además, tengo una comprensión limitada de cómo detectar un pellizco manualmente. Puedo obtener la posición de ambos dedos, parece que no puedo mezclar bien para detectar esto. ¿Alguien tiene un fragmento simple que SOLO detecta pellizco?


Desafortunadamente, detectar gestos de pellizco en los navegadores no es tan simple como uno esperaría, ¡pero HammerJS lo hace mucho más fácil!

Mira la demo de Pinch Zoom y Pan con HammerJS . Este ejemplo ha sido probado en Android, iOS y Windows Phone.

Puede encontrar el código fuente en Pinch Zoom y Pan con HammerJS .

Para su comodidad, aquí está el código fuente:

<!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, c.x, c.y); }); }; </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>


Hammer.js todo el camino! Maneja "transformaciones" (pellizcos). http://eightmedia.github.com/hammer.js/

Pero si desea implementarlo usted mismo, creo que la respuesta de Jeffrey es bastante sólida.


Ninguna de estas respuestas logró lo que estaba buscando, así que terminé escribiendo algo yo mismo. Quería pellizcar y hacer zoom en una imagen en mi sitio web usando mi trackpad MacBookPro. El siguiente código (que requiere jQuery) parece funcionar en Chrome y Edge, al menos. Tal vez esto sea útil para otra persona.

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


Piensa en qué es un evento de pinch : dos dedos en un elemento, acercándose o alejándose el uno del otro. Los eventos de gestos son, a mi conocimiento, un estándar bastante nuevo, por lo que probablemente la forma más segura de hacerlo es usar eventos táctiles de la siguiente manera:

(evento ontouchstart )

if (e.touches.length === 2) { scaling = true; pinchStart(e); }

(evento ontouchmove )

if (scaling) { pinchMove(e); }

(evento ontouchend )

if (scaling) { pinchEnd(e); scaling = false; }

Para obtener la distancia entre los dos dedos, usa la función hypot :

var dist = Math.hypot( e.touches[0].pageX - e.touches[1].pageX, e.touches[0].pageY - e.touches[1].pageY);



Desea utilizar los eventos gesturestart , gesturechange y gestureend . Estos se disparan cada vez que dos o más dedos tocan la pantalla.

Dependiendo de lo que necesite hacer con el gesto de pellizco, su enfoque deberá ajustarse. El multiplicador de scale puede examinarse para determinar qué tan dramático fue el gesto de pellizco del usuario. Consulte la documentación TouchEvent de Apple para obtener detalles sobre cómo se comportará la propiedad de la scale .

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

También puede interceptar el evento de gesturechange para detectar un pellizco, como ocurre si lo necesita para hacer que su aplicación se sienta más receptiva.