     }
     public func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
         if scrollView == pageScrollView {
-            guard let config = spreadConfiguration , config.spreadCount > 0 else {
-                return
-            }
-            
-            var targetSpreadIndex = centeredSpreadIndex ?? 0
-            
-            // spread hasnt changed, use velocity to inc/dec spread
-            if targetSpreadIndex == dragStartSpreadIndex {
-                if velocity.x > 0.5 {
+            scrollingVelocity = velocity
+            
+        }
+    }
+    
+    public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
+        if scrollView == pageScrollView {
+            
+            if !decelerate && !scrollView.isZoomBouncing {
+                finishDraggingByAnimatingToTarget(velocity: .zero)
+            }
+        }
+    }
+    
+    func finishDraggingByAnimatingToTarget(velocity:CGPoint) {
+        let s = self
+        let scrollView = s.pageScrollView
+        
+        if let finalContentOffset = s.calculateTargetContentOffset(visibleRect:scrollView.bounds, velocity: velocity) {
+            
+            let distance:CGFloat = abs(scrollView.contentOffset.x - finalContentOffset.x)
+            
+            
+            let defaultDuration = 0.5 // duration if there is no velocity
+            let maxDuration = 0.8
+            let minDuration = 0.3
+            // calculate the duration
+            let duration:TimeInterval = max(min(velocity.x != 0 ? TimeInterval(distance / (abs(velocity.x)*1000.0)) : defaultDuration, maxDuration), minDuration)
+            
+            let springVelocity:CGFloat = ((distance/CGFloat(duration)) / distance)
+            
+            
+            let currScrollId = s.scrollAnimIdentifier
+            
+            UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping:1, initialSpringVelocity:springVelocity, options: [.allowUserInteraction, .beginFromCurrentState], animations: {
+                
+                scrollView.setContentOffset(finalContentOffset, animated: false)
+                
+            }, completion: { [weak self] (finished) in
+                guard let s = self else { return }
+                if (finished && currScrollId == s.scrollAnimIdentifier) {
+                    s.scrollAnimIdentifier = 0
+                    s._didFinishScrolling()
+                }
+            })
+        }
+    }
+    
+    func calculateTargetContentOffset(visibleRect:CGRect, velocity:CGPoint) -> CGPoint? {
+        
+        guard let config = spreadConfiguration , config.spreadCount > 0 else {
+            return nil
+        }
+        
+        var targetSpreadIndex = centeredSpreadIndex ?? 0
+        
+        // spread hasnt changed, use velocity to inc/dec spread
+        if targetSpreadIndex == dragStartSpreadIndex {
+            if velocity.x > 0.5 {
+                targetSpreadIndex += 1
+            }
+            else if velocity.x < -0.5 {
+                targetSpreadIndex -= 1
+            }
+            else {
+                // no velocity, so se if the next or prev spreads are a certain % visible
+                //let visibleRect = scrollView.bounds
+                
+                let changeOnPercentageVisible:CGFloat = 0.1
+                
+                if visibleRect.origin.x > dragStartVisibleRect.origin.x && VersoView.calc_spreadVisibilityPercentage(spreadIndex:targetSpreadIndex+1, visibleRect: visibleRect, spreadFrames: spreadFrames) > changeOnPercentageVisible {
                     targetSpreadIndex += 1
                 }
-                else if velocity.x < -0.5 {
+                else if visibleRect.origin.x < dragStartVisibleRect.origin.x &&  VersoView.calc_spreadVisibilityPercentage(spreadIndex:targetSpreadIndex-1, visibleRect: visibleRect, spreadFrames: spreadFrames) > changeOnPercentageVisible {
                     targetSpreadIndex -= 1
                 }
-                else {
-                    // no velocity, so se if the next or prev spreads are a certain % visible
-                    let visibleRect = scrollView.bounds
-                    
-                    let changeOnPercentageVisible:CGFloat = 0.1                    
-                    
-                    if visibleRect.origin.x > dragStartVisibleRect.origin.x && VersoView.calc_spreadVisibilityPercentage(spreadIndex:targetSpreadIndex+1, visibleRect: visibleRect, spreadFrames: spreadFrames) > changeOnPercentageVisible {
-                        targetSpreadIndex += 1
-                    }
-                    else if visibleRect.origin.x < dragStartVisibleRect.origin.x &&  VersoView.calc_spreadVisibilityPercentage(spreadIndex:targetSpreadIndex-1, visibleRect: visibleRect, spreadFrames: spreadFrames) > changeOnPercentageVisible {
-                        targetSpreadIndex -= 1
-                    }
-                }
-            }
-            
-            
-            
-            // clamp targetSpread
-            targetSpreadIndex = min(max(targetSpreadIndex, 0), config.spreadCount-1)
-            
-            // generate offset for the new target spread
-            targetContentOffset.pointee = VersoView.calc_scrollOffset(spreadIndex:targetSpreadIndex, spreadFrames: spreadFrames, versoSize: versoSize)
-        }
-    }
-    
-    public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
-        if scrollView == pageScrollView {
-            if !decelerate && !scrollView.isZoomBouncing {
-                _didFinishScrolling()
-            }
-        }
+            }
+        }
+        
+        
+        
+        // clamp targetSpread
+        targetSpreadIndex = min(max(targetSpreadIndex, 0), config.spreadCount-1)
+        
+        // generate offset for the new target spread
+        return VersoView.calc_scrollOffset(spreadIndex:targetSpreadIndex, spreadFrames: spreadFrames, versoSize: versoSize)
     }
     
     

        // dont do any post-scrolling layout if the user rotated the device while scroll-animations were being performed.
        if performingLayout == false {
            
            _updateVisiblePageIndexes()
            
            _preparePageViews()

                return
            }
            
            scrollAnimIdentifier += 1
            
            scrollingVelocity = .zero
            // calculate the spreadIndex that was centered when  we started this drag
            dragStartSpreadIndex = centeredSpreadIndex ?? 0
            dragStartVisibleRect = scrollView.bounds
