using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; [RequireComponent(typeof (RawImage))] [AddComponentMenu("UI/Pinch and Zoom Image")] public class PinchZoomImage : MonoBehaviour ,IDragHandler, IPointerDownHandler, IPointerUpHandler { [Range(0, 0.1f)] public float posDuration = 0.05f; [Range(0, 0.1f)] public float rotDuration = 0.05f; [Range(0, 0.1f)] public float scaleDuration = 0.05f; public bool isRotation = true; public bool isScale = true; private bool simulatedByMouse = false; public void SetPosition(Vector3 position) { target_pos = position; } public Vector3 GetPosition() { return target_pos; } //IDragHandler public void OnDrag(PointerEventData eventData) { //Debug.Log("OnDrag"+Time.time); pointers[eventData.pointerId] = eventData; } //IPointerDownHandler public void OnPointerDown(PointerEventData eventData) { //Debug.Log("OnPointerDown" + Time.time); if (simulatedByMouse && pointers.Count == 0) { Vector3 pos = Camera.main.WorldToScreenPoint(transform.position); PointerEventData p = new PointerEventData(EventSystem.current); p.position = new Vector2(pos.x, pos.y); p.pointerId = -2; pointers.Add(p.pointerId, p); } pointers.Add(eventData.pointerId, eventData); ResetAnchor(); transform.SetSiblingIndex(transform.childCount - 1); } //IPointerUpHandler public void OnPointerUp(PointerEventData eventData) { //Debug.Log("OnPointerUp" + Time.time); pointers.Remove(eventData.pointerId); if (simulatedByMouse && pointers.Count == 1) pointers.Remove(-2); if (pointers.Count > 0) ResetAnchor(); } List GetPositionList() { List < Vector2 > result = new List(); foreach (int key in pointers.Keys) result.Add(pointers[key].position); return result; } private static Vector2 Average(List list) { Vector2 sum = Vector2.zero; foreach (Vector2 v in list) sum += v; return sum / list.Count; } private static List Substract(List list, Vector2 pos) { List result = new List(); foreach (Vector2 v in list) result.Add(v - pos); return result; } private static float AverageMagnitude(List list) { float sum = 0.0f; foreach (Vector2 v in list) sum += v.magnitude; return sum / list.Count; } Vector2 getAveragePosition() { Vector2 sum = Vector2.zero; foreach (int key in pointers.Keys) sum += pointers[key].position; return sum / pointers.Count; } float getAverageDistance(Dictionary directions) { float sum = 0.0f; foreach (int key in directions.Keys) sum += directions[key].magnitude; return sum / pointers.Count; } Dictionary getDirection(Vector2 pos) { Dictionary result = new Dictionary(); foreach (int key in pointers.Keys) { result.Add(key,pointers[key].position - pos); } return result; } // Use this for initialization void Start () { target_pos = transform.localPosition; target_q = transform.localRotation; target_scale = transform.localScale.x; } // Update is called once per frame void Update () { if (Input.GetKey(KeyCode.Escape)) Application.Quit(); if (Time.deltaTime == 0) return; if (pointers.Count > 0) { List pos_list = GetPositionList(); Vector2 pos = Average(pos_list); List diff_list = Substract(pos_list, pos); float magnitude = AverageMagnitude(diff_list); {//translation Vector3 diff_pos = pos - pre_pos; target_pos += diff_pos; vel += (diff_pos / Time.deltaTime - vel) * Mathf.Clamp01(Time.deltaTime / 0.2f); pre_pos = pos; } if (pointers.Count > 1) { if (isScale) {//Scale target_scale = target_scale * magnitude / pre_magnitude; pre_magnitude = magnitude; } if (isRotation) {//rotation Quaternion average = new Quaternion(0, 0, 0, 0); for(int i=0;i pos_list = GetPositionList(); //target_pos = transform.localPosition; pre_pos = Average(pos_list); pre_diff_list = Substract(pos_list, pre_pos); pre_magnitude = AverageMagnitude(pre_diff_list); } private Dictionary pointers = new Dictionary(); private Vector3 target_pos; private Quaternion target_q; private float target_scale; private Vector2 pre_pos; private List pre_diff_list; private float pre_magnitude; private Vector3 vel = Vector3.zero; }