UNPKG

5.84 kBPlain TextView Raw
1import {
2 hasTransition,
3 hasPerspective,
4 hasTouch,
5 Probe,
6 EventPassthrough,
7 extend,
8 Quadrant,
9} from '@better-scroll/shared-utils'
10
11// type
12export type Tap = 'tap' | ''
13export type BounceOptions = Partial<BounceConfig> | boolean
14export type DblclickOptions = Partial<DblclickConfig> | boolean
15
16// interface
17export interface BounceConfig {
18 top: boolean
19 bottom: boolean
20 left: boolean
21 right: boolean
22}
23
24export interface DblclickConfig {
25 delay: number
26}
27
28export interface CustomOptions {}
29
30export interface DefOptions {
31 [key: string]: any
32 startX?: number
33 startY?: number
34 scrollX?: boolean
35 scrollY?: boolean
36 freeScroll?: boolean
37 directionLockThreshold?: number
38 eventPassthrough?: string
39 click?: boolean
40 tap?: Tap
41 bounce?: BounceOptions
42 bounceTime?: number
43 momentum?: boolean
44 momentumLimitTime?: number
45 momentumLimitDistance?: number
46 swipeTime?: number
47 swipeBounceTime?: number
48 deceleration?: number
49 flickLimitTime?: number
50 flickLimitDistance?: number
51 resizePolling?: number
52 probeType?: number
53 stopPropagation?: boolean
54 preventDefault?: boolean
55 preventDefaultException?: {
56 tagName?: RegExp
57 className?: RegExp
58 }
59 tagException?: {
60 tagName?: RegExp
61 className?: RegExp
62 }
63 HWCompositing?: boolean
64 useTransition?: boolean
65 bindToWrapper?: boolean
66 bindToTarget?: boolean
67 disableMouse?: boolean
68 disableTouch?: boolean
69 autoBlur?: boolean
70 translateZ?: string
71 dblclick?: DblclickOptions
72 autoEndDistance?: number
73 outOfBoundaryDampingFactor?: number
74 specifiedIndexAsContent?: number
75 quadrant?: Quadrant
76}
77
78export interface Options extends DefOptions, CustomOptions {}
79export class CustomOptions {}
80export class OptionsConstructor extends CustomOptions implements DefOptions {
81 [key: string]: any
82 startX: number
83 startY: number
84 scrollX: boolean
85 scrollY: boolean
86 freeScroll: boolean
87 directionLockThreshold: number
88 eventPassthrough: string
89 click: boolean
90 tap: Tap
91 bounce: BounceConfig
92 bounceTime: number
93 momentum: boolean
94 momentumLimitTime: number
95 momentumLimitDistance: number
96 swipeTime: number
97 swipeBounceTime: number
98 deceleration: number
99 flickLimitTime: number
100 flickLimitDistance: number
101 resizePolling: number
102 probeType: number
103 stopPropagation: boolean
104 preventDefault: boolean
105 preventDefaultException: {
106 tagName?: RegExp
107 className?: RegExp
108 }
109 tagException: {
110 tagName?: RegExp
111 className?: RegExp
112 }
113 HWCompositing: boolean
114 useTransition: boolean
115 bindToWrapper: boolean
116 bindToTarget: boolean
117 disableMouse: boolean
118 disableTouch: boolean
119 autoBlur: boolean
120 translateZ: string
121 dblclick: DblclickOptions
122 autoEndDistance: number
123 outOfBoundaryDampingFactor: number
124 specifiedIndexAsContent: number
125 quadrant: Quadrant
126
127 constructor() {
128 super()
129 this.startX = 0
130 this.startY = 0
131 this.scrollX = false
132 this.scrollY = true
133 this.freeScroll = false
134 this.directionLockThreshold = 0
135 this.eventPassthrough = EventPassthrough.None
136 this.click = false
137 this.dblclick = false
138 this.tap = ''
139
140 this.bounce = {
141 top: true,
142 bottom: true,
143 left: true,
144 right: true,
145 }
146 this.bounceTime = 800
147
148 this.momentum = true
149 this.momentumLimitTime = 300
150 this.momentumLimitDistance = 15
151
152 this.swipeTime = 2500
153 this.swipeBounceTime = 500
154
155 this.deceleration = 0.0015
156
157 this.flickLimitTime = 200
158 this.flickLimitDistance = 100
159
160 this.resizePolling = 60
161 this.probeType = Probe.Default
162
163 this.stopPropagation = false
164 this.preventDefault = true
165 this.preventDefaultException = {
166 tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|AUDIO)$/,
167 }
168 this.tagException = {
169 tagName: /^TEXTAREA$/,
170 }
171
172 this.HWCompositing = true
173 this.useTransition = true
174
175 this.bindToWrapper = false
176 this.bindToTarget = false
177 this.disableMouse = hasTouch
178 this.disableTouch = !hasTouch
179 this.autoBlur = true
180
181 this.autoEndDistance = 5
182 this.outOfBoundaryDampingFactor = 1 / 3
183 this.specifiedIndexAsContent = 0
184 this.quadrant = Quadrant.First
185 }
186 merge(options?: Options) {
187 if (!options) return this
188 for (let key in options) {
189 if (key === 'bounce') {
190 this.bounce = this.resolveBounce(options[key]!)
191 continue
192 }
193 this[key] = options[key]
194 }
195 return this
196 }
197 process() {
198 this.translateZ =
199 this.HWCompositing && hasPerspective ? ' translateZ(1px)' : ''
200
201 this.useTransition = this.useTransition && hasTransition
202
203 this.preventDefault = !this.eventPassthrough && this.preventDefault
204
205 // If you want eventPassthrough I have to lock one of the axes
206 this.scrollX =
207 this.eventPassthrough === EventPassthrough.Horizontal
208 ? false
209 : this.scrollX
210 this.scrollY =
211 this.eventPassthrough === EventPassthrough.Vertical ? false : this.scrollY
212
213 // With eventPassthrough we also need lockDirection mechanism
214 this.freeScroll = this.freeScroll && !this.eventPassthrough
215
216 // force true when freeScroll is true
217 this.scrollX = this.freeScroll ? true : this.scrollX
218 this.scrollY = this.freeScroll ? true : this.scrollY
219
220 this.directionLockThreshold = this.eventPassthrough
221 ? 0
222 : this.directionLockThreshold
223
224 return this
225 }
226
227 resolveBounce(bounceOptions: BounceOptions): BounceConfig {
228 const DEFAULT_BOUNCE = {
229 top: true,
230 right: true,
231 bottom: true,
232 left: true,
233 }
234 const NEGATED_BOUNCE = {
235 top: false,
236 right: false,
237 bottom: false,
238 left: false,
239 }
240
241 let ret: BounceConfig
242 if (typeof bounceOptions === 'object') {
243 ret = extend(DEFAULT_BOUNCE, bounceOptions)
244 } else {
245 ret = bounceOptions ? DEFAULT_BOUNCE : NEGATED_BOUNCE
246 }
247
248 return ret
249 }
250}