PinchGesture.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace FairyGUI
  5. {
  6. /// <summary>
  7. /// 两个指头捏或者放的手势。
  8. /// </summary>
  9. public class PinchGesture : EventDispatcher
  10. {
  11. /// <summary>
  12. ///
  13. /// </summary>
  14. public GObject host { get; private set; }
  15. /// <summary>
  16. /// 当两个手指开始呈捏手势时派发该事件。
  17. /// </summary>
  18. public EventListener onBegin { get; private set; }
  19. /// <summary>
  20. /// 当其中一个手指离开屏幕时派发该事件。
  21. /// </summary>
  22. public EventListener onEnd { get; private set; }
  23. /// <summary>
  24. /// 当手势动作时派发该事件。
  25. /// </summary>
  26. public EventListener onAction { get; private set; }
  27. /// <summary>
  28. /// 总共缩放的量。
  29. /// </summary>
  30. public float scale;
  31. /// <summary>
  32. /// 从上次通知后的改变量。
  33. /// </summary>
  34. public float delta;
  35. float _startDistance;
  36. float _lastScale;
  37. int[] _touches;
  38. bool _started;
  39. bool _touchBegan;
  40. public PinchGesture(GObject host)
  41. {
  42. this.host = host;
  43. Enable(true);
  44. _touches = new int[2];
  45. onBegin = new EventListener(this, "onPinchBegin");
  46. onEnd = new EventListener(this, "onPinchEnd");
  47. onAction = new EventListener(this, "onPinchAction");
  48. }
  49. public void Dispose()
  50. {
  51. Enable(false);
  52. host = null;
  53. }
  54. public void Enable(bool value)
  55. {
  56. if (value)
  57. {
  58. if (host == GRoot.inst)
  59. {
  60. Stage.inst.onTouchBegin.Add(__touchBegin);
  61. Stage.inst.onTouchMove.Add(__touchMove);
  62. Stage.inst.onTouchEnd.Add(__touchEnd);
  63. }
  64. else
  65. {
  66. host.onTouchBegin.Add(__touchBegin);
  67. host.onTouchMove.Add(__touchMove);
  68. host.onTouchEnd.Add(__touchEnd);
  69. }
  70. }
  71. else
  72. {
  73. _started = false;
  74. _touchBegan = false;
  75. if (host == GRoot.inst)
  76. {
  77. Stage.inst.onTouchBegin.Remove(__touchBegin);
  78. Stage.inst.onTouchMove.Remove(__touchMove);
  79. Stage.inst.onTouchEnd.Remove(__touchEnd);
  80. }
  81. else
  82. {
  83. host.onTouchBegin.Remove(__touchBegin);
  84. host.onTouchMove.Remove(__touchMove);
  85. host.onTouchEnd.Remove(__touchEnd);
  86. }
  87. }
  88. }
  89. void __touchBegin(EventContext context)
  90. {
  91. if (Stage.inst.touchCount == 2)
  92. {
  93. if (!_started && !_touchBegan)
  94. {
  95. _touchBegan = true;
  96. Stage.inst.GetAllTouch(_touches);
  97. Vector2 pt1 = host.GlobalToLocal(Stage.inst.GetTouchPosition(_touches[0]));
  98. Vector2 pt2 = host.GlobalToLocal(Stage.inst.GetTouchPosition(_touches[1]));
  99. _startDistance = Vector2.Distance(pt1, pt2);
  100. context.CaptureTouch();
  101. }
  102. }
  103. }
  104. void __touchMove(EventContext context)
  105. {
  106. if (!_touchBegan || Stage.inst.touchCount != 2)
  107. return;
  108. InputEvent evt = context.inputEvent;
  109. Vector2 pt1 = host.GlobalToLocal(Stage.inst.GetTouchPosition(_touches[0]));
  110. Vector2 pt2 = host.GlobalToLocal(Stage.inst.GetTouchPosition(_touches[1]));
  111. float dist = Vector2.Distance(pt1, pt2);
  112. if (!_started && Mathf.Abs(dist - _startDistance) > UIConfig.touchDragSensitivity)
  113. {
  114. _started = true;
  115. scale = 1;
  116. _lastScale = 1;
  117. onBegin.Call(evt);
  118. }
  119. if (_started)
  120. {
  121. float ss = dist / _startDistance;
  122. delta = ss - _lastScale;
  123. _lastScale = ss;
  124. this.scale += delta;
  125. onAction.Call(evt);
  126. }
  127. }
  128. void __touchEnd(EventContext context)
  129. {
  130. _touchBegan = false;
  131. if (_started)
  132. {
  133. _started = false;
  134. onEnd.Call(context.inputEvent);
  135. }
  136. }
  137. }
  138. }