123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.EventSystems;
- using UnityEngine.UI;
- using TMPro;
-
-
- public class PhotoScrollView : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler
- {
- public ScrollRect smallScrollView;
- public ScrollRect largeScrollView;
- public TextMeshProUGUI pageIndicatorText;
- public float swipeThreshold = 150f; // 拖曳触发阈值
- public float snapSpeed = 10f; // 吸附速度
- public float threshold = 20f;
- private Vector2 startDragPos; // 拖曳开始位置
- private Vector2 endDragPos; // 拖曳结束位置
- private bool isDragging = false; // 是否正在拖曳
- private bool isVerticalDrag;
-
- private int currentPage = 0;
- private int totalPages = 0;
-
- private void Awake()
- {
- StartCoroutine(InitAfterMainScriptStarts());
- }
-
- public IEnumerator InitAfterMainScriptStarts()
- {
- yield return new WaitForEndOfFrame(); // 等待到當前幀結束
- // 在這裡進行 PhotoScrollView 的初始化
- totalPages = smallScrollView.content.childCount - 1;
- UpdatePageIndicator();
- }
-
- public void OnBeginDrag(PointerEventData eventData)
- {
- startDragPos = eventData.position;
- Vector2 dragDelta = eventData.delta.normalized; // 正規化的拖曳向量
- isVerticalDrag = Mathf.Abs(dragDelta.y) > Mathf.Abs(dragDelta.x); // 判断拖拽方向
- if (isVerticalDrag)
- {
- largeScrollView.OnBeginDrag(eventData);
- // 如果是垂直方向的拖拽,则禁用小的水平滚动视图
- smallScrollView.enabled = false;
- }
- else
- {
- // 如果是水平方向的拖拽,则禁用大的垂直滚动视图
- largeScrollView.enabled = false;
- }
-
- }
-
- public void OnDrag(PointerEventData eventData)
- {
- if (isVerticalDrag)
- {
- // 垂直方向的拖拽,传递事件给大的垂直滚动视图
- largeScrollView.OnDrag(eventData);
- }
- else
- {
- // 水平方向的拖拽
- if (Mathf.Abs(eventData.delta.y) > threshold)
- {
- // 如果超過閥值,則禁用小的水平滾動視圖
- smallScrollView.enabled = false;
- }
- else
- {
- // 如果沒有超過閥值,則啟用小的水平滾動視圖
- smallScrollView.enabled = true;
- }
- }
-
- }
-
- public void OnEndDrag(PointerEventData eventData)
- {
- if (isVerticalDrag)
- {
- largeScrollView.OnEndDrag(eventData);
- smallScrollView.enabled = true;
- }
- else
- {
- // 水平方向的拖拽,恢复大的垂直滚动视图
- largeScrollView.enabled = true;
-
- // 判断水平拖动的距离,根据情况显示上一页或下一页
- float dragDistance = Mathf.Abs(eventData.position.x - startDragPos.x);
- if (dragDistance > swipeThreshold)
- {
- if (eventData.position.x > startDragPos.x)
- {
- ShowPreviousPage();
- }
- else
- {
- ShowNextPage();
- }
- }
- else
- {
- SnapToNearestPage();
- }
- }
-
- }
-
- private void ShowPreviousPage()
- {
- if (currentPage > 0)
- {
- currentPage--;
- float normalizedPosition = (float)currentPage / (float)(totalPages-1 );
- StartCoroutine(SmoothScrollTo(normalizedPosition));
- UpdatePageIndicator();
- }
- }
-
- private void ShowNextPage()
- {
- if (currentPage < totalPages - 1)
- {
- currentPage++;
- float normalizedPosition = (float)currentPage / (float)(totalPages-1 );
- StartCoroutine(SmoothScrollTo(normalizedPosition));
- UpdatePageIndicator();
- }
- }
-
- private IEnumerator SmoothScrollTo(float targetNormalizedPosition)
- {
- while (Mathf.Abs(smallScrollView.horizontalNormalizedPosition - targetNormalizedPosition) > 0.01f)
- {
- smallScrollView.horizontalNormalizedPosition = Mathf.Lerp(smallScrollView.horizontalNormalizedPosition, targetNormalizedPosition, snapSpeed * Time.deltaTime);
- yield return null;
- }
- smallScrollView.horizontalNormalizedPosition = targetNormalizedPosition;
- }
-
- private void SnapToNearestPage()
- {
- float targetNormalizedPosition = (float)currentPage / (float)(totalPages-1);
- StartCoroutine(SmoothScrollTo(targetNormalizedPosition));
- }
-
- public void UpdatePageIndicator()
- {
- pageIndicatorText.text = string.Format("{0}/{1}", currentPage + 1, totalPages);
- }
- }
|