size.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. // Copyright 2007 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview A utility class for representing two-dimensional sizes.
  16. * @author brenneman@google.com (Shawn Brenneman)
  17. */
  18. goog.provide('goog.math.Size');
  19. /**
  20. * Class for representing sizes consisting of a width and height. Undefined
  21. * width and height support is deprecated and results in compiler warning.
  22. * @param {number} width Width.
  23. * @param {number} height Height.
  24. * @struct
  25. * @constructor
  26. */
  27. goog.math.Size = function(width, height) {
  28. /**
  29. * Width
  30. * @type {number}
  31. */
  32. this.width = width;
  33. /**
  34. * Height
  35. * @type {number}
  36. */
  37. this.height = height;
  38. };
  39. /**
  40. * Compares sizes for equality.
  41. * @param {goog.math.Size} a A Size.
  42. * @param {goog.math.Size} b A Size.
  43. * @return {boolean} True iff the sizes have equal widths and equal
  44. * heights, or if both are null.
  45. */
  46. goog.math.Size.equals = function(a, b) {
  47. if (a == b) {
  48. return true;
  49. }
  50. if (!a || !b) {
  51. return false;
  52. }
  53. return a.width == b.width && a.height == b.height;
  54. };
  55. /**
  56. * @return {!goog.math.Size} A new copy of the Size.
  57. */
  58. goog.math.Size.prototype.clone = function() {
  59. return new goog.math.Size(this.width, this.height);
  60. };
  61. if (goog.DEBUG) {
  62. /**
  63. * Returns a nice string representing size.
  64. * @return {string} In the form (50 x 73).
  65. * @override
  66. */
  67. goog.math.Size.prototype.toString = function() {
  68. return '(' + this.width + ' x ' + this.height + ')';
  69. };
  70. }
  71. /**
  72. * @return {number} The longer of the two dimensions in the size.
  73. */
  74. goog.math.Size.prototype.getLongest = function() {
  75. return Math.max(this.width, this.height);
  76. };
  77. /**
  78. * @return {number} The shorter of the two dimensions in the size.
  79. */
  80. goog.math.Size.prototype.getShortest = function() {
  81. return Math.min(this.width, this.height);
  82. };
  83. /**
  84. * @return {number} The area of the size (width * height).
  85. */
  86. goog.math.Size.prototype.area = function() {
  87. return this.width * this.height;
  88. };
  89. /**
  90. * @return {number} The perimeter of the size (width + height) * 2.
  91. */
  92. goog.math.Size.prototype.perimeter = function() {
  93. return (this.width + this.height) * 2;
  94. };
  95. /**
  96. * @return {number} The ratio of the size's width to its height.
  97. */
  98. goog.math.Size.prototype.aspectRatio = function() {
  99. return this.width / this.height;
  100. };
  101. /**
  102. * @return {boolean} True if the size has zero area, false if both dimensions
  103. * are non-zero numbers.
  104. */
  105. goog.math.Size.prototype.isEmpty = function() {
  106. return !this.area();
  107. };
  108. /**
  109. * Clamps the width and height parameters upward to integer values.
  110. * @return {!goog.math.Size} This size with ceil'd components.
  111. */
  112. goog.math.Size.prototype.ceil = function() {
  113. this.width = Math.ceil(this.width);
  114. this.height = Math.ceil(this.height);
  115. return this;
  116. };
  117. /**
  118. * @param {!goog.math.Size} target The target size.
  119. * @return {boolean} True if this Size is the same size or smaller than the
  120. * target size in both dimensions.
  121. */
  122. goog.math.Size.prototype.fitsInside = function(target) {
  123. return this.width <= target.width && this.height <= target.height;
  124. };
  125. /**
  126. * Clamps the width and height parameters downward to integer values.
  127. * @return {!goog.math.Size} This size with floored components.
  128. */
  129. goog.math.Size.prototype.floor = function() {
  130. this.width = Math.floor(this.width);
  131. this.height = Math.floor(this.height);
  132. return this;
  133. };
  134. /**
  135. * Rounds the width and height parameters to integer values.
  136. * @return {!goog.math.Size} This size with rounded components.
  137. */
  138. goog.math.Size.prototype.round = function() {
  139. this.width = Math.round(this.width);
  140. this.height = Math.round(this.height);
  141. return this;
  142. };
  143. /**
  144. * Scales this size by the given scale factors. The width and height are scaled
  145. * by {@code sx} and {@code opt_sy} respectively. If {@code opt_sy} is not
  146. * given, then {@code sx} is used for both the width and height.
  147. * @param {number} sx The scale factor to use for the width.
  148. * @param {number=} opt_sy The scale factor to use for the height.
  149. * @return {!goog.math.Size} This Size object after scaling.
  150. */
  151. goog.math.Size.prototype.scale = function(sx, opt_sy) {
  152. var sy = goog.isNumber(opt_sy) ? opt_sy : sx;
  153. this.width *= sx;
  154. this.height *= sy;
  155. return this;
  156. };
  157. /**
  158. * Uniformly scales the size to perfectly cover the dimensions of a given size.
  159. * If the size is already larger than the target, it will be scaled down to the
  160. * minimum size at which it still covers the entire target. The original aspect
  161. * ratio will be preserved.
  162. *
  163. * This function assumes that both Sizes contain strictly positive dimensions.
  164. * @param {!goog.math.Size} target The target size.
  165. * @return {!goog.math.Size} This Size object, after optional scaling.
  166. */
  167. goog.math.Size.prototype.scaleToCover = function(target) {
  168. var s = this.aspectRatio() <= target.aspectRatio() ?
  169. target.width / this.width :
  170. target.height / this.height;
  171. return this.scale(s);
  172. };
  173. /**
  174. * Uniformly scales the size to fit inside the dimensions of a given size. The
  175. * original aspect ratio will be preserved.
  176. *
  177. * This function assumes that both Sizes contain strictly positive dimensions.
  178. * @param {!goog.math.Size} target The target size.
  179. * @return {!goog.math.Size} This Size object, after optional scaling.
  180. */
  181. goog.math.Size.prototype.scaleToFit = function(target) {
  182. var s = this.aspectRatio() > target.aspectRatio() ?
  183. target.width / this.width :
  184. target.height / this.height;
  185. return this.scale(s);
  186. };