protected IEnumerator decelerate() { if (_isDraggingPastExtents) { yield return(_manager.StartCoroutine(springBackToBounds(2f))); } else if (_velocities.Count > 0) // bail out if we have no velocities! { // get the average velocity by summing all the velocities and dividing by count float total = 0; foreach (var v in _velocities) { total += v; } var avgVelocity = total / _velocities.Count; var elasticDecelerationModifier = 0.7f; while (!_isDragging) { var deltaMovement = avgVelocity * Time.deltaTime; var newOffset = _scrollPosition; if (layoutType == UIAbstractContainer.UILayoutType.Horizontal) { newOffset += deltaMovement; } else { newOffset -= deltaMovement; } var absVelocity = Mathf.Abs(avgVelocity); // if paging is enabled once we slow down we will snap to a page if (pagingEnabled && absVelocity < 2500) { // if we are past the extents let the handler below do the scrolling if (!_isDraggingPastExtents) { scrollToNearestPage(); } break; } // make sure we have some velocity and we are within our bounds if (absVelocity < 25) { break; } // use x for horizontal and y for vertical float lowerBounds; if (layoutType == UIAbstractContainer.UILayoutType.Horizontal) { lowerBounds = _minEdgeInset.x; } else { lowerBounds = _minEdgeInset.y; } if (newOffset < 0 && newOffset > lowerBounds) { _scrollPosition = newOffset; layoutChildren(); avgVelocity *= SCROLL_DECELERATION_MODIFIER; yield return(null); } else { _isDraggingPastExtents = true; _scrollPosition = newOffset; layoutChildren(); avgVelocity *= elasticDecelerationModifier; // we up the elasticDecelerationModifier each iteration elasticDecelerationModifier -= 0.1f; if (elasticDecelerationModifier <= 0) { break; } yield return(null); } } if (_isDraggingPastExtents) { yield return(_manager.StartCoroutine(springBackToBounds(0.9f))); } } }