-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtouch.js
120 lines (105 loc) · 2.77 KB
/
touch.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
'use strict'
/**
* Module dependencies.
*/
const createCommand = require('./command')
const getEventOffset = require('mouse-event-offset')
const events = require('dom-events')
const raf = require('raf')
/**
* Defaulttouch sttae
*/
const kDefaultTouchState = {
currentX: 0,
currentY: 0,
offsetX: 0,
offsetY: 0,
startX: 0,
startY: 0,
deltaX: 0,
deltaY: 0,
prevX: 0,
prevY: 0,
}
/**
* Creates a function that is suite to be an
* Axis3D command and current exposes touch
* state.
*
* @param {!Object} ctx
* @return {Function}
*/
module.exports = createTouchCommand
function createTouchCommand(ctx) {
const touches = []
const state = {
prev: null,
current: {touches: touches}
}
if (!ctx || 'object' != typeof ctx || Array.isArray(ctx)) {
throw new TypeError("createTouchCommand(): Expecting context object.")
}
if (ctx.domElement) {
events.on(ctx.domElement, 'touchstart', ontouchstart, false)
events.on(ctx.domElement, 'touchmove', ontouchmove, false)
events.on(ctx.domElement, 'touchend', ontouchend, false)
events.on(ctx.domElement, 'touchcancel', ontouchend, false)
}
ctx.once('beforedestroy', function() {
if (ctx.domElement) {
events.off(ctx.domElement, 'touchstart', ontouchstart, false)
events.off(ctx.domElement, 'touchmove', ontouchmove, false)
events.off(ctx.domElement, 'touchend', ontouchend, false)
events.off(ctx.domElement, 'touchcancel', ontouchend, false)
}
})
return createCommand(state)
function createTouch(i, e) {
const x = e.touches[i].clientX
const y = e.touches[i].clientY
return Object.assign({}, kDefaultTouchState, {
currentX: x,
currentY: y,
startX: x,
startY: y,
})
}
function synchronizeTouch(i, e) {
const touchTarget = e.targetTouches[i]
const touch = touches[i]
const offset = getEventOffset(e)
if (null == touch || null == touchTarget) {
return
}
touch.prevX = touch.currentX
touch.prevY = touch.currentY
touch.deltaX = touchTarget.clientX - touch.currentX
touch.deltaY = touchTarget.clientY - touch.currentY
touch.offsetX = offset[0]
touch.offsetY = offset[1]
touch.currentX = touchTarget.clientX
touch.currentY = touchTarget.clientY
raf(function() {
Object.assign(touch, {deltaX: 0, deltaY: 0})
})
}
function ontouchstart(e) {
e.preventDefault()
state.current.event = e
for (let i = 0; i < e.touches.length; ++i) {
touches[i] = createTouch(i, e)
synchronizeTouch(i, e)
}
}
function ontouchend(e) {
e.preventDefault()
touches.splice(0, touches.length)
}
function ontouchmove(e) {
if (touches && touches.length) {
for (let i = 0; i < touches.length; ++i) {
synchronizeTouch(i, e)
}
}
}
}