@@ -25,8 +25,16 @@ function vtkMouseRangeManipulator(publicAPI, model) {
25
25
function processDelta ( listener , delta ) {
26
26
const oldValue = listener . getValue ( ) ;
27
27
28
- // Apply scale and cached delta to current delta
29
- const newDelta = delta * listener . scale + incrementalDelta . get ( listener ) ;
28
+ // if exponential scroll is enabled, we raise our scale to the
29
+ // exponent of the net delta of the interaction. The further away
30
+ // the user's cursor is from the start of the interaction, the more
31
+ // their movements will effect the value.
32
+ const scalingFactor = listener . exponentialScroll
33
+ ? listener . scale ** Math . log2 ( Math . abs ( model . interactionNetDelta ) + 2 )
34
+ : listener . scale ;
35
+
36
+ const newDelta = delta * scalingFactor + incrementalDelta . get ( listener ) ;
37
+
30
38
let value = oldValue + newDelta ;
31
39
32
40
// Compute new value based on step
@@ -67,7 +75,8 @@ function vtkMouseRangeManipulator(publicAPI, model) {
67
75
step ,
68
76
getValue ,
69
77
setValue ,
70
- scale = 1
78
+ scale = 1 ,
79
+ exponentialScroll = false
71
80
) => {
72
81
const getFn = Number . isFinite ( getValue ) ? ( ) => getValue : getValue ;
73
82
model . horizontalListener = {
@@ -77,6 +86,7 @@ function vtkMouseRangeManipulator(publicAPI, model) {
77
86
getValue : getFn ,
78
87
setValue,
79
88
scale,
89
+ exponentialScroll,
80
90
} ;
81
91
incrementalDelta . set ( model . horizontalListener , 0 ) ;
82
92
publicAPI . modified ( ) ;
@@ -89,7 +99,8 @@ function vtkMouseRangeManipulator(publicAPI, model) {
89
99
step ,
90
100
getValue ,
91
101
setValue ,
92
- scale = 1
102
+ scale = 1 ,
103
+ exponentialScroll = false
93
104
) => {
94
105
const getFn = Number . isFinite ( getValue ) ? ( ) => getValue : getValue ;
95
106
model . verticalListener = {
@@ -99,6 +110,7 @@ function vtkMouseRangeManipulator(publicAPI, model) {
99
110
getValue : getFn ,
100
111
setValue,
101
112
scale,
113
+ exponentialScroll,
102
114
} ;
103
115
incrementalDelta . set ( model . verticalListener , 0 ) ;
104
116
publicAPI . modified ( ) ;
@@ -111,10 +123,19 @@ function vtkMouseRangeManipulator(publicAPI, model) {
111
123
step ,
112
124
getValue ,
113
125
setValue ,
114
- scale = 1
126
+ scale = 1 ,
127
+ exponentialScroll = false
115
128
) => {
116
129
const getFn = Number . isFinite ( getValue ) ? ( ) => getValue : getValue ;
117
- model . scrollListener = { min, max, step, getValue : getFn , setValue, scale } ;
130
+ model . scrollListener = {
131
+ min,
132
+ max,
133
+ step,
134
+ getValue : getFn ,
135
+ setValue,
136
+ scale,
137
+ exponentialScroll,
138
+ } ;
118
139
incrementalDelta . set ( model . scrollListener , 0 ) ;
119
140
publicAPI . modified ( ) ;
120
141
} ;
@@ -156,6 +177,7 @@ function vtkMouseRangeManipulator(publicAPI, model) {
156
177
//-------------------------------------------------------------------------
157
178
publicAPI . onButtonDown = ( interactor , renderer , position ) => {
158
179
model . previousPosition = position ;
180
+ model . interactionNetDelta = 0 ;
159
181
const glRenderWindow = interactor . getView ( ) ;
160
182
// Ratio is the dom size vs renderwindow size
161
183
const ratio =
@@ -232,12 +254,14 @@ function vtkMouseRangeManipulator(publicAPI, model) {
232
254
const dxNorm =
233
255
( position . x - model . previousPosition . x ) / model . containerSize [ 0 ] ;
234
256
const dx = scaleDeltaToRange ( model . horizontalListener , dxNorm ) ;
257
+ model . interactionNetDelta += dx ;
235
258
processDelta ( model . horizontalListener , dx ) ;
236
259
}
237
260
if ( model . verticalListener ) {
238
261
const dyNorm =
239
262
( position . y - model . previousPosition . y ) / model . containerSize [ 1 ] ;
240
263
const dy = scaleDeltaToRange ( model . verticalListener , dyNorm ) ;
264
+ model . interactionNetDelta += dy ;
241
265
processDelta ( model . verticalListener , dy ) ;
242
266
}
243
267
@@ -249,9 +273,14 @@ function vtkMouseRangeManipulator(publicAPI, model) {
249
273
if ( ! model . scrollListener || ! delta ) {
250
274
return ;
251
275
}
276
+ model . interactionNetDelta += delta * model . scrollListener . step ;
252
277
processDelta ( model . scrollListener , delta * model . scrollListener . step ) ;
253
278
} ;
254
- publicAPI . onStartScroll = publicAPI . onScroll ;
279
+
280
+ publicAPI . onStartScroll = ( payload ) => {
281
+ model . interactionNetDelta = 0 ;
282
+ publicAPI . onScroll ( payload ) ;
283
+ } ;
255
284
}
256
285
257
286
// ----------------------------------------------------------------------------
0 commit comments