Last active
August 29, 2015 14:19
-
-
Save matori/9c6f2d6cfa14fde6b2d5 to your computer and use it in GitHub Desktop.
Swipe
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| "use strict" | |
| normalize = -> | |
| nomalizedEvents = ["start", "move", "end", "cancel"] | |
| touchEvents = ["touchstart", "touchmove", "touchend", "touchcancel"] | |
| MSPointerEvents = ["MSPointerDown", "MSPointerMove", "MSPointerUp", "MSPointerCancel"] | |
| pointerEvents = ["pointerdown", "pointermove", "pointerup", "pointercancel"] | |
| mouseEvents = ["mousedown", "mousemove", "mouseup", null] | |
| if window.Modernizr and window.Modernizr.hasOwnProperty "touch" | |
| modernizrTouchDetect = window.Modernizr.touch | |
| supportTouch = modernizrTouchDetect or (("ontouchstart" of window) or window.DocumentTouch and document instanceof DocumentTouch) | |
| supportMSPointer = window.navigator.msPointerEnabled and not window.navigator.pointerEnabled | |
| supportPointer = window.navigator.pointerEnabled | |
| pointerType = "" | |
| if supportPointer | |
| supportEvents = pointerEvents | |
| pointerType = "pointer" | |
| else if supportMSPointer | |
| supportEvents = MSPointerEvents | |
| pointerType = "mspointer" | |
| else if supportTouch | |
| supportEvents = touchEvents | |
| pointerType = "touch" | |
| else | |
| supportEvents = mouseEvents | |
| pointerType = "mouse" | |
| eventType = {} | |
| for type, idx in nomalizedEvents | |
| eventType[type] = supportEvents[idx] | |
| eventType["type"] = pointerType | |
| eventType | |
| module.exports = normalize() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| "use strict" | |
| pointerEvents = require "./normalize-pointer-event-type" | |
| isPointer = pointerEvents.type is "pointer" | |
| isMSPointer = pointerEvents.type is "mspointer" | |
| isTouch = pointerEvents.type is "touch" | |
| isMouse = pointerEvents.type is "mouse" | |
| class Pointer | |
| defaultConfig = | |
| threshold: 100 # スワイプしたと判断できる最小移動距離 | |
| allowedTime: 500 # スワイプしたと判断できる制限時間 | |
| touchAction: "none" # PointerEvents 向けの CSS `touch-action` プロパティの値 | |
| throttle: 64 # move 時のスロットルタイム | |
| stopPropagation: false # `event.stopPropagation` するかどうか | |
| mouseFallback: true # `mousedown`, `mousemove`, `mouseup` でのフォールバックをするかどうか | |
| startCallback: (event, direction, distance) -> | |
| moveCallback: (event, direction, distance) -> | |
| endCallback: (event, direction, distance, isSwipe) -> | |
| constructor: (elements, userConfig) -> | |
| if "jquery" of elements | |
| throw "Pointer class does not allow jQuery object." | |
| @destroy() | |
| return | |
| @elements = if elements.hasOwnProperty "length" then elements else [elements] | |
| @config = @_setConfig userConfig | |
| if @config.mouseFallback is false and isMouse | |
| @destroy() | |
| return | |
| @_reset() | |
| @_init() | |
| _reset: -> | |
| @throttleTimer = undefined | |
| @isPointerDown = undefined | |
| @startTime = undefined | |
| @elapsedTime = undefined | |
| @startX = undefined | |
| @startY = undefined | |
| @isSwipe = undefined | |
| @direction = | |
| x: undefined | |
| y: undefined | |
| @distance = | |
| x: undefined | |
| y: undefined | |
| return | |
| _setConfig: (userConfig) -> | |
| config = {} | |
| for configKey, configVal of defaultConfig | |
| config[configKey] = configVal | |
| for userConfigKey, userConfigVal of userConfig | |
| config[userConfigKey] = userConfigVal | |
| config | |
| _getPointerObj: (evt) -> | |
| return if isTouch then evt.changedTouches[0] else evt | |
| _onPointerStart: (evt) => | |
| evt.preventDefault() | |
| if @config.stopPropagation | |
| evt.stopPropagation() | |
| pointerObj = @_getPointerObj evt | |
| @throttleTimer = null | |
| @isPointerDown = true | |
| @startTime = new Date().getTime() | |
| @startX = pointerObj.pageX | |
| @startY = pointerObj.pageY | |
| @isSwipe = false | |
| @direction = | |
| x: "default" | |
| y: "default" | |
| @distance = | |
| x: 0 | |
| y: 0 | |
| @config.startCallback evt, @direction, @distance | |
| _onPointerMove: (evt) => | |
| if not @isPointerDown | |
| return | |
| if not @throttleTimer | |
| @throttleTimer = setTimeout => | |
| @throttleTimer = null | |
| evt.preventDefault() | |
| if @config.stopPropagation | |
| evt.stopPropagation() | |
| pointerObj = @_getPointerObj evt | |
| @distance.x = pointerObj.pageX - @startX | |
| @distance.y = pointerObj.pageY - @startY | |
| @direction.x = if @distance.x < 0 then "left" else "right" | |
| @direction.y = if @distance.y < 0 then "up" else "down" | |
| @config.moveCallback evt, @direction, @distance | |
| , @config.throttle | |
| _onPointerEnd: (evt) => | |
| evt.preventDefault() | |
| if @config.stopPropagation | |
| evt.stopPropagation() | |
| @throttleTimer = null | |
| @isPointerDown = false | |
| @elapsedTime = new Date().getTime() - @startTime | |
| if @elapsedTime <= @config.allowedTime | |
| if Math.abs(@distance.x) >= @config.threshold or Math.abs(@distance.y) >= @config.threshold | |
| @isSwipe = true | |
| @config.endCallback evt, @direction, @distance, @isSwipe | |
| _onPointerCancel: (evt) -> | |
| evt.preventDefault() | |
| if config.stopPropagation | |
| evt.stopPropagation() | |
| @_reset() | |
| _attachEvents: => | |
| for element in @elements | |
| element.addEventListener pointerEvents.start, @_onPointerStart, false | |
| element.addEventListener pointerEvents.move, @_onPointerMove, false | |
| element.addEventListener pointerEvents.end, @_onPointerEnd, false | |
| if not isMouse | |
| element.addEventListener pointerEvents.cancel, @_onPointerCancel, false | |
| _detachEvents: -> | |
| for element in @elements | |
| element.removeEventListener pointerEvents.start, @_onPointerStart, false | |
| element.removeEventListener pointerEvents.move, @_onPointerMove, false | |
| element.removeEventListener pointerEvents.end, @_onPointerEnd, false | |
| if not isMouse | |
| element.removeEventListener pointerEvents.cancel, @_onPointerCancel, false | |
| _init: -> | |
| if isPointer or isMSPointer | |
| for element in @elements | |
| element.style.touchAction = element.style.msTouchAction = @config.touchAction | |
| @_attachEvents() | |
| destroy: -> | |
| @_detachEvents() | |
| @_reset() | |
| if isPointer or isMSPointer | |
| for element in @elements | |
| element.style.touchAction = element.style.msTouchAction = "" | |
| @elements = undefined | |
| @config = undefined | |
| module.exports = Pointer |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment