Button.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import { Point } from "../spatial/Point.js";
  2. import { Rectangle } from "../spatial/Rectangle.js";
  3. export class Button {
  4. constructor(x, y, width, height, text, options = {}) {
  5. this.customDraw = null
  6. this.customClick = null;
  7. this.center = new Point(x, y);
  8. this.bounds = new Rectangle(this.center.x - width / 2, this.center.y - height / 2, width, height);
  9. this.whenHovered = () => {};
  10. this.isHovered = false;
  11. this.text = text;
  12. this.customFontDraw = null;
  13. this.customBackgroundDraw = null;
  14. this.options = Object.assign({}, this.defaultOptions(), options);
  15. }
  16. setPosition(x, y) {
  17. this.center.x = x;
  18. this.center.y = y;
  19. this.bounds.x = this.center.x - this.bounds.width / 2;
  20. this.bounds.y = this.center.y - this.bounds.height / 2;
  21. }
  22. drawFunction(fnc) {
  23. this.customDraw = fnc;
  24. }
  25. hoverFunction(fnc) {
  26. this.whenHovered = fnc;
  27. }
  28. clickFunction(fnc) {
  29. this.customClick = fnc;
  30. }
  31. fontDrawFunction(fnc) {
  32. this.customFontDraw = fnc;
  33. }
  34. backgroundDrawFunction(fnc) {
  35. this.customBackgroundDraw = fnc;
  36. }
  37. defaultOptions() {
  38. return {
  39. fontSize: 48,
  40. fontFamily: "Arial",
  41. textAlign: "center",
  42. lineWidth: 4,
  43. backgroundFillStyle: "rgba(255,255,255,0.5)",
  44. backgroundStrokeStyle: null,
  45. textFillStyle: "white",
  46. textStrokeStyle: null,
  47. };
  48. }
  49. draw(ctx, scaledCanvas) {
  50. ctx.save();
  51. ctx.translate(this.center.x, this.center.y);
  52. if(this.customDraw) {
  53. this.customDraw(ctx, scaledCanvas);
  54. } else {
  55. if(this.customBackgroundDraw) {
  56. this.customBackgroundDraw(ctx, scaledCanvas, this.options);
  57. } else {
  58. ctx.beginPath();
  59. ctx.rect(-this.bounds.width / 2, -this.bounds.height / 2, this.bounds.width, this.bounds.height);
  60. ctx.closePath();
  61. ctx.fillStyle = this.options.backgroundFillStyle;
  62. ctx.strokeStyle = this.options.backgroundStrokeStyle;
  63. if(this.isHovered) {
  64. document.body.style.cursor = "pointer";
  65. this.whenHovered(ctx, scaledCanvas);
  66. }
  67. if(this.options.backgroundFillStyle) {
  68. ctx.fill();
  69. }
  70. if(this.options.backgroundStrokeStyle) {
  71. ctx.stroke();
  72. }
  73. }
  74. if(this.customFontDraw) {
  75. this.customFontDraw(ctx, scaledCanvas, this.options);
  76. } else {
  77. ctx.font = `${this.options.fontSize}px ${this.options.fontFamily}`;
  78. ctx.textAlign = this.options.textAlign;
  79. ctx.lineWidth = this.options.lineWidth;
  80. if(this.options.textFillStyle) {
  81. ctx.fillStyle = this.options.textFillStyle;
  82. ctx.fillText(this.text, 0, this.options.fontSize * 0.375);
  83. }
  84. if(this.options.textStrokeStyle) {
  85. ctx.strokeStyle = this.options.textStrokeStyle;
  86. ctx.strokeText(this.text, 0, this.options.fontSize * 0.375);
  87. }
  88. }
  89. }
  90. ctx.restore();
  91. }
  92. mouseMove(event) {
  93. this.isHovered = false;
  94. let mousePoint = new Point(event.clientX, event.clientY);
  95. if(this.bounds.pointWithin(mousePoint)) {
  96. this.isHovered = true;
  97. }
  98. }
  99. mouseDown(event) {
  100. if(this.customClick) {
  101. let mousePoint = new Point(event.clientX, event.clientY);
  102. if(this.bounds.pointWithin(mousePoint)) {
  103. this.customClick(event);
  104. }
  105. return;
  106. }
  107. }
  108. }