forked from bsdfzzzy/vue2-hammer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
132 lines (125 loc) · 3.96 KB
/
index.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
121
122
123
124
125
126
127
128
129
130
131
import Hammer from 'hammerjs'
import { isEmpty } from 'lodash'
const gestures = ['tap', 'pan', 'pinch', 'press', 'rotate', 'swipe', 'doubletap']
const directions = ['up', 'down', 'left', 'right', 'horizontal', 'vertical', 'all']
export const VueHammer = {
config: {},
customEvents: {},
install: function(Vue) {
const that = this
Vue.directive('hammer', {
bind(el, binding) {
if (!el.hammer) {
el.hammer = new Hammer.Manager(el)
}
const mc = el.hammer
// determine event type
const event = binding.arg
if (!event) {
console.warn('[vue-hammer] event type argument is required.')
}
that.config[event] = {}
const direction = binding.modifiers
if (!isEmpty(direction)) {
Object.keys(direction).map(keyName => {
that.config[event].direction = String(keyName)
})
}
let recognizerType, recognizer
if (that.customEvents[event]) {
// custom event
const custom = that.customEvents[event]
recognizerType = custom.type
recognizer = new Hammer[that.capitalize(recognizerType)](custom)
recognizer.recognizeWith(mc.recognizers)
mc.add(recognizer)
} else {
// built-in event
recognizerType = gestures.find(gesture => gesture === event)
if (!recognizerType) {
console.warn('[vue-hammer] invalid event type: ' + event)
return
}
recognizer = mc.get(recognizerType)
if (!recognizer) {
// add recognizer
recognizer = new Hammer[that.capitalize(recognizerType)]()
// make sure multiple recognizers work together...
recognizer.recognizeWith(mc.recognizers)
mc.add(recognizer)
}
// apply global options
const globalOptions = VueHammer.config[recognizerType]
if (globalOptions) {
that.guardDirections(globalOptions)
recognizer.set(globalOptions)
}
// apply local options
const localOptions =
el.hammerOptions &&
el.hammerOptions[recognizerType]
if (localOptions) {
that.guardDirections(localOptions)
recognizer.set(localOptions)
}
}
},
inserted(el, binding) {
const mc = el.hammer
const event = binding.arg
if (mc.handler) {
mc.off(event, mc.handler)
}
if (typeof binding.value !== 'function') {
mc.handler = null
console.warn(
'[vue-hammer] invalid handler function for v-hammer: ' +
binding.arg
)
} else {
mc.on(event, (mc.handler = binding.value))
}
},
update(el, binding) {
const mc = el.hammer
const event = binding.arg
// teardown old handler
if (mc.handler) {
mc.off(event, mc.handler)
}
if (typeof binding.value !== 'function') {
mc.handler = null
console.warn(
'[vue-hammer] invalid handler function for v-hammer: ' +
binding.arg
)
} else {
mc.on(event, (mc.handler = binding.value))
}
},
unbind(el, binding) {
if (mc.handler) {
el.hammer.off(binding.arg, mc.handler)
}
if (!Object.keys(mc.handlers).length) {
el.hammer.destroy()
el.hammer = null
}
},
})
},
guardDirections(options) {
var dir = options.direction
if (typeof dir === 'string') {
var hammerDirection = 'DIRECTION_' + dir.toUpperCase()
if (directions.indexOf(dir) > -1 && Hammer.hasOwnProperty(hammerDirection)) {
options.direction = Hammer[hammerDirection]
} else {
console.warn('[vue-hammer] invalid direction: ' + dir)
}
}
},
capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1)
},
}