UGUI滑頁組件

如何用UGUI實現滑頁效果

效果圖如下:
這裏寫圖片描述

核心原理
在滑動結束的時刻,重新計算ScrollRect的normalizePosition,使得目標頁顯示在窗口正中。

數學推理

  • 假定ScrollRect的NormalizePosition爲n,子控件數目爲c
  • 當c=2時,要麼顯示第一頁,要麼顯示第二頁,n的取值爲0(n<=0.5)或1(n>0.5)
  • 當c=3時,第一頁n=0,第二頁n=0.5,第三頁n=1,滑動中的n假設在(0, 0.5]區間,如果少於區間中位數,則置爲區間mix,否則置爲maz
  • 可以看出,子控件數目c決定了區間的數目,只要把當前的滑動值n劃分到某一個區間,在判斷它靠近區間左邊或是右邊,就能計算出最後的目標值。

核心代碼片段

    private float CalDragNormalizeValue() {
        float normalizeValue = scrollRect.normalizedPosition.x;
        int low =0, high=0;
        float d = 1.0f;
        CalRange(ref low, ref high, ref d);
        normalizeValue = Near(normalizeValue, low * d, high * d);
        normalizeValue = Mathf.Clamp(normalizeValue, 0f, 1f);
        return normalizeValue;
    }

    private float CalClickNormalizeValue(int index) {
        float normalizeValue = 0f;
        if (content.childCount > 1) {
            normalizeValue = 1.0f * index / (content.childCount - 1);
        }
        scrollRect.normalizedPosition = new Vector2(normalizeValue, normalizeValue);
        return normalizeValue;
    }

    private void CalRange(ref int low, ref int high, ref float d) {
        if (content.childCount <= 1) {
            low = 0;
            high = 0;
            d = 1f;
            return;
        }

        float normalizeValue = scrollRect.normalizedPosition.x;
        d = 1.0f / (content.childCount - 1);
        low =(int) Mathf.Floor(normalizeValue / d);
        high = low + 1;
    }

    private float Near(float value, float a, float b) {
        float mid = (a+b)/2;
        return value <= mid ? a : b;
    }

Github工程地址
SlidePage

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章