Permalink
Browse files

Big cleanup

  • Loading branch information...
Koen Bok
Koen Bok committed Jan 27, 2016
1 parent 111572b commit 575fadca5f3af02e5f98f1ea232d4ce3090bcfe1
Showing with 113 additions and 68 deletions.
  1. +108 −40 framer/GestureInputRecognizer.coffee
  2. +1 −24 framer/LayerPinchable.coffee
  3. +4 −4 framer/Utils.coffee
@@ -11,6 +11,14 @@ GestureInputForceTapMobilePollTime = 1/30
{DOMEventManager} = require "./DOMEventManager"
Utils.sanitizeRotation = ->
previous = null
return sanitize = (value) ->
previous ?= value
return value
class exports.GestureInputRecognizer
constructor: ->
@@ -35,11 +43,13 @@ class exports.GestureInputRecognizer
@session =
startEvent: @_getGestureEvent(event)
lastEvent: null
startMultiEvent: null
startTime: Date.now()
pressTimer: window.setTimeout(@longpressstart, GestureInputLongPressTime * 1000)
started: {}
events: []
sanitizeRotation: Utils.sanitizeRotation()
event = @_getGestureEvent(event)
@@ -296,14 +306,25 @@ class exports.GestureInputRecognizer
@session.lastEvent = event
_getEventPoint: (event) ->
if event.touches?.length > 1
return Utils.pointCenter(
@_getTouchPoint(event, 0),
@_getTouchPoint(event, 1))
if event.touches?.length == 1
return @_getTouchPoint(event, 0)
return point =
x: event.pageX
y: event.pageY
_getGestureEvent: (event) ->
_.extend event,
time: Date.now() # Current time √
point: {x:event.pageX, y:event.pageY} # Current point √
start: {x:event.pageX, y:event.pageY} # Start point √
previous: {x:event.pageX, y:event.pageY} # Previous point √
point: @_getEventPoint(event) # Current point √
start: @_getEventPoint(event) # Start point √
previous: @_getEventPoint(event) # Previous point √
offset: {x:0, y:0} # Offset since start √
offsetTime: 0 # Time since start √
@@ -319,66 +340,107 @@ class exports.GestureInputRecognizer
velocity: {x:0, y:0} # Velocity average over the last few events √
fingers: event.touches?.length or 0 # Number of fingers used √
touchCenter: {x:event.pageX, y:event.pageY} # Center between two fingers √
touchDistance: 0 # Distance between two fingers √
touchCenter: @_getEventPoint(event) # Center between two fingers √
touchOffset: {x:0, y:0} # Offset between two fingers √
touchDistance: 0 # Distance between two fingers √
scale: 1 # Scale value from two fingers √
scaleDirection: null # Direction for scale: up or down
rotation: 0 # Rotation value from two fingers √
# Properties relative to a start event
if @session?.startEvent
event.start = @session.startEvent.point
event.offsetTime = event.time - @session.startEvent.time
event.offset = Utils.pointSubtract(event.point, event.start)
event.offsetAngle = Utils.pointAngle(event.start, event.point)
event.offsetTime = event.time - @session.startEvent.time
event.offsetAngle = Utils.pointAngle(
@_getTouchPoint(@session.startEvent, 0),
@_getTouchPoint(event, 0))
event.offsetDirection = @_getDirection(event.offset)
# Properties relative to the previous event
if @session?.lastEvent
event.previous = @session.lastEvent.point
event.deltaTime = event.time - @session.lastEvent.time
event.delta = Utils.pointSubtract(event.point, @session.lastEvent.point)
event.deltaAngle = Utils.pointAngle(event.point, @session.lastEvent.point)
event.deltaDirection = @_getDirection(event.delta)
# Properties related to multi touch
if event.fingers > 1
touchPointA = @_getTouchPoint(event, 0)
touchPointB = @_getTouchPoint(event, 1)
event.touchCenter = Utils.pointCenter(touchPointB, touchPointA)
event.touchDistance = Utils.pointDistance(touchPointA, touchPointB)
event.rotation = Utils.pointAngle(touchPointA, touchPointB)
# Special cases
# Velocity
if @session?.events
events = _.filter @session.events, (e) ->
return e.time > (event.time - (GestureInputVelocityTime * 1000))
event.velocity = @_getVelocity(events)
if event.fingers > 0
event.angle = 0
if @session?.startEvent
pointA = @_getTouchPoint(@session.startEvent, 0)
pointB = @_getTouchPoint(event, 0)
event.angle = Utils.pointAngle(pointA, pointB)
event.touchOffset = Utils.pointSubtract(pointA, pointB)
event.offsetDirection = @_getDirection(event.offset)
if @session?.lastEvent
if @session.lastEvent.fingers == 1 and event.fingers == 2
print "1 -> 2"
if @session.lastEvent.fingers == 2 and event.fingers == 1
print "2 -> 1"
# if event.fingers > 0
# if @session?.startEvent
# pointA = @_getTouchPoint(@session.startEvent, 0)
# pointB = @_getTouchPoint(event, 0)
# event.angle = Utils.pointAngle(pointA, pointB)
# event.touchOffset = Utils.pointSubtract(pointA, pointB)
if event.fingers > 1
pointA = @_getTouchPoint(event, 0)
pointB = @_getTouchPoint(event, 1)
event.touchCenter = Utils.pointCenter(pointB, pointA)
event.touchDistance = Utils.pointDistance(pointA, pointB)
event.rotation = Utils.pointAngle(pointA, pointB)
# if event.fingers > 1
# pointA = @_getTouchPoint(event, 0)
# pointB = @_getTouchPoint(event, 1)
# event.touchCenter = Utils.pointCenter(pointB, pointA)
# event.touchDistance = Utils.pointDistance(pointA, pointB)
# event.rotation = Utils.pointAngle(pointA, pointB)
if @session?.lastEvent
# If the amount of fingers changed we don't send any delta
if @session.lastEvent.fingers != event.fingers
event.delta = {x:0, y:0}
# # if @session?.lastEvent
# # if Math.abs(event.rotation - @session.lastEvent.rotation) >= 180
# # print "Oh no"
# If there are exactly two fingers we use their center point as delta,
# this works because we use the single finger point as center when there
# is only one finger in this touch.
else
event.delta = Utils.pointSubtract(event.touchCenter, @session.lastEvent.touchCenter)
event.deltaAngle = Utils.pointAngle(@session.lastEvent.touchCenter, event.touchCenter)
event.deltaDirection = @_getDirection(event.delta)
# if @session?.lastEvent
# # If the amount of fingers changed we don't send any delta
# if @session.lastEvent.fingers != event.fingers
# event.delta = {x:0, y:0}
# # If there are exactly two fingers we use their center point as delta,
# # this works because we use the single finger point as center when there
# # is only one finger in this touch.
# else
# event.delta = Utils.pointSubtract(event.touchCenter, @session.lastEvent.touchCenter)
# event.deltaAngle = Utils.pointAngle(@session.lastEvent.touchCenter, event.touchCenter)
# event.deltaDirection = @_getDirection(event.delta)
# if @session?.started.pinch
# event.scale = event.touchDistance / @session.started.pinch.touchDistance
# if @session?.lastEvent
# event.scaleDirection = @_getScaleDirection(event.scale - @session.lastEvent.scale)
if @session?.started.pinch
event.scale = event.touchDistance / @session.started.pinch.touchDistance
# if @session?.force
# event.force = @session.force
if @session?.force
event.force = @session.force
# event.offset = Utils.pointSubtract(event.point, event.start)
# event.offsetAngle = Utils.pointAngle(event.start, event.point)
# event.offsetDirection = @_getDirection(event.offset)
# # if @session.lastEvent?
# # if @session.lastEvent.fingers == 1 and event.fingers == 2
# # event.offset = Utils.pointSubtract(event.offset, event.touchOff)
# Convert point style event properties to dom style:
# event.delta -> event.deltaX, event.deltaY
@@ -407,6 +469,12 @@ class exports.GestureInputRecognizer
return "right" if direction is "left"
return "bottom" if direction is "up"
return "left" if direction is "right"
return null
_getScaleDirection: (offset) ->
return "up" if offset > 0
return "down" if offset < 0
return null
_createEvent: (type, event) ->
@@ -14,6 +14,7 @@ Events.ScaleStart = "scalestart"
Events.Scale = "scale"
Events.ScaleEnd = "scaleend"
class exports.LayerPinchable extends BaseClass
@define "enabled", @simpleProperty("enabled", true)
@@ -49,9 +50,6 @@ class exports.LayerPinchable extends BaseClass
_pinchStart: (event) =>
@_reset()
@emit(Events.PinchStart, event)
@emit(Events.ScaleStart, event) if @scale
@emit(Events.RotateStart, event) if @rotate
if @centerOrigin
@@ -98,27 +96,6 @@ class exports.LayerPinchable extends BaseClass
rotation = Utils.clamp(rotation, @rotateMin, @rotateMax) if (@rotateMin and @rotateMax)
rotation = Utils.nearestIncrement(rotation, @rotateIncrements) if @rotateIncrements
@layer.rotation = rotation
@emit(Events.Rotate, event)
@emit(Events.Pinch, event)
_pinchEnd: (event) =>
@_reset()
@emit(Events.PinchEnd, event)
@emit(Events.ScaleEnd, event) if @scale
@emit(Events.RotateEnd, event) if @rotate
emit: (eventName, event) ->
return
@layer.emit(eventName, event, @)
super eventName, event, @
onPinchStart: (cb) -> @on(Events.PinchStart, cb)
onPinch: (cb) -> @on(Events.Pinch, cb)
onPinchEnd: (cb) -> @on(Events.PinchEnd, cb)
onRotateStart: (cb) -> @on(Events.RotateStart, cb)
onRotate: (cb) -> @on(Events.Rotate, cb)
onRotateEnd: (cb) -> @on(Events.RotateEnd, cb)
onScaleStart: (cb) -> @on(Events.ScaleStart, cb)
onScale: (cb) -> @on(Events.Scale, cb)
onScaleEnd: (cb) -> @on(Events.ScaleEnd, cb)
@@ -793,7 +793,7 @@ Utils.pointAngle = (p1, p2) ->
# Coordinate system
# convert a point from a layer to the context level, with rootContext enabled you can make it cross to the top context
Utils.convertPointToContext = (point = {}, layer, rootContext=false, includeLayer = true) ->
Utils.convertPointToContext = (point = {}, layer, rootContext=false, includeLayer=true) ->
point = _.defaults(point, {x:0, y:0, z:0})
ancestors = layer.ancestors(rootContext)
ancestors.unshift(layer) if includeLayer
@@ -805,15 +805,15 @@ Utils.convertPointToContext = (point = {}, layer, rootContext=false, includeLaye
return point
Utils.convertFrameToContext = (frame = {}, layer, rootContext=false, includeLayer = true) ->
Utils.convertFrameToContext = (frame = {}, layer, rootContext=false, includeLayer=true) ->
frame = _.defaults(frame, {x:0, y:0, width:100, height:100})
corners = Utils.pointsFromFrame(frame)
convertedCorners = corners.map (point) =>
return Utils.convertPointToContext(point, layer, rootContext, includeLayer)
return Utils.frameFromPoints(convertedCorners)
# convert a point from the context level to a layer, with rootContext enabled you can make it cross from the top context
Utils.convertPointFromContext = (point = {}, layer, rootContext=false, includeLayer = true) ->
Utils.convertPointFromContext = (point = {}, layer, rootContext=false, includeLayer=true) ->
point = _.defaults(point, {x:0, y:0, z:0})
ancestors = layer.ancestors(rootContext)
ancestors.reverse()
@@ -823,7 +823,7 @@ Utils.convertPointFromContext = (point = {}, layer, rootContext=false, includeLa
return point
# convert a frame from the context level to a layer, with rootContext enabled you can make it start from the top context
Utils.convertFrameFromContext = (frame = {}, layer, rootContext=false, includeLayer = true) ->
Utils.convertFrameFromContext = (frame = {}, layer, rootContext=false, includeLayer=true) ->
frame = _.defaults(frame, {x:0, y:0, width:100, height:100})
corners = Utils.pointsFromFrame(frame)
convertedCorners = corners.map (point) =>

0 comments on commit 575fadc

Please sign in to comment.