ǰÑÔ
Ëæ×Å Hybrid Ó¦Óõķḻ£¬HTML5 ¹¤³ÌʦÃÇÒѾ²»Âú×ãÓÚ°Ñ×ÀÃæ¶ËÌåÑé¼òµ¥ÒÆÖ²µ½Òƶ¯¶Ë£¬ËûÃÇêéêìÒÆ¶¯ÔÉúÓ¦ÓÃÈËÐÔ»¯µÄ²Ù×÷ÌåÑé£¬ÌØ±ðÊÇÔÉúÓ¦ÓÃÓëÉú¾ãÀ´µÄ·á¸»µÄÊÖÊÆÏµÍ³¡£HTML5
ûÓÐÌṩ¿ªÏä¼´ÓõÄÊÖÊÆÏµÍ³£¬µ«ÊÇÌṩÁ˸üµ×²ãһЩµÄ¶Ô touch ʼþµÄ¼àÌý¡£»ùÓÚ´Ë£¬ÎÒÃÇ¿ÉÒÔ×ö³ö×Ô¼ºµÄÊÖÊÆ¿â¡£
ÊÖÊÆ
³£ÓÃµÄ HTML5 ÊÖÊÆ¿ÉÒÔ·ÖΪÁ½À࣬µ¥µãÊÖÊÆºÍÁ½µãÊÖÊÆ¡£µ¥µãÊÖÊÆÓÐ tap£¨µ¥»÷£©£¬double tap£¨Ë«»÷£©£¬long
tap£¨³¤°´£©£¬swipe£¨»Ó£©£¬move£¨Òƶ¯£©¡£Á½µãÊÖÊÆÓÐ pinch£¨Ëõ·Å£©£¬rotate£¨Ðýת£©¡£
½ÓÏÂÀ´ÎÒÃÇʵÏÖÒ»¸ö¼ì²âÕâЩÊÖÊÆµÄ javaScript ¿â£¬²¢ÀûÓÃÕâ¸öÊÖÊÆ¿â×ö³öìÅ¿áµÄ½»»¥Ð§¹û¡£

ÒÆ¶¯
¹ØÓÚÒÆ¶¯ÊÖÊÆ¼ì²âÎÒÃÇÕâÀï²»ÔÙ׸Êö¡£×ܽáһϾÍÊÇÔÚÿ´Îtouchmoveʼþ·¢Éúʱ£¬°ÑÁ½¸öÎ»ÒÆµãÖ®¼äµÄ×ø±êλÖÃÏà¼õ£¬¾Í¿ÉÒÔÁË¡£
µ¥»÷£¨tap£©
ÊÖÊÆ¼ì²âµÄ¹Ø¼üÊÇÓà touchstart£¬touchmove£¬touchend Èý¸öʼþ¶ÔÊÖÊÆ½øÐзֽ⡣
ÄÇôÔõô·Ö½âµ¥»÷ʼþÄØ£¿
1.ÔÚ touchstart ·¢Éúʱ½øÈëµ¥»÷¼ì²â£¬Ö»ÓÐÒ»¸ö½Ó´¥µã¡£ÒòΪµ¥»÷ʼþÏÞÖÆÎªÒ»¸öÊÖÖ¸µÄ¶¯×÷¡£
2.ûÓз¢Éú touchmove ʼþ»òÕß touchmove ÔÚÒ»¸öºÜСµÄ·¶Î§£¨ÈçÏÂͼ£©¡£ÏÞÖÆ
touchmove ÔÚÒ»¸öºÜС·¶Î§£¬ÊÇΪÁ˸øÓû§Ò»¶¨µÄÈßÓà¿Õ¼ä£¬ÒòΪ²»Äܱ£Ö¤Óû§ÊÖÖ¸ÔÚ½Ó´¥ÆÁÄ»µÄʱºò²»·¢ÉúÇá΢µÄÎ»ÒÆ¡£

