Principle and implementation example of HTML5 gesture detection

Source: Internet
Author: User
Tags abs

Commonly used HTML5 gestures can be divided into two categories, one-point gestures and two-point gestures. A single point gesture has tap (click), double tap (double-click), Long Tap (long Press), swipe (swing), move (moving). Two point gestures have pinch (zoom), rotate (rotate).

Next we implement a JS library to detect these gestures and use this gesture library to make cool interactive effects.


Move

About mobile gesture detection we have made a detailed introduction in this blog post, no longer repeat here. To sum up, it is OK to subtract the coordinate position between the two displacement points at each Touchmove event.

Click (TAP)

The key of gesture detection is to decompose gestures with touchstart,touchmove,touchend three events.

So how do you decompose the click event?

When touchstart occurs, there is only one contact point to enter the click Detection. Because the Click event is limited to one finger action.
No Touchmove event occurred or touchmove in a very small range (pictured below). Limit Touchmove in a very small range, is to give users a certain amount of redundant space, because can not ensure that the user's fingers in contact with the screen does not occur a slight displacement.

3.touchend occurs within a short period of time after Touchstart (pictured below). The threshold for this time period is the millisecond level, which is used to limit the time of the finger and screen contact. Because click the event from start to finish is very fast.

With the above process, you can start monitoring the tap event.

_gettime () {

return new Date (). GetTime ();

}

_ontouchstart (e) {

Record where the touch started

This.startx = E.touches[0].pagex;

This.starty = E.touches[0].pagey;

if (E.touches.length > 1) {

Multi-point monitoring

...

}else {

Record the time the touch started

This.starttime = This._gettime ();

}

}

_ontouchmove (e) {

...

Record where the finger is moving

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 {

The movement of the finger is less than 10 pixels and the contact time of the finger and screen is 500 milliseconds.

if (Timestamp-this.starttime < 500) {

This._emitevent (' OnTap ')

}

}

}
Double-click (double tap)

As with a click, the double-click Event also requires us to quantify the gestures.

Double-click an event is the behavior of a finger. So in Touchstart, we have to determine how many points of contact the screen has at this time.
The double-click event contains two separate click Behaviors. Ideally, these two clicks should fall on the same spot on the screen. In order to give the user a certain amount of redundant space, two clicks of the coordinate point to limit the distance within 10 pixels.

Double-click the event essence is two quick clicks. That is to say, two clicks the interval time is very short. With a certain amount of testing quantified, we set the interval of two clicks to 300 milliseconds.

Note In the double-click event we detected the displacements and intervals of the adjacent two Touchstart events.

_ontouchstart (e) {

if (E.touches.length > 1) {

...

} else {

if (this.previoustouchpoint) {

Two times the distance between adjacent Touchstart is less than 10, while the interval is less than 300ms

if (Math.Abs (THIS.STARTX-THIS.PREVIOUSTOUCHPOINT.STARTX) < &&

Math.Abs (This.starty-this.previoustouchpoint.starty) < &&

Math.Abs (This.starttime-this.previoustouchtime) < 300) {

This._emitevent (' Ondoubletap ');

}

}

Saves time and location information for the last Touchstart

This.previoustouchtime = This.starttime;

This.previoustouchpoint = {

StartX:this.startX,

StartY:this.startY

};

}

}
Long Press

The long press should be the easiest gesture to decompose. We can decompose this way: for a long time after the touchstart occurs, if no touchmove or Touchend event occurs, then the long press gesture is triggered.

Long press is a finger behavior that needs to be tested on the screen to see if there is only one contact point.
If the finger moves in space, then the length is canceled by the event.
If the finger stays on the screen longer than 800ms, it triggers a long press gesture.
If the finger stays on the screen for less than 800ms, that is, the touchend is triggered in 800ms after the touchstart occurs, so long as the event is canceled.

_ontouchstart (e) {

Cleartimeout (this.longpresstimeout);

if (E.touches.length > 1) {

}else {

This.longpresstimeout = settimeout (() =>{

This._emitevent (' onlongpress ');

});

}

}

_ontouchmove (e) {

...

Cleartimeout (this.longpresstimeout);

...

}

_ontouchend (e) {

...

Cleartimeout (this.longpresstimeout);

...

}
Zoom (pinch)

Zooming is a very interesting gesture, remember the first generation of the iphone double finger zoom picture to you to bring the shock? However, the measurement of the shrinking drop potential is relatively simple.

Scaling is the behavior of two fingers and needs to be tested to see if there are two contact points on the screen.
Scaling is quantified by the ratio of distances between two scaling behaviors is worth it to, as shown below.

So the core of the scaling is to get the straight distance between the two contact points.

Pythagorean

_getdistance (Xlen,ylen) {
Return math.sqrt (Xlen * xlen + Ylen * ylen);
}
The Xlen here is the absolute value of the X coordinate difference of the two contact points, and the corresponding Ylen is the absolute value of the Y coordinate difference.

_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 {

...

}

}
In the _ontouchstart function, the distance between the two contact points is obtained and saved when the touchstart occurs.

_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 (' Onpinch ', {scale:pinchscale-this.previouspinchscale});

This.previouspinchscale = Pinchscale;

}

}else {

...

}

}
Rotation (rotate)

Rotating gestures need to detect two more important values, one is the angle of rotation, and the other is the direction of rotation (clockwise or counterclockwise).

The calculation of rotation angle and direction needs to be obtained through the calculation of vectors, and this paper is no longer expanded.


First, you need to get the direction and angle of rotation of the vector.

These two methods belong to the vector computation, the concrete principle please read the last reference of this article

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

}
Then we call the method that gets the direction and angle of rotation when the finger is moving.

_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 (' Onrotate ', {

Angle

});

this.touchvector.x = vector.x;

This.touchvector.y = VECTOR.Y;

}

...

}
Actual combat

Well, our gesture system is done here. Next to the actual combat test this system is reliable, do a simple picture browser, support image scaling, rotating, moving, long press.

First of all, do DOM programming, like [before], our event-monitoring mechanism does not directly affect the image, but it acts on the parent element of the picture.


Then, you can start using the gesture detection system above.

Render () {

Return (

<gestures onpinch={this.onpinch} onmove={this.onmove} onrotate={this.onrotate} OnDoubleTap={this.onDoubleTap} Onlongpress={this.onlongpress}>

<div classname= "wrapper" >

! [] (http://upload-images.jianshu.io/upload_images/2362670-f8b44d4b9101e8d6.jpg?imageMogr2/auto-orient/strip% 7cimageview2/2/w/1240)

</div>

</Gestures>

);

}
Because of the increment of our gesture system detection, we cannot apply the increment directly to the object, but we need to add these increments. Take rotation for example:

Onrotate (event) {

Add an increment

This.angle + + Event.angle

This.setstate ({

Angle:this.angle

});

}
At this point, our gesture detection is complete.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.