Adam Shaw 7 лет назад
Родитель
Сommit
3dedf2939a
1 измененных файлов с 55 добавлено и 41 удалено
  1. 55 41
      src/dnd/AutoScroller.ts

+ 55 - 41
src/dnd/AutoScroller.ts

@@ -1,7 +1,7 @@
 import { ScrollGeomCache, ElementScrollGeomCache, WindowScrollGeomCache } from '../common/scroll-geom-cache'
 
-interface Side { // rename to Edge?
-  controller: ScrollGeomCache
+interface Edge {
+  scrollCache: ScrollGeomCache
   name: 'top' | 'left' | 'right' | 'bottom'
   distance: number
 }
@@ -15,10 +15,11 @@ export default class AutoScroller {
 
   // options that can be set by caller
   isEnabled: boolean = true
-  scrollerQuery: (Window | string)[] = [ window, '.fc-scroller' ]
-  edge: number = 50
+  scrollQuery: (Window | string)[] = [ window, '.fc-scroller' ]
+  edgeThreshold: number = 50 // pixels
   maxVelocity: number = 300 // pixels per second
 
+  // internal state
   pointerScreenX: number
   pointerScreenY: number
   isAnimating: boolean = false
@@ -26,13 +27,12 @@ export default class AutoScroller {
   everMovedDown: boolean = false
   everMovedLeft: boolean = false
   everMovedRight: boolean = false
-
-  private controllers: ScrollGeomCache[] // rename to caches?
-  private msSinceRequest: number
+  scrollCaches: ScrollGeomCache[]
+  msSinceRequest: number
 
   start(pageX: number, pageY: number) {
     if (this.isEnabled) {
-      this.controllers = this.buildControllers()
+      this.scrollCaches = this.buildCaches()
 
       this.pointerScreenX = null
       this.pointerScreenY = null
@@ -73,11 +73,11 @@ export default class AutoScroller {
     if (this.isEnabled) {
       this.isAnimating = false
 
-      for (let controller of this.controllers) {
-        controller.destroy()
+      for (let scrollCache of this.scrollCaches) {
+        scrollCache.destroy()
       }
 
-      this.controllers = null
+      this.scrollCaches = null
     }
   }
 
@@ -88,14 +88,14 @@ export default class AutoScroller {
 
   private animate = () => {
     if (this.isAnimating) { // wasn't cancelled between animation calls
-      let side = this.computeBestSide(
+      let edge = this.computeBestEdge(
         this.pointerScreenX + window.scrollX,
         this.pointerScreenY + window.scrollY
       )
 
-      if (side) {
+      if (edge) {
         let now = getTime()
-        this.handleSide(side, (now - this.msSinceRequest) / 1000)
+        this.handleSide(edge, (now - this.msSinceRequest) / 1000)
         this.requestAnimation(now)
       } else {
         this.isAnimating = false
@@ -103,36 +103,38 @@ export default class AutoScroller {
     }
   }
 
-  private handleSide(side: Side, seconds: number) {
-    let { controller } = side
-    let { edge } = this
-    let invDistance = edge - side.distance
-    let velocity = (invDistance * invDistance) / (edge * edge) * this.maxVelocity * seconds // quadratic
+  private handleSide(edge: Edge, seconds: number) {
+    let { scrollCache } = edge
+    let { edgeThreshold } = this
+    let invDistance = edgeThreshold - edge.distance
+    let velocity =
+      (invDistance * invDistance) / (edgeThreshold * edgeThreshold) * // quadratic
+      this.maxVelocity * seconds
     let sign = 1
 
-    switch (side.name) {
+    switch (edge.name) {
 
       case 'left':
         sign = -1
       case 'right':
-        controller.setScrollLeft(controller.getScrollLeft() + velocity * sign)
+        scrollCache.setScrollLeft(scrollCache.getScrollLeft() + velocity * sign)
         break
 
       case 'top':
         sign = -1
       case 'bottom':
-        controller.setScrollTop(controller.getScrollTop() + velocity * sign)
+        scrollCache.setScrollTop(scrollCache.getScrollTop() + velocity * sign)
         break
     }
   }
 
   // left/top are relative to document topleft
-  private computeBestSide(left, top): Side | null {
-    let { edge } = this
-    let bestSide: Side | null = null
+  private computeBestEdge(left, top): Edge | null {
+    let { edgeThreshold } = this
+    let bestSide: Edge | null = null
 
-    for (let controller of this.controllers) {
-      let rect = controller.rect
+    for (let scrollCache of this.scrollCaches) {
+      let rect = scrollCache.rect
       let leftDist = left - rect.left
       let rightDist = rect.right - left
       let topDist = top - rect.top
@@ -141,20 +143,32 @@ export default class AutoScroller {
       // completely within the rect?
       if (leftDist >= 0 && rightDist >= 0 && topDist >= 0 && bottomDist >= 0) {
 
-        if (topDist <= edge && this.everMovedUp && controller.canScrollUp() && (!bestSide || bestSide.distance > topDist)) {
-          bestSide = { controller, name: 'top', distance: topDist }
+        if (
+          topDist <= edgeThreshold && this.everMovedUp && scrollCache.canScrollUp() &&
+          (!bestSide || bestSide.distance > topDist)
+        ) {
+          bestSide = { scrollCache, name: 'top', distance: topDist }
         }
 
-        if (bottomDist <= edge && this.everMovedDown && controller.canScrollDown() && (!bestSide || bestSide.distance > bottomDist)) {
-          bestSide = { controller, name: 'bottom', distance: bottomDist }
+        if (
+          bottomDist <= edgeThreshold && this.everMovedDown && scrollCache.canScrollDown() &&
+          (!bestSide || bestSide.distance > bottomDist)
+        ) {
+          bestSide = { scrollCache, name: 'bottom', distance: bottomDist }
         }
 
-        if (leftDist <= edge && this.everMovedLeft && controller.canScrollLeft() && (!bestSide || bestSide.distance > leftDist)) {
-          bestSide = { controller, name: 'left', distance: leftDist }
+        if (
+          leftDist <= edgeThreshold && this.everMovedLeft && scrollCache.canScrollLeft() &&
+          (!bestSide || bestSide.distance > leftDist)
+        ) {
+          bestSide = { scrollCache, name: 'left', distance: leftDist }
         }
 
-        if (rightDist <= edge && this.everMovedRight && controller.canScrollRight() && (!bestSide || bestSide.distance > rightDist)) {
-          bestSide = { controller, name: 'right', distance: rightDist }
+        if (
+          rightDist <= edgeThreshold && this.everMovedRight && scrollCache.canScrollRight() &&
+          (!bestSide || bestSide.distance > rightDist)
+        ) {
+          bestSide = { scrollCache, name: 'right', distance: rightDist }
         }
       }
     }
@@ -162,20 +176,20 @@ export default class AutoScroller {
     return bestSide
   }
 
-  private buildControllers() {
-    return this.queryScrollerEls().map((el) => {
+  private buildCaches() {
+    return this.queryScrollEls().map((el) => {
       if (el === window) {
-        return new WindowScrollGeomCache(false) // don't listen to user-generated scrolls
+        return new WindowScrollGeomCache(false) // false = don't listen to user-generated scrolls
       } else {
-        return new ElementScrollGeomCache(el, false) // don't listen to user-generated scrolls
+        return new ElementScrollGeomCache(el, false) // false = don't listen to user-generated scrolls
       }
     })
   }
 
-  private queryScrollerEls() {
+  private queryScrollEls() {
     let els = []
 
-    for (let query of this.scrollerQuery) {
+    for (let query of this.scrollQuery) {
       if (typeof query === 'object') {
         els.push(query)
       } else {