BoundingRect.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. var vec2 = require("./vector");
  2. var matrix = require("./matrix");
  3. /**
  4. * @module echarts/core/BoundingRect
  5. */
  6. var v2ApplyTransform = vec2.applyTransform;
  7. var mathMin = Math.min;
  8. var mathMax = Math.max;
  9. /**
  10. * @alias module:echarts/core/BoundingRect
  11. */
  12. function BoundingRect(x, y, width, height) {
  13. if (width < 0) {
  14. x = x + width;
  15. width = -width;
  16. }
  17. if (height < 0) {
  18. y = y + height;
  19. height = -height;
  20. }
  21. /**
  22. * @type {number}
  23. */
  24. this.x = x;
  25. /**
  26. * @type {number}
  27. */
  28. this.y = y;
  29. /**
  30. * @type {number}
  31. */
  32. this.width = width;
  33. /**
  34. * @type {number}
  35. */
  36. this.height = height;
  37. }
  38. BoundingRect.prototype = {
  39. constructor: BoundingRect,
  40. /**
  41. * @param {module:echarts/core/BoundingRect} other
  42. */
  43. union: function (other) {
  44. var x = mathMin(other.x, this.x);
  45. var y = mathMin(other.y, this.y);
  46. this.width = mathMax(other.x + other.width, this.x + this.width) - x;
  47. this.height = mathMax(other.y + other.height, this.y + this.height) - y;
  48. this.x = x;
  49. this.y = y;
  50. },
  51. /**
  52. * @param {Array.<number>} m
  53. * @methods
  54. */
  55. applyTransform: function () {
  56. var lt = [];
  57. var rb = [];
  58. var lb = [];
  59. var rt = [];
  60. return function (m) {
  61. // In case usage like this
  62. // el.getBoundingRect().applyTransform(el.transform)
  63. // And element has no transform
  64. if (!m) {
  65. return;
  66. }
  67. lt[0] = lb[0] = this.x;
  68. lt[1] = rt[1] = this.y;
  69. rb[0] = rt[0] = this.x + this.width;
  70. rb[1] = lb[1] = this.y + this.height;
  71. v2ApplyTransform(lt, lt, m);
  72. v2ApplyTransform(rb, rb, m);
  73. v2ApplyTransform(lb, lb, m);
  74. v2ApplyTransform(rt, rt, m);
  75. this.x = mathMin(lt[0], rb[0], lb[0], rt[0]);
  76. this.y = mathMin(lt[1], rb[1], lb[1], rt[1]);
  77. var maxX = mathMax(lt[0], rb[0], lb[0], rt[0]);
  78. var maxY = mathMax(lt[1], rb[1], lb[1], rt[1]);
  79. this.width = maxX - this.x;
  80. this.height = maxY - this.y;
  81. };
  82. }(),
  83. /**
  84. * Calculate matrix of transforming from self to target rect
  85. * @param {module:zrender/core/BoundingRect} b
  86. * @return {Array.<number>}
  87. */
  88. calculateTransform: function (b) {
  89. var a = this;
  90. var sx = b.width / a.width;
  91. var sy = b.height / a.height;
  92. var m = matrix.create(); // 矩阵右乘
  93. matrix.translate(m, m, [-a.x, -a.y]);
  94. matrix.scale(m, m, [sx, sy]);
  95. matrix.translate(m, m, [b.x, b.y]);
  96. return m;
  97. },
  98. /**
  99. * @param {(module:echarts/core/BoundingRect|Object)} b
  100. * @return {boolean}
  101. */
  102. intersect: function (b) {
  103. if (!b) {
  104. return false;
  105. }
  106. if (!(b instanceof BoundingRect)) {
  107. // Normalize negative width/height.
  108. b = BoundingRect.create(b);
  109. }
  110. var a = this;
  111. var ax0 = a.x;
  112. var ax1 = a.x + a.width;
  113. var ay0 = a.y;
  114. var ay1 = a.y + a.height;
  115. var bx0 = b.x;
  116. var bx1 = b.x + b.width;
  117. var by0 = b.y;
  118. var by1 = b.y + b.height;
  119. return !(ax1 < bx0 || bx1 < ax0 || ay1 < by0 || by1 < ay0);
  120. },
  121. contain: function (x, y) {
  122. var rect = this;
  123. return x >= rect.x && x <= rect.x + rect.width && y >= rect.y && y <= rect.y + rect.height;
  124. },
  125. /**
  126. * @return {module:echarts/core/BoundingRect}
  127. */
  128. clone: function () {
  129. return new BoundingRect(this.x, this.y, this.width, this.height);
  130. },
  131. /**
  132. * Copy from another rect
  133. */
  134. copy: function (other) {
  135. this.x = other.x;
  136. this.y = other.y;
  137. this.width = other.width;
  138. this.height = other.height;
  139. },
  140. plain: function () {
  141. return {
  142. x: this.x,
  143. y: this.y,
  144. width: this.width,
  145. height: this.height
  146. };
  147. }
  148. };
  149. /**
  150. * @param {Object|module:zrender/core/BoundingRect} rect
  151. * @param {number} rect.x
  152. * @param {number} rect.y
  153. * @param {number} rect.width
  154. * @param {number} rect.height
  155. * @return {module:zrender/core/BoundingRect}
  156. */
  157. BoundingRect.create = function (rect) {
  158. return new BoundingRect(rect.x, rect.y, rect.width, rect.height);
  159. };
  160. var _default = BoundingRect;
  161. module.exports = _default;