-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPageScrollRect
More file actions
157 lines (130 loc) · 5.07 KB
/
PageScrollRect
File metadata and controls
157 lines (130 loc) · 5.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
//UGUI ScrollRect CenterOnChild
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using System.Collections.Generic;
using DG.Tweening;
public class PageScrollRect : MonoBehaviour, IDragHandler,IEndDragHandler{
public ScrollRect scrollRect;
public RectTransform viewPointTransform;
public RectTransform targetTransform;
public int curCenterIndex;
void OnGUI()
{
if(GUILayout.Button("DoCenter"))
{
CenterOnItem(targetTransform);
}
if(GUILayout.Button("NextPage"))
{
FlipPage(true);
}
if (GUILayout.Button("PrevPage"))
{
FlipPage(false);
}
}
void CenterChildByIndex(int index)
{
if(index>=0 && index<scrollRect.content.transform.childCount)
{
curCenterIndex = index;
CenterOnItem(scrollRect.content.transform.GetChild(index).GetComponent<RectTransform>());
}
}
public void FlipPage(bool nextPage)
{
if(nextPage)
{
CenterChildByIndex(curCenterIndex + 1);
}
else
{
CenterChildByIndex(curCenterIndex -1);
}
}
/// <summary>
/// 指定一个 item让其定位到ScrollRect中间
/// </summary>
/// <param name="target">需要定位到的目标</param>
public void CenterOnItem(RectTransform target)
{
Debug.Log("Going to center on " + target.name);
// Item is here
var itemCenterPositionInScroll = GetWorldPointInWidget(scrollRect.GetComponent<RectTransform>(), GetWidgetWorldPoint(target));
Debug.Log("Item Anchor Pos In Scroll: " + itemCenterPositionInScroll);
// But must be here
var targetPositionInScroll = GetWorldPointInWidget(scrollRect.GetComponent<RectTransform>(), GetWidgetWorldPoint(viewPointTransform));
Debug.Log("Target Anchor Pos In Scroll: " + targetPositionInScroll);
// So it has to move this distance
var difference = targetPositionInScroll - itemCenterPositionInScroll;
difference.z = 0f;
RectTransform contentTransform = scrollRect.content;
var newNormalizedPosition = new Vector2(difference.x / (contentTransform.rect.width - viewPointTransform.rect.width),
difference.y / (contentTransform.rect.height - viewPointTransform.rect.height));
newNormalizedPosition = scrollRect.normalizedPosition - newNormalizedPosition;
newNormalizedPosition.x = Mathf.Clamp01(newNormalizedPosition.x);
newNormalizedPosition.y = Mathf.Clamp01(newNormalizedPosition.y);
// scrollRect.normalizedPosition = new Vector2(scrollRect.normalizedPosition.x, newNormalizedPosition.y);
if (scrollRect.vertical)
{
DOTween.To(() => scrollRect.normalizedPosition, y => scrollRect.normalizedPosition = y, newNormalizedPosition, 1f);
}
else if(scrollRect.horizontal)
{
DOTween.To(() => scrollRect.normalizedPosition, x => scrollRect.normalizedPosition = x, newNormalizedPosition, 1f);
}
}
Vector3 GetWidgetWorldPoint(RectTransform target)
{
//pivot position + item size has to be included
var pivotOffset = new Vector3(
(0.5f - target.pivot.x) * target.rect.size.x,
(0.5f - target.pivot.y) * target.rect.size.y,
0f);
var localPosition = target.localPosition + pivotOffset;
return target.parent.TransformPoint(localPosition);
}
Vector3 GetWorldPointInWidget(RectTransform target, Vector3 worldPoint)
{
return target.InverseTransformPoint(worldPoint);
}
public void OnDrag(PointerEventData eventData)
{
//throw new System.NotImplementedException();
}
public void OnEndDrag(PointerEventData eventData)
{
//throw new System.NotImplementedException();
CenterToClosestChild(scrollRect.content);
}
void CenterToClosestChild(Transform parentChild)
{
Transform closestChild=null;
float dist=float.MaxValue;
var currentPos = GetWorldPointInWidget(scrollRect.GetComponent<RectTransform>(), GetWidgetWorldPoint(viewPointTransform));
for(int i=0;i<parentChild.childCount;i++)
{
Transform child = parentChild.GetChild(i);
RectTransform rect = child.GetComponent<RectTransform>();
var itemCenterPositionInScroll = GetWorldPointInWidget(scrollRect.GetComponent<RectTransform>(), GetWidgetWorldPoint(rect));
Debug.Log("Item Anchor Pos In Scroll: " + itemCenterPositionInScroll);
float distance =Mathf.Abs(currentPos.y - itemCenterPositionInScroll.y);
if(distance<dist)
{
dist = distance;
closestChild = child;
curCenterIndex = i;
}
}
if(closestChild)
{
CenterOnItem(closestChild.GetComponent<RectTransform>());
}
else
{
Debug.LogError("Got nothing to center on ");
}
}
}