public static Vector2 GetContentAnchoredPositionBounded(this ScrollRect sr, Vector2 targetAnchoredPos) { if (sr && sr.content) { var contentRtx = sr.content.transform as RectTransform; var srRtx = sr.transform as RectTransform; Bounds contentBounds = sr.GetContentBoundsInAnotherSpace((RectTransform)sr.transform); Bounds viewBounds = new Bounds(srRtx.rect.center, srRtx.rect.size); bool allowHorizontal = (sr.movementType == ScrollRect.MovementType.Unrestricted) || contentBounds.size.x > viewBounds.size.x; bool allowVertical = (sr.movementType == ScrollRect.MovementType.Unrestricted) || contentBounds.size.y > viewBounds.size.y; Vector2 offset = sr.CalculateOffsetImpl(targetAnchoredPos - contentRtx.anchoredPosition); targetAnchoredPos += offset; if (!sr.horizontal || !allowHorizontal) { targetAnchoredPos.x = contentRtx.anchoredPosition.x; } if (!sr.vertical || !allowVertical) { targetAnchoredPos.y = contentRtx.anchoredPosition.y; } return(targetAnchoredPos); } return(Vector2.zero); }
public static Vector2 GetClosestContentAnchoredPositionBounded(this ScrollRect sr, Vector2 targetAnchoredPosA, Vector2 targetAnchoredPosB) { if (sr && sr.content) { var contentRtx = sr.content.transform as RectTransform; var srRtx = sr.transform as RectTransform; Bounds contentBounds = sr.GetContentBoundsInAnotherSpace((RectTransform)sr.transform); Bounds viewBounds = new Bounds(srRtx.rect.center, srRtx.rect.size); bool allowHorizontal = (sr.movementType == ScrollRect.MovementType.Unrestricted) || contentBounds.size.x > viewBounds.size.x; bool allowVertical = (sr.movementType == ScrollRect.MovementType.Unrestricted) || contentBounds.size.y > viewBounds.size.y; Vector2 offsetA = sr.CalculateOffsetImpl(targetAnchoredPosA - contentRtx.anchoredPosition); targetAnchoredPosA += offsetA; Vector2 offsetB = sr.CalculateOffsetImpl(targetAnchoredPosB - contentRtx.anchoredPosition); targetAnchoredPosB += offsetB; if (!sr.horizontal || !allowHorizontal) { targetAnchoredPosA.x = contentRtx.anchoredPosition.x; targetAnchoredPosB.x = contentRtx.anchoredPosition.x; } if (!sr.vertical || !allowVertical) { targetAnchoredPosA.y = contentRtx.anchoredPosition.y; targetAnchoredPosB.y = contentRtx.anchoredPosition.y; } // we want to get the closest position along A<->B float t = 0f; if (!Mathf.Approximately(targetAnchoredPosA.x, targetAnchoredPosB.x)) { t = Mathf.InverseLerp(targetAnchoredPosA.x, targetAnchoredPosB.x, contentRtx.anchoredPosition.x); } else { t = Mathf.InverseLerp(targetAnchoredPosA.y, targetAnchoredPosB.y, contentRtx.anchoredPosition.y); } return(Vector2.Lerp(targetAnchoredPosA, targetAnchoredPosB, t)); } return(Vector2.zero); }