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); }
static Vector3 CalculateOffsetImpl(this ScrollRect sr, Vector2 delta) { if (sr) { Vector3 offset = Vector3.zero; if (sr.movementType == ScrollRect.MovementType.Unrestricted) { return(offset); } var srRtx = sr.transform as RectTransform; Bounds srBounds = new Bounds(srRtx.rect.center, srRtx.rect.size); Bounds contentBounds = sr.GetContentBoundsInAnotherSpace((RectTransform)sr.transform); bool allowHorizontal = (sr.movementType == ScrollRect.MovementType.Unrestricted) || contentBounds.size.x > srBounds.size.x; bool allowVertical = (sr.movementType == ScrollRect.MovementType.Unrestricted) || contentBounds.size.y > srBounds.size.y; Vector2 contentBoundsTranslatedMin = contentBounds.min; Vector2 contentBoundsTranslatedMax = contentBounds.max; if (sr.horizontal) { contentBoundsTranslatedMin.x += delta.x; contentBoundsTranslatedMax.x += delta.x; if (!allowHorizontal || contentBoundsTranslatedMin.x > srBounds.min.x) { offset.x = srBounds.min.x - contentBoundsTranslatedMin.x; } else if (contentBoundsTranslatedMax.x < srBounds.max.x) { offset.x = srBounds.max.x - contentBoundsTranslatedMax.x; } } if (sr.vertical) { contentBoundsTranslatedMin.y += delta.y; contentBoundsTranslatedMax.y += delta.y; if (!allowVertical || contentBoundsTranslatedMax.y < srBounds.max.y) { offset.y = srBounds.max.y - contentBoundsTranslatedMax.y; } else if (contentBoundsTranslatedMin.y > srBounds.min.y) { offset.y = srBounds.min.y - contentBoundsTranslatedMin.y; } } return(offset); } return(Vector3.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); }