3.touchend ·¢ÉúÔÚ touchstartºóµÄºÜ¶Ìʱ¼äÄÚ£¨ÈçÏÂͼ£©¡£Õâ¸öʱ¼ä¶ÎµÄãÐÖµÊǺÁÃë¼¶£¬ÓÃÀ´ÏÞÖÆÊÖÖ¸ºÍÆÁÄ»½Ó´¥µÄʱ¼ä¡£ÒòΪµ¥»÷ʼþ´Ó¿ªÊ¼µ½½áÊøÊǺܿìµÄ¡£ 
ÓÐÁËÉÏÃæµÄÁ÷³Ì£¬¾Í¿ÉÒÔ¿ªÊ¼ÊµÏÖ tap ʼþ¼à²âÁË¡£
_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('onTap')
}
}
} |
Ë«»÷£¨double tap£©
ºÍµ¥»÷Ò»Ñù£¬Ë«»÷ʼþÒ²ÐèÒªÎÒÃǶÔÊÖÊÆ½øÐÐÁ¿»¯·Ö½â¡£
1.Ë«»÷ʼþÊÇÒ»¸öÊÖÖ¸µÄÐÐΪ¡£ËùÒÔÔÚ touchstart ʱ£¬ÎÒÃÇÒªÅжϴËʱÆÁÄ»Óм¸¸ö½Ó´¥µã¡£
2.Ë«»÷ʼþÖаüº¬Á½´Î¶ÀÁ¢µÄµ¥»÷ÐÐΪ¡£ÀíÏëÇé¿öÏ£¬ÕâÁ½´Îµã»÷Ó¦¸ÃÂäÔÚÆÁÄ»ÉϵÄͬһ¸öµãÉÏ¡£ÎªÁ˸øÓû§Ò»¶¨µÄÈßÓà¿Õ¼ä£¬½«Á½´Îµã»÷µÄ×ø±êµã¾àÀëÏÞÖÆÔÚ10¸öÏñËØÒÔÄÚ¡£

3.Ë«»÷ʼþ±¾ÖÊÊÇÁ½´Î¿ìËٵĵ¥»÷¡£Ò²¼´ÊÇ˵£¬Á½´Îµã»÷µÄ¼ä¸ôʱ¼äºÜ¶Ì¡£Í¨¹ýÒ»¶¨µÄ²âÊÔÁ¿»¯ºó£¬ÎÒÃǰÑÁ½´Îµ¥»÷µÄʱ¼ä¼ä¸ôÉèΪ300ºÁÃë¡£

×¢ÒâË«»÷ʼþÖÐÎÒÃǼì²âÁËÏàÁÚÁ½¸ö touchstart ʼþµÄÎ»ÒÆºÍʱ¼ä¼ä¸ô¡£
_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('onDoubleTap');
}
}
//±£´æÉÏÒ»´ÎtouchstartµÄʱ¼äºÍλÖÃÐÅÏ¢
this.previousTouchTime = this.startTime;
this.previousTouchPoint = {
startX : this.startX,
startY : this.startY
};
}
} |
³¤°´£¨long press£©
³¤°´Ó¦¸ÃÊÇ×îÈÝÒ×·Ö½âµÄÊÖÊÆ¡£ÎÒÃÇ¿ÉÒÔÕâÑù·Ö½â£ºÔÚ touchstart ·¢ÉúºóµÄºÜ³¤Ò»¶Îʱ¼äÄÚ£¬Èç¹ûûÓз¢Éú
touchmove »òÕß touchend ʼþ£¬ÄÇô¾Í´¥·¢³¤°´ÊÖÊÆ¡£
1.³¤°´ÊÇÒ»¸öÊÖÖ¸µÄÐÐΪ£¬ÐèÒª¼ì²âÆÁÄ»ÉÏÊÇ·ñÖ»ÓÐÒ»¸ö½Ó´¥µã¡£
2.Èç¹ûÊÖÖ¸ÔÚ¿Õ¼äÉÏ·¢ÉúÁËÒÆ¶¯£¬ÄÇô³¤°´Ê¼þÈ¡Ïû¡£
3.Èç¹ûÊÖÖ¸ÔÚÆÁÄ»ÉÏÍ£ÁôµÄʱ¼ä³¬¹ý800ms£¬ÄÇô´¥·¢³¤°´ÊÖÊÆ¡£
4.Èç¹ûÊÖÖ¸ÔÚÆÁÄ»ÉÏÍ£ÁôµÄʱ¼äСÓÚ800ms£¬Ò²¼´ touchend
ÔÚ touchstart ·¢ÉúºóµÄ800msÄÚ´¥·¢£¬ÄÇô³¤°´Ê¼þÈ¡Ïû¡£

_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);
...
} |
Ëõ·Å£¨pinch£©
Ëõ·ÅÊÇÒ»¸ö·Ç³£ÓÐȤµÄÊÖÊÆ£¬»¹¼ÇµÃµÚÒ»´úiPhone˫ָËõ·ÅͼƬ¸øÄã´øÀ´µÄÕðº³Âð£¿ËäÈ»Èç´Ë£¬Ëõ·ÅÊÖÊÆµÄ¼ì²âÈ´Ïà¶Ô¼òµ¥¡£
1.Ëõ·ÅÊÇÁ½¸öÊÖÖ¸µÄÐÐΪ£¬ÐèÒª¼ì²âÆÁÄ»ÉÏÊÇ·ñÓÐÁ½¸ö½Ó´¥µã¡£
2.Ëõ·Å±ÈÀýµÄÁ¿»¯£¬ÊÇͨ¹ýÁ½´ÎËõ·ÅÐÐΪ֮¼äµÄ¾àÀëµÄ±ÈÖµµÃµ½£¬ÈçÏÂͼ¡£

