using Gameplay.Performance; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using static UIButtonEx; public interface IPinchHandler { void OnPinchStart(); void OnPinchEnd(); void OnPinchZoom(float gapDelta); } /// /// 用于图片的双指缩放以及拖拽效果 /// public class PinchZoomModule : MonoBehaviour, IPointerUpHandler, IPointerDownHandler, IDragHandler, IBeginDragHandler, IEndDragHandler { private int firstEnterFingerID = -1; private int lastEnterFingerID = -1; private int nowFingersCount = 0; private Vector2 firstFingerPosition; private Vector2 lastFingerPosition; private float distance = 0.0f; public float zoomSpeed = 0.01f; public float minZoom = 0.5f; public float maxZoom = 2.0f; float scale = 1.0f; public float zoomGap = 0.0f; public float zoomGapDelta = 0.0f; public float zoomGapDeltaSpeed = 0.1f; float scaleFactor; private bool isPinchZooming = false; public IPinchHandler pinchHandler; public delegate void OnDragStartedHandler(PointerEventData eventData); public OnDragStartedHandler OnDragStarted; public delegate void OnDragCompletedHandler(PointerEventData eventData); public OnDragCompletedHandler OnDragCompleted; public delegate void OnDragHandler(PointerEventData eventData); public OnDragHandler OnDraging; void Awake() { if (GetComponent(typeof(IPinchHandler)) as IPinchHandler == null) { var add = gameObject.AddComponent(); add.minScale = minZoom; add.maxScale = maxZoom; add.enabled = false; } pinchHandler = GetComponent(typeof(IPinchHandler)) as IPinchHandler; } private void OnEnable() { GetComponent().enabled = true; zoomGap = 0.0f; scale = 1.0f; scaleFactor = UIRoot.Instance.RootCanvas.GetComponent().sizeDelta.x / Screen.width; } private void OnDisable() { GetComponent().enabled = false; } public void OnPointerDown(PointerEventData eventData) { nowFingersCount++; if (nowFingersCount == 1) { firstEnterFingerID = eventData.pointerId; firstFingerPosition = eventData.position; } else if (nowFingersCount == 2) { lastEnterFingerID = eventData.pointerId; lastFingerPosition = eventData.position; distance = Vector2.Distance(firstFingerPosition, lastFingerPosition); distance *= scaleFactor; isPinchZooming = true; pinchHandler?.OnPinchStart(); } } public void OnPointerUp(PointerEventData eventData) { nowFingersCount--; if (eventData.pointerId == firstEnterFingerID) { firstEnterFingerID = lastEnterFingerID; firstFingerPosition = lastFingerPosition; lastEnterFingerID = -1; if (isPinchZooming) { isPinchZooming = false; pinchHandler?.OnPinchEnd(); } } else if (eventData.pointerId == lastEnterFingerID) { lastEnterFingerID = -1; if (isPinchZooming) { isPinchZooming = false; pinchHandler?.OnPinchEnd(); } } } public void OnDrag(PointerEventData eventData) { if (isPinchZooming) { if (eventData.pointerId == firstEnterFingerID) { firstFingerPosition = eventData.position; } else if (eventData.pointerId == lastEnterFingerID) { lastFingerPosition = eventData.position; } float nowDistance = Vector2.Distance(firstFingerPosition, lastFingerPosition); nowDistance *= scaleFactor; if (distance == 0) { distance = nowDistance; return; } zoomGapDelta = nowDistance / distance; //zoomGap = zoomGapDelta * zoomSpeed; distance = nowDistance; scale = Mathf.Clamp(scale * zoomGapDelta, minZoom, maxZoom);//+ zoomGap * zoomGapDeltaSpeed pinchHandler?.OnPinchZoom(scale); } else OnDraging?.Invoke(eventData); } public void OnBeginDrag(PointerEventData eventData) { OnDragStarted?.Invoke(eventData); } public void OnEndDrag(PointerEventData eventData) { OnDragCompleted?.Invoke(eventData); } }