button.ts 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. import { Nullable } from "babylonjs/types";
  2. import { Vector2 } from "babylonjs/Maths/math";
  3. import { Rectangle } from "./rectangle";
  4. import { Control } from "./control";
  5. import { TextBlock } from "./textBlock";
  6. import { Image } from "./image";
  7. /**
  8. * Class used to create 2D buttons
  9. */
  10. export class Button extends Rectangle {
  11. /**
  12. * Function called to generate a pointer enter animation
  13. */
  14. public pointerEnterAnimation: () => void;
  15. /**
  16. * Function called to generate a pointer out animation
  17. */
  18. public pointerOutAnimation: () => void;
  19. /**
  20. * Function called to generate a pointer down animation
  21. */
  22. public pointerDownAnimation: () => void;
  23. /**
  24. * Function called to generate a pointer up animation
  25. */
  26. public pointerUpAnimation: () => void;
  27. private _image: Nullable<Image>;
  28. /**
  29. * Returns the image part of the button (if any)
  30. */
  31. public get image(): Nullable<Image> {
  32. return this._image;
  33. }
  34. private _textBlock: Nullable<TextBlock>;
  35. /**
  36. * Returns the image part of the button (if any)
  37. */
  38. public get textBlock(): Nullable<TextBlock> {
  39. return this._textBlock;
  40. }
  41. /**
  42. * Creates a new Button
  43. * @param name defines the name of the button
  44. */
  45. constructor(public name?: string) {
  46. super(name);
  47. this.thickness = 1;
  48. this.isPointerBlocker = true;
  49. let alphaStore: Nullable<number> = null;
  50. this.pointerEnterAnimation = () => {
  51. alphaStore = this.alpha;
  52. this.alpha -= 0.1;
  53. };
  54. this.pointerOutAnimation = () => {
  55. if (alphaStore !== null) {
  56. this.alpha = alphaStore;
  57. }
  58. };
  59. this.pointerDownAnimation = () => {
  60. this.scaleX -= 0.05;
  61. this.scaleY -= 0.05;
  62. };
  63. this.pointerUpAnimation = () => {
  64. this.scaleX += 0.05;
  65. this.scaleY += 0.05;
  66. };
  67. }
  68. protected _getTypeName(): string {
  69. return "Button";
  70. }
  71. // While being a container, the button behaves like a control.
  72. /** @hidden */
  73. public _processPicking(x: number, y: number, type: number, pointerId: number, buttonIndex: number): boolean {
  74. if (!this.isHitTestVisible || !this.isVisible || this.notRenderable) {
  75. return false;
  76. }
  77. if (!super.contains(x, y)) {
  78. return false;
  79. }
  80. this._processObservables(type, x, y, pointerId, buttonIndex);
  81. return true;
  82. }
  83. /** @hidden */
  84. public _onPointerEnter(target: Control): boolean {
  85. if (!super._onPointerEnter(target)) {
  86. return false;
  87. }
  88. if (this.pointerEnterAnimation) {
  89. this.pointerEnterAnimation();
  90. }
  91. return true;
  92. }
  93. /** @hidden */
  94. public _onPointerOut(target: Control, force = false): void {
  95. if (this.pointerOutAnimation) {
  96. this.pointerOutAnimation();
  97. }
  98. super._onPointerOut(target, force);
  99. }
  100. /** @hidden */
  101. public _onPointerDown(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number): boolean {
  102. if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
  103. return false;
  104. }
  105. if (this.pointerDownAnimation) {
  106. this.pointerDownAnimation();
  107. }
  108. return true;
  109. }
  110. /** @hidden */
  111. public _onPointerUp(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean): void {
  112. if (this.pointerUpAnimation) {
  113. this.pointerUpAnimation();
  114. }
  115. super._onPointerUp(target, coordinates, pointerId, buttonIndex, notifyClick);
  116. }
  117. // Statics
  118. /**
  119. * Creates a new button made with an image and a text
  120. * @param name defines the name of the button
  121. * @param text defines the text of the button
  122. * @param imageUrl defines the url of the image
  123. * @returns a new Button
  124. */
  125. public static CreateImageButton(name: string, text: string, imageUrl: string): Button {
  126. var result = new Button(name);
  127. // Adding text
  128. var textBlock = new TextBlock(name + "_button", text);
  129. textBlock.textWrapping = true;
  130. textBlock.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
  131. textBlock.paddingLeft = "20%";
  132. result.addControl(textBlock);
  133. // Adding image
  134. var iconImage = new Image(name + "_icon", imageUrl);
  135. iconImage.width = "20%";
  136. iconImage.stretch = Image.STRETCH_UNIFORM;
  137. iconImage.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  138. result.addControl(iconImage);
  139. // Store
  140. result._image = iconImage;
  141. result._textBlock = textBlock;
  142. return result;
  143. }
  144. /**
  145. * Creates a new button made with an image
  146. * @param name defines the name of the button
  147. * @param imageUrl defines the url of the image
  148. * @returns a new Button
  149. */
  150. public static CreateImageOnlyButton(name: string, imageUrl: string): Button {
  151. var result = new Button(name);
  152. // Adding image
  153. var iconImage = new Image(name + "_icon", imageUrl);
  154. iconImage.stretch = Image.STRETCH_FILL;
  155. iconImage.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  156. result.addControl(iconImage);
  157. // Store
  158. result._image = iconImage;
  159. return result;
  160. }
  161. /**
  162. * Creates a new button made with a text
  163. * @param name defines the name of the button
  164. * @param text defines the text of the button
  165. * @returns a new Button
  166. */
  167. public static CreateSimpleButton(name: string, text: string): Button {
  168. var result = new Button(name);
  169. // Adding text
  170. var textBlock = new TextBlock(name + "_button", text);
  171. textBlock.textWrapping = true;
  172. textBlock.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
  173. result.addControl(textBlock);
  174. // Store
  175. result._textBlock = textBlock;
  176. return result;
  177. }
  178. /**
  179. * Creates a new button made with an image and a centered text
  180. * @param name defines the name of the button
  181. * @param text defines the text of the button
  182. * @param imageUrl defines the url of the image
  183. * @returns a new Button
  184. */
  185. public static CreateImageWithCenterTextButton(name: string, text: string, imageUrl: string): Button {
  186. var result = new Button(name);
  187. // Adding image
  188. var iconImage = new Image(name + "_icon", imageUrl);
  189. iconImage.stretch = Image.STRETCH_FILL;
  190. result.addControl(iconImage);
  191. // Adding text
  192. var textBlock = new TextBlock(name + "_button", text);
  193. textBlock.textWrapping = true;
  194. textBlock.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
  195. result.addControl(textBlock);
  196. // Store
  197. result._image = iconImage;
  198. result._textBlock = textBlock;
  199. return result;
  200. }
  201. }