ScrollView双指缩放

ScrollView双指缩放

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

//参考自 https://blog.csdn.net/qq_39162826/article/details/108587752
public class TouchScale : MonoBehaviour
{
    RectTransform contentRect;
    RectTransform scrollRect;
    public ScrollRect scroll;
    float scrollW;
    float scrollH;
    float contentW;
    float contentH;
    void Start()
    {
        scrollRect = scroll.GetComponent<RectTransform>();
        contentRect = scroll.content;
        scrollW = scrollRect.sizeDelta.x;
        scrollH = scrollRect.sizeDelta.y;
        contentW = contentRect.sizeDelta.x;
        contentH = contentRect.sizeDelta.y;
        float scaleWMin = scrollW / contentW;
        float scaleHMin= scrollH / contentH;
        scaleRange.x = scaleWMin > scaleHMin ? scaleWMin : scaleHMin;
    }
    float baseDistance;
    float baseScale;
     Vector2 scaleRange = new Vector2(0.675f, 1);

    Vector2 midPos;
    Vector3 contentPos;
    Vector3 baseDisV3;
    void Update()
    {
        if (Input.touchCount > 1)
        {
            scroll.enabled = false;
            Touch t1 = Input.touches[0];
            Touch t2 = Input.touches[1];
            if (t1.phase == TouchPhase.Canceled || t2.phase == TouchPhase.Canceled || t1.phase == TouchPhase.Ended || t2.phase == TouchPhase.Ended)
            {
                return;
            }
            bool isNew =t1.phase==TouchPhase.Began|| t2.phase == TouchPhase.Began;

            if (isNew)//两个触控点中任意一个刚按下时
            {
                //的焦点位置
                Vector3 midPos = new Vector3((Camera.main.ScreenToWorldPoint(t1.position).x + Camera.main.ScreenToWorldPoint(t2.position).x) / 2, (Camera.main.ScreenToWorldPoint(t1.position).y + Camera.main.ScreenToWorldPoint(t2.position).y) / 2, 0);
                //的界面初始位置 也是它的中心位置
                contentPos = contentRect.position;
                //的焦点到界面中心位置的初始向量
                baseDisV3 = midPos - contentPos; 
                //的两个触控点的初始距离
                baseDistance = Vector2.Distance(t1.position, t2.position);
                //的界面的初始缩放值
                baseScale = contentRect.localScale.x;
            }
            else
            {
                //两个触控点 任意一个移动时
                if (t1.phase == TouchPhase.Moved || t2.phase == TouchPhase.Moved)
                {
                    //当前的两个触控点的距离
                    float nowDistance = Vector2.Distance(t1.position, t2.position);
                    //根据两个触控点的当前距离和初始距离的比值等比例改变缩放值
                    float scale = baseScale* nowDistance / baseDistance;
                    //确保缩放值在限制范围内
                    scale = Mathf.Clamp(scale, scaleRange.x, scaleRange.y);
                    //设置缩放值
                    contentRect.localScale = Vector3.one * scale;
                    //由于缩放导致的焦点到界面中心位置的向量disV3变化了 获得disV3变化的值
                    Vector3 disV3Change = baseDisV3 * (scale / baseScale - 1);

                    #region 根据content的缩放获取当前的xy轴移动范围
                    float scaleWidth = contentW * scale;
                    float scaleHeight = contentH * scale;
                    

                    float wL = Mathf.Abs((scaleWidth - scrollW) / 2);
                    float hL = Mathf.Abs((scaleHeight - scrollH) / 2);
                    #endregion

                    //通过移动content位置来保证焦点的相对位置不变
                    float x = contentPos.x - disV3Change.x;
                    float y = contentPos.y - disV3Change.y;
                    contentRect.position = new Vector3(x, y, 0);
                    //移动完content位置后校验一下 来保证在限制范围内
                    contentRect.localPosition = new Vector3(Mathf.Clamp(contentRect.localPosition.x, -wL, wL),
                        Mathf.Clamp(contentRect.localPosition.y, -hL, hL),0);
                }
            }
        }
        else
        {
            scroll.enabled = true;
        }
    }
}

测试工程下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值