Permalink
Browse files

Merge pull request #244 from jchavarri/gestures

Gesture support using Hammer.js
  • Loading branch information...
koenbok committed Jan 8, 2016
2 parents 36193ac + a30ad3e commit d7571f8e0b4187d44b83802ab20bb2e152ab29c0
@@ -1,5 +1,6 @@
{_} = require "./Underscore"
{EventEmitter} = require "./EventEmitter"
{GestureManagerElement} = require "./GestureManager"
Utils = require "./Utils"
@@ -8,14 +9,21 @@ EventManagerIdCounter = 0
class DOMEventManagerElement extends EventEmitter
constructor: (@element) ->
@_elementGestureManager = new GestureManagerElement(@element)
addListener: (eventName, listener, capture=false) ->
super(eventName, listener)
@element.addEventListener(eventName, listener, capture)
if Events.isGestureEvent eventName
@_elementGestureManager.addEventListener(eventName, listener, capture)
else
@element.addEventListener(eventName, listener)
removeListener: (eventName, listener) ->
super(eventName, listener)
@element.removeEventListener(eventName, listener)
if Events.isGestureEvent eventName
@_elementGestureManager.removeEventListener(eventName, listener)
else
@element.removeEventListener(eventName, listener)
# Keep the DOM API working
addEventListener: @::addListener
@@ -38,4 +46,4 @@ class exports.DOMEventManager
reset: ->
for element, elementEventManager of @_elements
elementEventManager.removeAllListeners()
elementEventManager.removeAllListeners()
@@ -35,13 +35,62 @@ Events.AnimationDidStart = "start"
Events.AnimationDidStop = "stop"
Events.AnimationDidEnd = "end"
# Gesture events
_gestures = []
# Pan
_gestures.push Events.Pan = "pan" # This event includes all the other Pan events
_gestures.push Events.PanStart = "panstart"
_gestures.push Events.PanMove = "panmove"
_gestures.push Events.PanEnd = "panend"
_gestures.push Events.PanCancel = "pancancel"
_gestures.push Events.PanLeft = "panleft"
_gestures.push Events.PanRight = "panright"
_gestures.push Events.PanUp = "panup"
_gestures.push Events.PanDown = "pandown"
# Pinch
_gestures.push Events.Pinch = "pinch" # This event includes all the other Pinch events
_gestures.push Events.PinchStart = "pinchstart"
_gestures.push Events.PinchMove = "pinchmove"
_gestures.push Events.PinchEnd = "pinchend"
_gestures.push Events.PinchCancel = "pinchcancel"
_gestures.push Events.PinchIn = "pinchin"
_gestures.push Events.PinchOut = "pinchout"
# Press
_gestures.push Events.Press = "press"
_gestures.push Events.PressUp = "pressup"
# Rotate
_gestures.push Events.Rotate = "rotate" # This event includes all the other Rotate events
_gestures.push Events.RotateStart = "rotatestart"
_gestures.push Events.RotateMove = "rotatemove"
_gestures.push Events.RotateEnd = "rotateend"
_gestures.push Events.RotateCancel = "rotatecancel"
# Swipe
_gestures.push Events.Swipe = "swipe"
_gestures.push Events.SwipeLeft = "swipeleft"
_gestures.push Events.SwipeRight = "swiperight"
_gestures.push Events.SwipeUp = "swipeup"
_gestures.push Events.SwipeDown = "swipedown"
# Tap
_gestures.push Events.Tap = "tap"
_gestures.push Events.SingleTap = "singletap"
_gestures.push Events.DoubleTap = "doubletap"
# Scroll events
Events.Scroll = "scroll"
# Image events
Events.ImageLoaded = "load"
Events.ImageLoadError = "error"
Events.isGestureEvent = (eventName) ->
return eventName in _gestures
# Extract touch events for any event
Events.touchEvent = (event) ->
touchEvent = event.touches?[0]
@@ -0,0 +1,143 @@
Hammer = require "hammerjs"
class exports.GestureManagerElement
constructor: (@element) ->
@_events = {}
@_manager = null
_getEventFamily: (eventName) ->
eventFamily = undefined
switch eventName
when Events.Pan, Events.PanStart, Events.PanMove, Events.PanEnd, Events.PanCancel, Events.PanLeft, Events.PanRight, Events.PanUp, Events.PanDown
eventFamily = Events.Pan
when Events.Pinch, Events.PinchStart, Events.PinchMove, Events.PinchEnd, Events.PinchCancel, Events.PinchIn, Events.PinchOut
eventFamily = Events.Pinch
when Events.Press, Events.PressUp
eventFamily = Events.Press
when Events.Rotate, Events.RotateStart, Events.RotateMove, Events.RotateEnd, Events.RotateCancel
eventFamily = Events.Rotate
when Events.Swipe, Events.SwipeLeft, Events.SwipeRight, Events.SwipeUp, Events.SwipeDown
eventFamily = Events.Swipe
when Events.Tap, Events.SingleTap
eventFamily = Events.Tap
when Events.DoubleTap # Tap and DoubleTap need different type of recognizers
eventFamily = Events.DoubleTap
else
return eventFamily
_getDependentRecognizersForEventFamily: (eventFamily) ->
# We need to add simultaneous recognition for certain gestures to be detected together
# See http://hammerjs.github.io/recognize-with/
# All these dependencies come from https://cdn.rawgit.com/hammerjs/hammer.js/master/tests/manual/visual.html
existingRecognizers = []
switch eventFamily
when Events.Pan # Pan depends on Swipe, Rotate and Pinch
if swipe = @_manager.get(Events.Swipe)
existingRecognizers.push(swipe)
if rotate = @_manager.get(Events.Rotate)
existingRecognizers.push(rotate)
if pinch = @_manager.get(Events.Pinch)
existingRecognizers.push(pinch)
when Events.Swipe # Swipe depends on Pan
if pan = @_manager.get(Events.Pan)
existingRecognizers.push(pan)
when Events.Rotate # Rotate depends on Pan and Pinch
if pan = @_manager.get(Events.Pan)
existingRecognizers.push(pan)
if pinch = @_manager.get(Events.Pinch)
existingRecognizers.push(pinch)
when Events.Pinch # Pinch depends on Pan and Rotate
if pan = @_manager.get(Events.Pan)
existingRecognizers.push(pan)
if rotate = @_manager.get(Events.Pinch)
existingRecognizers.push(rotate)
when Events.DoubleTap # DoubleTap depends on Tap
if tap = @_manager.get(Events.Tap)
existingRecognizers.push(tap)
else
return existingRecognizers
addEventListener: (eventName, listener) ->
#Lazy creation
@_manager ?= new Hammer.Manager(@element)
validEvent = true
recognizer = undefined
# Get event family to add different recognizers
eventFamily = @_getEventFamily(eventName)
# Add recognizer if needed
switch eventFamily
when Events.Pan
if not @_manager.get(Events.Pan)
recognizer = new Hammer.Pan({ event: Events.Pan})
when Events.Pinch
if not @_manager.get(Events.Pinch)
recognizer = new Hammer.Pinch({ event: Events.Pinch})
when Events.Press
if not @_manager.get(Events.Press)
recognizer = new Hammer.Press({ event: Events.Press})
when Events.Rotate
if not @_manager.get(Events.Rotate)
recognizer = new Hammer.Rotate({ event: Events.Rotate})
when Events.Swipe
if not @_manager.get(Events.Swipe)
recognizer = new Hammer.Swipe({ event: Events.Swipe})
when Events.Tap
if not @_manager.get(Events.Tap)
recognizer = new Hammer.Tap({ event: Events.Tap})
when Events.DoubleTap
if not @_manager.get(Events.DoubleTap)
recognizer = new Hammer.Tap({ event: Events.DoubleTap, taps: 2})
else
validEvent = false
if recognizer
# Add other recognizers if they existed already
existingRecognizers = @_getDependentRecognizersForEventFamily(eventFamily)
if existingRecognizers.length > 0
@_manager.add(recognizer).recognizeWith(existingRecognizers)
else
@_manager.add recognizer
if validEvent
@_manager.on eventName, listener
removeEventListener: (eventName, listener) ->
# The EventManager already checks that the listener has been registered
# so we can remove it safely
# -- Should we remove the recognizers as well?? --
@_manager.off eventName, listener
@@ -927,6 +927,43 @@ class exports.Layer extends BaseClass
onDragAnimationDidEnd: (cb) -> @on(Events.DragAnimationDidEnd, cb)
onDirectionLockDidStart: (cb) -> @on(Events.DirectionLockDidStart, cb)
onPan: (cb) -> @on(Events.Pan, cb)
onPanStart: (cb) -> @on(Events.PanStart, cb)
onPanMove: (cb) -> @on(Events.PanMove, cb)
onPanEnd: (cb) -> @on(Events.PanEnd, cb)
onPanCancel: (cb) -> @on(Events.PanCancel, cb)
onPanLeft: (cb) -> @on(Events.PanLeft, cb)
onPanRight: (cb) -> @on(Events.PanRight, cb)
onPanUp: (cb) -> @on(Events.PanUp, cb)
onPanDown: (cb) -> @on(Events.PanDown, cb)
onPinch: (cb) -> @on(Events.Pinch, cb)
onPinchStart: (cb) -> @on(Events.PinchStart, cb)
onPinchMove: (cb) -> @on(Events.PinchMove, cb)
onPinchEnd: (cb) -> @on(Events.PinchEnd, cb)
onPinchCancel: (cb) -> @on(Events.PinchCancel, cb)
onPinchIn: (cb) -> @on(Events.PinchIn, cb)
onPinchOut: (cb) -> @on(Events.PinchOut, cb)
onPress: (cb) -> @on(Events.Press, cb)
onPressUp: (cb) -> @on(Events.PressUp, cb)
onRotate: (cb) -> @on(Events.Rotate, cb)
onRotateStart: (cb) -> @on(Events.RotateStart, cb)
onRotateMove: (cb) -> @on(Events.RotateMove, cb)
onRotateEnd: (cb) -> @on(Events.RotateEnd, cb)
onRotateCancel: (cb) -> @on(Events.RotateCancel, cb)
onSwipe: (cb) -> @on(Events.Swipe, cb)
onSwipeLeft: (cb) -> @on(Events.SwipeLeft, cb)
onSwipeRight: (cb) -> @on(Events.SwipeRight, cb)
onSwipeUp: (cb) -> @on(Events.SwipeUp, cb)
onSwipeDown: (cb) -> @on(Events.SwipeDown, cb)
onTap: (cb) -> @on(Events.Tap, cb)
onSingleTap: (cb) -> @on(Events.SingleTap, cb)
onDoubleTap: (cb) -> @on(Events.DoubleTap, cb)
##############################################################
## DESCRIPTOR
@@ -15,6 +15,7 @@
"url": "https://github.com/koenbok/Framer.git"
},
"devDependencies": {
"hammerjs": "^2.0.4",
"eventemitter3": "^1.1.1",
"gulp-util": "^3.0.7",
"husl": "^6.0.1",
@@ -11,6 +11,7 @@ require "./tests/EventEmitterTest"
require "./tests/UtilsTest"
require "./tests/BaseClassTest"
require "./tests/LayerTest"
require "./tests/LayerEventsTest"
require "./tests/LayerStatesTest"
require "./tests/VideoLayerTest"
require "./tests/ImporterTest"
Oops, something went wrong.

0 comments on commit d7571f8

Please sign in to comment.