valueAndUnit.ts 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. import { AdvancedDynamicTexture } from "./advancedDynamicTexture";
  2. /**
  3. * Class used to specific a value and its associated unit
  4. */
  5. export class ValueAndUnit {
  6. private _value = 1;
  7. private _originalUnit: number;
  8. /**
  9. * Gets or sets a value indicating that this value will not scale accordingly with adaptive scaling property
  10. * @see https://doc.babylonjs.com/how_to/gui#adaptive-scaling
  11. */
  12. public ignoreAdaptiveScaling = false;
  13. /**
  14. * Creates a new ValueAndUnit
  15. * @param value defines the value to store
  16. * @param unit defines the unit to store
  17. * @param negativeValueAllowed defines a boolean indicating if the value can be negative
  18. */
  19. public constructor(value: number,
  20. /** defines the unit to store */
  21. public unit = ValueAndUnit.UNITMODE_PIXEL,
  22. /** defines a boolean indicating if the value can be negative */
  23. public negativeValueAllowed = true) {
  24. this._value = value;
  25. this._originalUnit = unit;
  26. }
  27. /** Gets a boolean indicating if the value is a percentage */
  28. public get isPercentage(): boolean {
  29. return this.unit === ValueAndUnit.UNITMODE_PERCENTAGE;
  30. }
  31. /** Gets a boolean indicating if the value is store as pixel */
  32. public get isPixel(): boolean {
  33. return this.unit === ValueAndUnit.UNITMODE_PIXEL;
  34. }
  35. /** Gets direct internal value */
  36. public get internalValue(): number {
  37. return this._value;
  38. }
  39. /**
  40. * Gets value as pixel
  41. * @param host defines the root host
  42. * @param refValue defines the reference value for percentages
  43. * @returns the value as pixel
  44. */
  45. public getValueInPixel(host: AdvancedDynamicTexture, refValue: number): number {
  46. if (this.isPixel) {
  47. return this.getValue(host);
  48. }
  49. return this.getValue(host) * refValue;
  50. }
  51. /**
  52. * Update the current value and unit. This should be done cautiously as the GUi won't be marked as dirty with this function.
  53. * @param value defines the value to store
  54. * @param unit defines the unit to store
  55. * @returns the current ValueAndUnit
  56. */
  57. public updateInPlace(value: number, unit = ValueAndUnit.UNITMODE_PIXEL): ValueAndUnit {
  58. this._value = value;
  59. this.unit = unit;
  60. return this;
  61. }
  62. /**
  63. * Gets the value accordingly to its unit
  64. * @param host defines the root host
  65. * @returns the value
  66. */
  67. public getValue(host: AdvancedDynamicTexture): number {
  68. if (host && !this.ignoreAdaptiveScaling && this.unit !== ValueAndUnit.UNITMODE_PERCENTAGE) {
  69. var width: number = 0;
  70. var height: number = 0;
  71. if (host.idealWidth) {
  72. width = (this._value * host.getSize().width) / host.idealWidth;
  73. }
  74. if (host.idealHeight) {
  75. height = (this._value * host.getSize().height) / host.idealHeight;
  76. }
  77. if (host.useSmallestIdeal && host.idealWidth && host.idealHeight) {
  78. return window.innerWidth < window.innerHeight ? width : height;
  79. }
  80. if (host.idealWidth) { // horizontal
  81. return width;
  82. }
  83. if (host.idealHeight) { // vertical
  84. return height;
  85. }
  86. }
  87. return this._value;
  88. }
  89. /**
  90. * Gets a string representation of the value
  91. * @param host defines the root host
  92. * @param decimals defines an optional number of decimals to display
  93. * @returns a string
  94. */
  95. public toString(host: AdvancedDynamicTexture, decimals?: number): string {
  96. switch (this.unit) {
  97. case ValueAndUnit.UNITMODE_PERCENTAGE:
  98. let percentage = this.getValue(host) * 100;
  99. return (decimals ? percentage.toFixed(decimals) : percentage) + "%";
  100. case ValueAndUnit.UNITMODE_PIXEL:
  101. let pixels = this.getValue(host);
  102. return (decimals ? pixels.toFixed(decimals) : pixels) + "px";
  103. }
  104. return this.unit.toString();
  105. }
  106. /**
  107. * Store a value parsed from a string
  108. * @param source defines the source string
  109. * @returns true if the value was successfully parsed
  110. */
  111. public fromString(source: string | number): boolean {
  112. var match = ValueAndUnit._Regex.exec(source.toString());
  113. if (!match || match.length === 0) {
  114. return false;
  115. }
  116. var sourceValue = parseFloat(match[1]);
  117. var sourceUnit = this._originalUnit;
  118. if (!this.negativeValueAllowed) {
  119. if (sourceValue < 0) {
  120. sourceValue = 0;
  121. }
  122. }
  123. if (match.length === 4) {
  124. switch (match[3]) {
  125. case "px":
  126. sourceUnit = ValueAndUnit.UNITMODE_PIXEL;
  127. break;
  128. case "%":
  129. sourceUnit = ValueAndUnit.UNITMODE_PERCENTAGE;
  130. sourceValue /= 100.0;
  131. break;
  132. }
  133. }
  134. if (sourceValue === this._value && sourceUnit === this.unit) {
  135. return false;
  136. }
  137. this._value = sourceValue;
  138. this.unit = sourceUnit;
  139. return true;
  140. }
  141. // Static
  142. private static _Regex = /(^-?\d*(\.\d+)?)(%|px)?/;
  143. private static _UNITMODE_PERCENTAGE = 0;
  144. private static _UNITMODE_PIXEL = 1;
  145. /** UNITMODE_PERCENTAGE */
  146. public static get UNITMODE_PERCENTAGE(): number {
  147. return ValueAndUnit._UNITMODE_PERCENTAGE;
  148. }
  149. /** UNITMODE_PIXEL */
  150. public static get UNITMODE_PIXEL(): number {
  151. return ValueAndUnit._UNITMODE_PIXEL;
  152. }
  153. }