Maison > interface Web > Tutoriel H5 > le corps du texte

Principe et mise en œuvre de la détection des gestes HTML5

黄舟
Libérer: 2017-03-04 16:17:46
original
3005 Les gens l'ont consulté

Avant-propos

Avec l'enrichissement des applications hybrides, les ingénieurs HTML5 ne se contentent plus de simplement porter l'expérience bureau sur mobile. Ils convoitent l'expérience d'exploitation humanisée des applications natives mobiles. notamment le système de gestes riche inhérent aux applications natives. HTML5 ne fournit pas de système de gestes prêt à l'emploi, mais il fournit une surveillance de niveau inférieur des événements tactiles. Sur cette base, nous pouvons créer notre propre bibliothèque de gestes.

Gestes

Les gestes HTML5 couramment utilisés peuvent être divisés en deux catégories, les gestes à un seul point et les gestes à deux points. Les gestes en un seul point incluent appuyer, appuyer deux fois, appuyer longuement, glisser et déplacer. Les gestes à deux points incluent le pincement (zoom) et la rotation (rotation).

Ensuite, nous implémentons une bibliothèque javaScript qui détecte ces gestes et utilisons cette bibliothèque de gestes pour créer des effets interactifs sympas.

Principe et mise en œuvre de la détection des gestes HTML5

Mobile

Nous n'entrerons pas ici dans les détails de la détection des gestes mobiles. Pour résumer, chaque fois qu'un événement touchmove se produit, soustrayez simplement les positions des coordonnées entre les deux points de déplacement.

Cliquez (appuyez)

La clé de la détection des gestes est d'utiliser les trois événements touchstart, touchmove et touchend pour décomposer les gestes.

Alors comment décomposer l'événement clic ?

  1. Entrez dans la détection des clics lorsque le démarrage tactile se produit avec un seul point de contact. Parce que l'événement de clic est limité à l'action d'un seul doigt.

  2. L'événement touchmove ne se produit pas ou le touchmove est dans une petite plage (comme indiqué ci-dessous). Limiter le déplacement tactile à une petite plage vise à donner à l'utilisateur une certaine redondance, car il n'y a aucune garantie que le doigt de l'utilisateur ne bougera pas légèrement lorsqu'il touche l'écran.

Principe et mise en œuvre de la détection des gestes HTML5

3.touchend se produit peu de temps après le démarrage du toucher (comme indiqué ci-dessous). Le seuil pour cette période de temps est au niveau de la milliseconde, qui est utilisé pour limiter la durée pendant laquelle le doigt est en contact avec l'écran. Parce que l'événement click est très rapide du début à la fin.
Principe et mise en œuvre de la détection des gestes HTML5

Avec le processus ci-dessus, vous pouvez commencer à mettre en œuvre la surveillance des événements tactiles.

_getTime() {

  return new Date().getTime(); 

}

_onTouchStart(e) {

    //记录touch开始的位置

    this.startX = e.touches[0].pageX;

    this.startY = e.touches[0].pageY;

    if(e.touches.length > 1) {

      //多点监测

      ...

    }else {

      //记录touch开始的时间

      this.startTime = this._getTime();

    }

 }

_onTouchMove(e) {

  ...

  //记录手指移动的位置

  this.moveX = e.touches[0].pageX;

  this.moveY = e.touches[0].pageY;

  ...

}

