EffectArea.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. using UnityEngine;
  2. using UnityEngine.UI;
  3. namespace Coffee.UIEffects
  4. {
  5. /// <summary>
  6. /// Area for effect.
  7. /// </summary>
  8. public enum EffectArea
  9. {
  10. RectTransform,
  11. Fit,
  12. Character,
  13. }
  14. public static class EffectAreaExtensions
  15. {
  16. static readonly Rect rectForCharacter = new Rect(0, 0, 1, 1);
  17. static readonly Vector2[] splitedCharacterPosition = {Vector2.up, Vector2.one, Vector2.right, Vector2.zero};
  18. /// <summary>
  19. /// Gets effect for area.
  20. /// </summary>
  21. public static Rect GetEffectArea(this EffectArea area, VertexHelper vh, Rect rectangle, float aspectRatio = -1)
  22. {
  23. Rect rect = default(Rect);
  24. switch (area)
  25. {
  26. case EffectArea.RectTransform:
  27. rect = rectangle;
  28. break;
  29. case EffectArea.Character:
  30. rect = rectForCharacter;
  31. break;
  32. case EffectArea.Fit:
  33. // Fit to contents.
  34. UIVertex vertex = default(UIVertex);
  35. float xMin = float.MaxValue;
  36. float yMin = float.MaxValue;
  37. float xMax = float.MinValue;
  38. float yMax = float.MinValue;
  39. for (int i = 0; i < vh.currentVertCount; i++)
  40. {
  41. vh.PopulateUIVertex(ref vertex, i);
  42. float x = vertex.position.x;
  43. float y = vertex.position.y;
  44. xMin = Mathf.Min(xMin, x);
  45. yMin = Mathf.Min(yMin, y);
  46. xMax = Mathf.Max(xMax, x);
  47. yMax = Mathf.Max(yMax, y);
  48. }
  49. rect.Set(xMin, yMin, xMax - xMin, yMax - yMin);
  50. break;
  51. default:
  52. rect = rectangle;
  53. break;
  54. }
  55. if (0 < aspectRatio)
  56. {
  57. if (rect.width < rect.height)
  58. {
  59. rect.width = rect.height * aspectRatio;
  60. }
  61. else
  62. {
  63. rect.height = rect.width / aspectRatio;
  64. }
  65. }
  66. return rect;
  67. }
  68. /// <summary>
  69. /// Gets position factor for area.
  70. /// </summary>
  71. public static void GetPositionFactor(this EffectArea area, int index, Rect rect, Vector2 position, bool isText,
  72. bool isTMPro, out float x, out float y)
  73. {
  74. if (isText && area == EffectArea.Character)
  75. {
  76. index = isTMPro ? (index + 3) % 4 : index % 4;
  77. x = splitedCharacterPosition[index].x;
  78. y = splitedCharacterPosition[index].y;
  79. }
  80. else if (area == EffectArea.Fit)
  81. {
  82. x = Mathf.Clamp01((position.x - rect.xMin) / rect.width);
  83. y = Mathf.Clamp01((position.y - rect.yMin) / rect.height);
  84. }
  85. else
  86. {
  87. x = Mathf.Clamp01(position.x / rect.width + 0.5f);
  88. y = Mathf.Clamp01(position.y / rect.height + 0.5f);
  89. }
  90. }
  91. /// <summary>
  92. /// Normalize vertex position by local matrix.
  93. /// </summary>
  94. public static void GetNormalizedFactor(this EffectArea area, int index, Matrix2x3 matrix, Vector2 position,
  95. bool isText, out Vector2 nomalizedPos)
  96. {
  97. if (isText && area == EffectArea.Character)
  98. {
  99. nomalizedPos = matrix * splitedCharacterPosition[(index + 3) % 4];
  100. }
  101. else
  102. {
  103. nomalizedPos = matrix * position;
  104. }
  105. }
  106. }
  107. }