void Update() { if (_Adapter == null) { return; } float pullAmount01 = 0f; var piv = _SrollbarPivotOnInit; int sign = 1; if (_Adapter.GetContentSizeToViewportRatio() > 1d) { var insetStart = _Adapter.ContentVirtualInsetFromViewportStart; if (insetStart > 0d) { if (_Adapter.IsHorizontal) { pullAmount01 = (float)(insetStart / _Adapter.BaseParameters.Viewport.rect.width); piv.x = 0f; } else { pullAmount01 = (float)(insetStart / _Adapter.BaseParameters.Viewport.rect.height); piv.y = 1f; } } else { var insetEnd = _Adapter.ContentVirtualInsetFromViewportEnd; if (insetEnd > 0d) { sign = -1; pullAmount01 = (float)(insetEnd / _Adapter.GetContentSize()); if (_Adapter.IsHorizontal) { pullAmount01 = (float)(insetEnd / _Adapter.BaseParameters.Viewport.rect.width); piv.x = 1f; } else { pullAmount01 = (float)(insetEnd / _Adapter.BaseParameters.Viewport.rect.height); piv.y = 0f; } } } } if (_HandleRT.pivot != piv) { _HandleRT.pivot = piv; } var euler = _HandleRT.localEulerAngles; // Multiplying argument by _Speed to speed up sine function growth euler.z = Mathf.Sin(pullAmount01 * _RotationSensivity * Mathf.PI) * _DegreesOfFreedom * sign; _HandleRT.localEulerAngles = euler; }
internal void StartSnappingIfNeeded() { if (!_StartCalled) { return; } // Disabling the script should make it unoperable if (!enabled) { return; } if (_SnappingDoneAndEndSnappingEventPending) { OnSnappingEndedOrCancelled(); return; } if (_Adapter == null || !_Adapter.IsInitialized) { return; } // Commented: this now works //if (_Adapter.GetItemsCount() > OSAConst.MAX_ITEMS_TO_SUPPORT_SMOOTH_SCROLL_AND_ITEM_RESIZING) // return; // Initializing it here, because in Start the adapter may not be initialized if (_GetSignedAbstractSpeed == null) { // _ScrollRect.velocity doesn't reflect <curNormPos-prevNormPos>, as it would be expected, but the opposite of that (opposite sign) // Returning: negative, if towards end; positive, else. if (_Adapter.BaseParameters.IsHorizontal) { _GetSignedAbstractSpeed = () => _Adapter.Velocity[0]; } else { _GetSignedAbstractSpeed = () => - _Adapter.Velocity[1]; } } //Debug.Log("SnappingInProgress=" + SnappingInProgress + ", _SnapNeeded=" + _SnapNeeded + ", magnitude=" + _ScrollRect.velocity.magnitude + ", IsPointerDraggingOnScrollRect=" + IsPointerDraggingOnScrollRect + ", IsPointerDraggingOnScrollbar=" + IsPointerDraggingOnScrollbar); float signedSpeed = _GetSignedAbstractSpeed(); float speed = Mathf.Abs(signedSpeed); if (SnappingInProgress || !_SnapNeeded || speed >= snapWhenSpeedFallsBelow || IsPointerDraggingOnScrollRect || IsPointerDraggingOnScrollbar) { return; } if (_Adapter.ContentVirtualInsetFromViewportStart >= 0d || _Adapter.ContentVirtualInsetFromViewportEnd >= 0d) // Content is at end => don't force any snapping { return; } float distanceToTarget; var middle = GetMiddleVH(out distanceToTarget); //if (middle == null) // Debug.Log("null"); if (middle == null) { return; } _SnapNeeded = false; if (distanceToTarget <= snapAllowedError) { return; } //Debug.Log(middle.ItemIndex); int indexToSnapTo = middle.ItemIndex; bool snapToNextOnly = speed >= minSpeedToAllowSnapToNext // Not allowed to skip neighbors. Snapping to neigbors is only allowed if the current middle is the previous middle && indexToSnapTo == _LastSnappedItemIndex; if (snapToNextOnly) { bool loopingEnabled = _Adapter.BaseParameters.effects.loopItems && _Adapter.GetContentSizeToViewportRatio() > 1d; int count = _Adapter.GetItemsCount(); if (signedSpeed < 0) // going towards end => snap to bigger indexInView { if (indexToSnapTo == count - 1 && !loopingEnabled) { return; } indexToSnapTo = (indexToSnapTo + 1) % count; } else // going towards start => snap to smaller indexInView { if (indexToSnapTo == 0 && !loopingEnabled) { return; } indexToSnapTo = ((indexToSnapTo + count) /*adding count to prevent a negative dividend*/ - 1) % count; } } else { indexToSnapTo = middle.ItemIndex; } //Debug.Log("start: " + s); _SnappingCancelled = false; bool continuteAnimation; bool cancelledOrEnded = false; // used to check if the scroll was cancelled immediately after calling SmoothScrollTo (i.e. without first setting SnappingInProgress = true) _Adapter.SmoothScrollTo( indexToSnapTo, snapDuration, viewportSnapPivot01, itemSnapPivot01, progress => { continuteAnimation = true; if (progress == 1f || _SnappingCancelled || IsPointerDraggingOnScrollRect || IsPointerDraggingOnScrollbar) // done. last iteration { cancelledOrEnded = true; continuteAnimation = false; //Debug.Log("received end callback: SnappingInProgress=" + SnappingInProgress); if (SnappingInProgress) { _LastSnappedItemIndex = indexToSnapTo; SnappingInProgress = false; _SnappingDoneAndEndSnappingEventPending = true; } } // If the items were refreshed while the snap animation was playing or if the user touched the scrollview, don't continue; return(continuteAnimation); }, true ); // The scroll was cancelled immediately after calling SmoothScrollTo => cancel if (cancelledOrEnded) { return; } SnappingInProgress = true; //always true, because we're overriding the previous scroll if (SnappingInProgress) { OnSnappingStarted(); } }