_onTouchEnd(e) {

  let timestamp = this._getTime();

  if(this.moveX !== null && Math.abs(this.moveX - this.startX) > 10 ||

    this.moveY !== null && Math.abs(this.moveY - this.startY) > 10) {

      ...

  }else {

    //手指移动的位移要小于10像素并且手指和屏幕的接触时间要短语500毫秒

    if(timestamp - this.startTime < 500) {

      this._emitEvent(&#39;onTap&#39;)

    }

  }

}
Copier après la connexion

Double tap

Comme un simple clic, l'événement de double tap nous oblige également à décomposer quantitativement les gestes.

  1. L'événement de double-clic est le comportement d'un doigt. Ainsi, lors du démarrage tactile, nous devons déterminer combien de points de contact il y a sur l'écran à ce moment-là.

  2. Un événement de double-clic contient deux comportements de clic indépendants. Idéalement, les deux clics devraient atterrir au même point de l'écran. Afin de donner à l'utilisateur un certain espace redondant, la distance entre les points de coordonnées de deux clics est limitée à 10 pixels maximum.
    Principe et mise en œuvre de la détection des gestes HTML5

  3. Un événement de double-clic est essentiellement constitué de deux clics rapides. Autrement dit, le temps entre deux clics est très court. Après avoir réussi certains tests de quantification, nous fixons l'intervalle de temps entre deux clics à 300 millisecondes.
    Principe et mise en œuvre de la détection des gestes HTML5

Notez que dans l'événement de double-clic, nous détectons le déplacement et l'intervalle de temps entre deux événements touchstart adjacents.

_onTouchStart(e) {

  if(e.touches.length > 1) {

  ...

  } else {

    if(this.previousTouchPoint) {

      //两次相邻的touchstart之间距离要小于10,同时时间间隔小于300ms

      if( Math.abs(this.startX -this.previousTouchPoint.startX) < 10  &&

          Math.abs(this.startY - this.previousTouchPoint.startY) < 10 && 

          Math.abs(this.startTime - this.previousTouchTime) < 300) {

            this._emitEvent(&#39;onDoubleTap&#39;);

          }

    }

    //保存上一次touchstart的时间和位置信息

    this.previousTouchTime = this.startTime;

    this.previousTouchPoint = {

        startX : this.startX,

        startY : this.startY

     };

  }

}
Copier après la connexion

Appui long

Un appui long devrait être le geste le plus simple à décomposer. Nous pouvons le décomposer comme ceci : pendant une longue période après le début du toucher, si aucun événement touchmove ou touchend ne se produit, alors le geste d'appui long est déclenché.

  1. Un appui long est une action du doigt et doit détecter s'il n'y a qu'un seul point de contact sur l'écran.

  2. Si le doigt bouge dans l'espace, l'événement d'appui long est annulé.

  3. Si le doigt reste sur l'écran pendant plus de 800ms, le geste d'appui long se déclenche.

  4. Si le doigt reste sur l'écran pendant moins de 800 ms, c'est-à-dire que le toucher est déclenché dans les 800 ms après le démarrage du toucher, alors l'événement d'appui long est annulé.
    Principe et mise en œuvre de la détection des gestes HTML5

_onTouchStart(e) {

  clearTimeout(this.longPressTimeout);

  if(e.touches.length > 1) {

  }else {

    this.longPressTimeout = setTimeout(()=>{

      this._emitEvent(&#39;onLongPress&#39;);

    });

  }

}

_onTouchMove(e) {

  ...

  clearTimeout(this.longPressTimeout);

  ...

}

_onTouchEnd(e) {

  ...

  clearTimeout(this.longPressTimeout);

  ...

}
Copier après la connexion

Zoom (pincer)

Le zoom est un geste très intéressant, rappelez-vous encore l'image avec zoom à deux doigts de l'iPhone de première génération tu apportes le choc ? Néanmoins, la détection des gestes de zoom est relativement simple.

  1. Le zoom est un comportement à deux doigts qui nécessite de détecter s'il y a deux points de contact sur l'écran.

  2. La quantification du rapport de mise à l'échelle est obtenue par le rapport de la distance entre deux actions de mise à l'échelle, comme le montre la figure ci-dessous.
    Principe et mise en œuvre de la détection des gestes HTML5

所以缩放的核心是获取两个接触点之间的直线距离。

//勾股定理

_getDistance(xLen,yLen) {
   return Math.sqrt(xLen * xLen + yLen * yLen);
  }
Copier après la connexion

这里的xLen是两个接触点x坐标差的绝对值,yLen相应的就是y坐标差的绝对值。

_onTouchStart(e) {

  if(e.touches.length > 1) {

    let point1 = e.touches[0];

    let point2 = e.touches[1];

    let xLen = Math.abs(point2.pageX - point1.pageX);

    let yLen = Math.abs(point2.pageY - point1.pageY);

    this.touchDistance = this._getDistance(xLen, yLen);

  } else {

    ...

  }

}
Copier après la connexion

在_onTouchStart函数中获取并且保存 touchstart 发生时两个接触点之间的距离。

_onTouchMove(e) {

  if(e.touches.length > 1) {

      let xLen = Math.abs(e.touches[0].pageX - e.touches[1].pageX);

      let yLen = Math.abs(e.touches[1].pageY - e.touches[1].pageY);

      let touchDistance = this._getDistance(xLen,yLen);

      if(this.touchDistance) {

        let pinchScale = touchDistance / this.touchDistance;

          this._emitEvent(&#39;onPinch&#39;,{scale:pinchScale - this.previousPinchScale});

          this.previousPinchScale = pinchScale;

      }

  }else {

    ...

  }

}
Copier après la connexion

旋转(rotate)

旋转手势需要检测两个比较重要的值,一是旋转的角度,二是旋转的方向(顺时针或逆时针)。

其中旋转角度和方向的计算需要通过向量的计算来获取,本文不再展开。

Principe et mise en œuvre de la détection des gestes HTML5

首先,需要获取向量的旋转方向和角度。

//这两个方法属于向量计算,具体原理请阅读本文最后的参考文献

  _getRotateDirection(vector1,vector2) {

    return vector1.x * vector2.y - vector2.x * vector1.y;

  }  

  _getRotateAngle(vector1,vector2) {

    let direction = this._getRotateDirection(vector1,vector2);

    direction = direction > 0 ? -1 : 1;

    let len1 = this._getDistance(vector1.x,vector1.y);

    let len2 = this._getDistance(vector2.x,vector2.y);

    let mr = len1 * len2;

    if(mr === 0) return 0;

    let dot = vector1.x * vector2.x + vector1.y * vector2.y;

    let r = dot / mr;

    if(r > 1) r = 1;

    if(r < -1) r = -1;

    return Math.acos(r) * direction * 180 / Math.PI;

  }
Copier après la connexion

然后,我们在手指发生移动时,调用获取旋转方向和角度的方法。

_onTouchStart(e) {

  ...  

  if(e.touches.length > 1) {

    this.touchVector = {

       x: point2.pageX - this.startX,

       y: point2.pageY - this.startY

     };

  }

  ...

}

_onTouchMove(e) {

  ...

  if(this.touchVector) {

        let vector = {

          x: e.touches[1].pageX - e.touches[0].pageX,

          y: e.touches[1].pageY - e.touches[0].pageY

        };

        let angle = this._getRotateAngle(vector,this.touchVector);

        this._emitEvent(&#39;onRotate&#39;,{

          angle

        });

        this.touchVector.x = vector.x;

        this.touchVector.y = vector.y;

      }

  ...

}
Copier après la connexion

实战

好了,我们的手势系统到这里就完成了。接下来要在实战中检验这套系统是否可靠,做一个简单的图片浏览器,支持图片缩放,旋转,移动,长按。

首先,做好DOM规划,和“之前”一样,我们的事件监听机制并不直接作用在图片上,而是作用在图片的父元素上。

Principe et mise en œuvre de la détection des gestes HTML5

然后,可以开始使用上面的手势检测系统了。

render() {

    return (

      <Gestures onPinch={this.onPinch} onMove={this.onMove} onRotate={this.onRotate} onDoubleTap={this.onDoubleTap} onLongPress={this.onLongPress}>

        <p className="wrapper" >

          ![](http://www.php.cn/)

        </p>

      </Gestures>

    );

  }
Copier après la connexion

由于我们的手势系统检测的增量,因此不能直接把增量应用在对象上,而是需要把这些增量累加。以旋转为例:

onRotate(event) {

    //对增量进行累加

    this.angle += event.angle

    this.setState({

      angle:this.angle

    });

  }
Copier après la connexion

至此,我们的手势检测就完成了。

 以上就是HTML5 手势检测原理和实现的内容,更多相关内容请关注PHP中文网(www.php.cn)!



Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal