const config = { maxSingleTouchTime : 300 , singleTapDistanceSquared : 25 } ; type Point = { x : number ; y : number ; } ; type ClapHandler = { ( e ) : void ; ( e ) : void ; } ; export default function onClap ( element , callback , ctx ? ) { var touchStartTime = Date . now ( ) ; let startPos ; element . addEventListener ( 'click' , invokeHandler as ClapHandler , { passive : false } ) ; element . addEventListener ( 'touchend' , handleTouchEnd , { passive : false } ) ; element . addEventListener ( 'touchstart' , handleTouchStart , { passive : false } ) ; return disposePrevHandler ; function handleTouchStart ( e ) { var touches = e . touches ; if ( touches . length === 1 ) { touchStartTime = Date . now ( ) ; startPos = { x : e . touches [ 0 ] . pageX , y : e . touches [ 0 ] . pageY } ; } } function handleTouchEnd ( e ) { if ( e . touches . length > 1 ) return ; var dt = Date . now ( ) - touchStartTime ; if ( dt > config . maxSingleTouchTime ) return ; let touch = e . changedTouches [ 0 ] ; var dx = touch . pageX - startPos . x ; var dy = touch . pageY - startPos . y ; if ( dx * dx + dy * dy < config . singleTapDistanceSquared ) { invokeHandler ( touch ) ; } } function disposePrevHandler ( ) { element . removeEventListener ( 'click' , invokeHandler as ClapHandler ) ; element . removeEventListener ( 'touchend' , handleTouchEnd ) ; element . removeEventListener ( 'touchstart' , handleTouchStart ) ; } function invokeHandler ( e ) { callback . call ( ctx , e ) ; } }