Unity 对图片的操作,单指拖动,双指放大缩小

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

/// <summary>
/// 图片单指移动、双指放大缩小操作
/// </summary>
public class ImageZoomAndPan : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
    private Image targetImage; // 目标图片组件
    private Vector3 _targetScale; // 目标图片的缩放比例
    private bool isDragging = false; // 是否正在拖动
    private Vector2 initialMousePosition; // 开始拖动时的鼠标位置
    private Vector3 initialImagePosition; // 开始拖动时的图片位置

    private bool _isMove;

    private bool isPivot = false;

    private void Awake()
    {
        _isMove = false;
        targetImage = transform.GetComponent<Image>();
    }

    void Update()
    {
        if (_isMove)
        {
            if (Input.touchCount == 2)
            {
                HandleTwoFingerZoom();
            }
            else if (Input.touchCount == 1)
            {
                HandleOneFingerPan();
            }
            else if (Input.GetMouseButtonDown(0))
            {
                // 开始拖动时记录初始位置
                isDragging = true;
                initialMousePosition = Input.mousePosition;
                initialImagePosition = targetImage.transform.localPosition;
            }
            else if (Input.GetMouseButtonUp(0))
            {
                // 结束拖动
                isDragging = false;
            }
            else if (isDragging)
            {
                // 鼠标拖动移动
                Vector2 deltaPosition = (Vector2)Input.mousePosition - initialMousePosition;
                targetImage.transform.localPosition = initialImagePosition + new Vector3(deltaPosition.x, deltaPosition.y, 0);
            }
            //else if (Input.GetAxis("Mouse ScrollWheel") != 0)
            //{
            //    HandleMouseZoom();
            //}
        }
        else
        {
            _targetScale = targetImage.transform.localScale;
            isPivot = false;
        }
    }

    private void HandleTwoFingerZoom()
    {
        // 第一个点
        Touch touchZero = Input.GetTouch(0);
        // 第二个点
        Touch touchOne = Input.GetTouch(1);

        if (!isPivot)
        {
            isPivot = true;
            // 两点在屏幕上的中心点
            Vector2 centerPoint = new Vector2((touchZero.rawPosition.x + touchOne.rawPosition.x) / 2 - Screen.width / 2, (touchZero.rawPosition.y + touchOne.rawPosition.y) / 2 - Screen.height / 2);

            // 将图片的中心点改为中间
            RectTransform rectTransform = targetImage.GetComponent<RectTransform>();
            Vector2 orgPivot = rectTransform.pivot;
            Debug.Log("orgPivot: " + orgPivot);
            Vector2 originalPosition = rectTransform.position;
            rectTransform.pivot = new Vector2(0.5f, 0.5f);

            Vector2 adjustedPosition = CalculateAdjustedPosition(originalPosition, rectTransform.pivot, orgPivot);
            rectTransform.position = adjustedPosition;

            // 中心点转成相对于图片的位置
            Debug.Log("centerPoint: " + centerPoint);
            Vector2 relativeImage = centerPoint - (Vector2)(targetImage.transform.localPosition);
            Debug.Log("relativeImage: " + relativeImage);

            // 获取图片所占的范围
            Vector2 size = rectTransform.sizeDelta * rectTransform.transform.localScale.x;
            Debug.Log("size: " + size);

            // 算出在图片的哪个位置0-1之间
            float x = (relativeImage.x + size.x / 2.0f) / size.x;
            float y = (relativeImage.y + size.y / 2.0f) / size.y;

            Vector2 orgPivot2 = rectTransform.pivot;
            Vector2 originalPosition2 = rectTransform.position;
            // 将图片的中心点改成这个位置
            rectTransform.pivot = new Vector2(x, y);

            Vector2 adjustedPosition2 = CalculateAdjustedPosition(originalPosition2, rectTransform.pivot, orgPivot2);
            rectTransform.position = adjustedPosition2;
            Debug.Log(rectTransform.pivot);
        }

        // 两个点的距离
        float beginDistance = Vector3.Distance(touchZero.rawPosition, touchOne.rawPosition);
        float endDistance = Vector3.Distance(touchZero.position, touchOne.position);

        float distance = endDistance - beginDistance;
        Vector3 scale = _targetScale + new Vector3(distance / 200f, distance / 200f, 1);
        if (scale.x < 1)
        {
            scale = new Vector3(1, 1, 1);
        }
        else if (scale.x > 5)
        {
            scale = new Vector3(5, 5, 1);
        }
        targetImage.transform.localScale = scale;

        WorkorderEventDefine.ScalingCircuitDiagram.SendEventMessage(scale.x - 1);
    }

    Vector2 CalculateAdjustedPosition(Vector2 originalPosition, Vector2 newPivot, Vector2 originalPivot)
    {
        // 计算相对于原始 Pivot 的偏移
        Vector2 pivotOffset = new Vector2(newPivot.x - originalPivot.x, newPivot.y - originalPivot.y);

        RectTransform rectTransform = targetImage.GetComponent<RectTransform>();
        // 计算相对于新 Pivot 的位置
        Vector2 adjustedPosition = originalPosition + (rectTransform.sizeDelta * rectTransform.transform.localScale.x * pivotOffset);

        return adjustedPosition;
    }

    private void HandleOneFingerPan()
    {
        Touch touch = Input.GetTouch(0);
        targetImage.transform.localPosition += new Vector3(touch.deltaPosition.x, touch.deltaPosition.y);
    }

    private void HandleMouseZoom()
    {
        // 鼠标滚轮缩放
        float scrollValue = Input.GetAxis("Mouse ScrollWheel");
        Vector3 scale = _targetScale;
        scale.x += scrollValue * 1f;
        scale.y += scrollValue * 1f;
        if (scale.x < 1)
        {
            scale = new Vector3(1, 1, 1);
        }
        else if (scale.x > 5)
        {
            scale = new Vector3(5, 5, 1);
        }
        targetImage.transform.localScale = scale;

        WorkorderEventDefine.ScalingCircuitDiagram.SendEventMessage(scale.x - 1);

        _targetScale = targetImage.transform.localScale;
    }

    public void OnPointerEnter(PointerEventData eventData)
    {
        _isMove = true;
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        _isMove = false;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值