|
|
@@ -1,17 +1,23 @@ |
|
|
_ = require "underscore" |
|
|
|
|
|
{EventEmitter} = require "../eventemitter" |
|
|
{Events} = require "../primitives/events" |
|
|
|
|
|
class exports.Draggable |
|
|
# Add specific events for draggable |
|
|
Events.DragStart = "dragstart" |
|
|
Events.DragMove = "dragmove" |
|
|
Events.DragEnd = "dragend" |
|
|
|
|
|
# Make any view draggable |
|
|
|
|
|
class exports.Draggable extends EventEmitter |
|
|
|
|
|
@VelocityTimeOut = 100 |
|
|
|
|
|
constructor: (@view) -> |
|
|
|
|
|
@speed = {x:1.0, y:1.0} |
|
|
|
|
|
if @view.__draggable |
|
|
console.error "Draggable: already registered draggable for #{@view.name}" |
|
|
|
|
|
@view.__draggable = @ |
|
|
@_deltas = [] |
|
|
@_isDragging = false |
|
|
|
|
@@ -20,14 +26,39 @@ class exports.Draggable |
|
|
attach: -> @view.on Events.TouchStart, @_touchStart |
|
|
remove: -> @view.off Events.TouchStart, @_touchStart |
|
|
|
|
|
calculateVelocity: -> |
|
|
|
|
|
if @_deltas.length < 2 |
|
|
return {x:0, y:0} |
|
|
|
|
|
curr = @_deltas[-1..-1][0] |
|
|
prev = @_deltas[-2..-2][0] |
|
|
time = curr.t - prev.t |
|
|
|
|
|
# Bail out if the last move updates where a while ago |
|
|
timeSinceLastMove = (new Date().getTime() - prev.t) |
|
|
|
|
|
if timeSinceLastMove > @VelocityTimeOut |
|
|
return {x:0, y:0} |
|
|
|
|
|
velocity = |
|
|
x: (curr.x - prev.x) / time |
|
|
y: (curr.y - prev.y) / time |
|
|
|
|
|
velocity.x = 0 if velocity.x is Infinity |
|
|
velocity.y = 0 if velocity.y is Infinity |
|
|
|
|
|
velocity |
|
|
|
|
|
_updatePosition: (event) => |
|
|
|
|
|
touchEvent = Events.sanitize event |
|
|
touchEvent = Events.touchEvent event |
|
|
|
|
|
delta = |
|
|
x: touchEvent.clientX - @_start.x |
|
|
y: touchEvent.clientY - @_start.y |
|
|
|
|
|
|
|
|
# Correct for current drag speed |
|
|
correctedDelta = |
|
|
x: delta.x * @speed.x |
|
|
y: delta.y * @speed.y |
|
@@ -46,7 +77,7 @@ class exports.Draggable |
|
|
|
|
|
@_isDragging = true |
|
|
|
|
|
touchEvent = Events.sanitize event |
|
|
touchEvent = Events.touchEvent event |
|
|
|
|
|
@_start = |
|
|
x: touchEvent.clientX |
|
@@ -59,7 +90,7 @@ class exports.Draggable |
|
|
document.addEventListener Events.TouchMove, @_updatePosition |
|
|
document.addEventListener Events.TouchEnd, @_touchEnd |
|
|
|
|
|
@view.emit Events.DragStart, event |
|
|
@emit Events.DragStart, event |
|
|
|
|
|
_touchEnd: (event) => |
|
|
|
|
@@ -68,58 +99,6 @@ class exports.Draggable |
|
|
document.removeEventListener Events.TouchMove, @_updatePosition |
|
|
document.removeEventListener Events.TouchEnd, @_touchEnd |
|
|
|
|
|
@view.emit Events.DragEnd, event |
|
|
@_deltas = [] |
|
|
|
|
|
_calculateVelocity: (time=20) => |
|
|
@emit Events.DragEnd, event |
|
|
|
|
|
if @_deltas.length < 2 |
|
|
return {x:0, y:0} |
|
|
|
|
|
curr = @_deltas[-1..-1][0] |
|
|
prev = @_deltas[-2..-2][0] |
|
|
time = curr.t - prev.t |
|
|
|
|
|
# Bail out if the last move updates where a while ago |
|
|
timeSinceLastMove = (new Date().getTime() - prev.t) |
|
|
|
|
|
if timeSinceLastMove > 100 |
|
|
return {x:0, y:0} |
|
|
|
|
|
velocity = |
|
|
x: (curr.x - prev.x) / time |
|
|
y: (curr.y - prev.y) / time |
|
|
|
|
|
velocity.x = 0 if velocity.x is Infinity |
|
|
velocity.y = 0 if velocity.y is Infinity |
|
|
|
|
|
velocity |
|
|
|
|
|
_calculateAverageVelocity: (time=100) => |
|
|
|
|
|
if @_deltas.length < 2 |
|
|
return {x:0, y:0} |
|
|
|
|
|
currTime = lastTime = _.last(@_deltas).t |
|
|
|
|
|
deltas = for i in [@_deltas.length - 1..0] by -1 |
|
|
|
|
|
currDelta = @_deltas[i] |
|
|
currTime = currDelta.t |
|
|
|
|
|
if currTime < (lastTime - time) |
|
|
break |
|
|
|
|
|
currDelta |
|
|
|
|
|
totalDelta = |
|
|
x: utils.sum(_.pluck deltas, "x") |
|
|
y: utils.sum(_.pluck deltas, "y") |
|
|
|
|
|
totalTime = _.first(deltas).t - _.last(deltas).t |
|
|
|
|
|
return {x:0, y:0} if totalTime is 0 |
|
|
|
|
|
velocity = |
|
|
x: (totalDelta.x / totalTime) |
|
|
y: (totalDelta.y / totalTime) |
|
|
@_deltas = []
|