ËùÒÔËõ·ÅµÄºËÐÄÊÇ»ñÈ¡Á½¸ö½Ó´¥µãÖ®¼äµÄÖ±Ïß¾àÀë¡£
//¹´¹É¶¨Àí
_getDistance(xLen,yLen) {
return Math.sqrt(xLen * xLen + yLen * yLen);
} |
ÕâÀïµÄ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 {
...
}
} |
ÔÚ_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('onPinch',{scale:pinchScale
- this.previousPinchScale});
this.previousPinchScale = pinchScale;
}
}else {
...
}
} |
Ðýת(rotate)
ÐýתÊÖÊÆÐèÒª¼ì²âÁ½¸ö±È½ÏÖØÒªµÄÖµ£¬Ò»ÊÇÐýתµÄ½Ç¶È£¬¶þÊÇÐýתµÄ·½Ïò£¨Ë³Ê±Õë»òÄæÊ±Õ룩¡£
ÆäÖÐÐýת½Ç¶ÈºÍ·½ÏòµÄ¼ÆËãÐèҪͨ¹ýÏòÁ¿µÄ¼ÆËãÀ´»ñÈ¡£¬±¾ÎIJ»ÔÙÕ¹¿ª¡£

Ê×ÏÈ£¬ÐèÒª»ñÈ¡ÏòÁ¿µÄÐýת·½ÏòºÍ½Ç¶È¡£
//ÕâÁ½¸ö·½·¨ÊôÓÚÏòÁ¿¼ÆË㣬¾ßÌåÔÀíÇëÔĶÁ±¾ÎÄ×îºóµÄ²Î¿¼ÎÄÏ×
_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;
} |
È»ºó£¬ÎÒÃÇÔÚÊÖÖ¸·¢ÉúÒÆ¶¯Ê±£¬µ÷ÓûñÈ¡Ðýת·½ÏòºÍ½Ç¶ÈµÄ·½·¨¡£
_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;
}
...
} |
ʵս
ºÃÁË£¬ÎÒÃǵÄÊÖÊÆÏµÍ³µ½ÕâÀï¾ÍÍê³ÉÁË¡£½ÓÏÂÀ´ÒªÔÚʵսÖмìÑéÕâÌ×ϵͳÊÇ·ñ¿É¿¿£¬×öÒ»¸ö¼òµ¥µÄͼƬä¯ÀÀÆ÷£¬Ö§³ÖͼƬËõ·Å£¬Ðýת£¬Òƶ¯£¬³¤°´¡£
Ê×ÏÈ£¬×öºÃDOM¹æ»®£¬ºÍ¡°Ö®Ç°¡±Ò»Ñù£¬ÎÒÃǵÄʼþ¼àÌý»úÖÆ²¢²»Ö±½Ó×÷ÓÃÔÚͼƬÉÏ£¬¶øÊÇ×÷ÓÃÔÚͼƬµÄ¸¸ÔªËØÉÏ¡£

È»ºó£¬¿ÉÒÔ¿ªÊ¼Ê¹ÓÃÉÏÃæµÄÊÖÊÆ¼ì²âϵͳÁË¡£
render() {
return (
<Gestures onPinch={this.onPinch} onMove={this.onMove}
onRotate={this.onRotate} onDoubleTap={this.onDoubleTap}
onLongPress={this.onLongPress}>
<div className="wrapper" >

</div>
</Gestures>
);
} |
ÓÉÓÚÎÒÃǵÄÊÖÊÆÏµÍ³¼ì²âµÄÔöÁ¿£¬Òò´Ë²»ÄÜÖ±½Ó°ÑÔöÁ¿Ó¦ÓÃÔÚ¶ÔÏóÉÏ£¬¶øÊÇÐèÒª°ÑÕâЩÔöÁ¿ÀÛ¼Ó¡£ÒÔÐýתΪÀý£º
onRotate(event) {
//¶ÔÔöÁ¿½øÐÐÀÛ¼Ó
this.angle += event.angle
this.setState({
angle:this.angle
});
} |
ÖÁ´Ë£¬ÎÒÃǵÄÊÖÊÆ¼ì²â¾ÍÍê³ÉÁË¡£ |