Early work on Mapp, will move to Github or Gitlab if something becomes of it.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

159 lines
4.1 KiB

5 years ago
  1. import { fabric } from "fabric";
  2. fabric.perfLimitSizeTotal = 134217728;
  3. fabric.maxCacheSideLimit = 65536;
  4. export default class Board {
  5. constructor(id) {
  6. this.id = id;
  7. this.state = {a: 32};
  8. this.containerElement = document.getElementById(id);
  9. if (this.containerElement == null) {
  10. throw new Error(`Container ${this.id} not found`)
  11. }
  12. this.canvasElement = document.createElement("canvas");
  13. this.containerElement.appendChild(this.canvasElement);
  14. this.canvas = new fabric.Canvas(this.canvasElement, {backgroundColor: "#555"});
  15. this.gridGroup = new fabric.Group();
  16. this.canvas.add(this.gridGroup);
  17. this.gridOptions = {
  18. enabled: true,
  19. size: 64,
  20. hightlightInterval: 8,
  21. lineColor: "#444",
  22. highlightColor: "#333",
  23. };
  24. this.setupPanning();
  25. }
  26. destroy() {
  27. this.canvasElement.remove();
  28. }
  29. resize(width, height) {
  30. this.canvas.setHeight(height);
  31. this.canvas.setWidth(width);
  32. this.redrawGrid();
  33. this.moveGrid();
  34. this.canvas.renderAll();
  35. }
  36. redrawGrid() {
  37. const {enabled, size, hightlightInterval, lineColor, highlightColor} = this.gridOptions;
  38. for (const obj of this.gridGroup.getObjects().slice()) {
  39. this.gridGroup.remove(obj);
  40. }
  41. if (!enabled) {
  42. return;
  43. }
  44. const wCount = Math.ceil((this.canvas.getWidth() / this.canvas.getZoom()) / size) + (hightlightInterval * 2);
  45. const hCount = Math.ceil((this.canvas.getHeight() / this.canvas.getZoom()) / size) + (hightlightInterval * 2);
  46. const width2 = wCount * (size);
  47. const height2 = hCount * (size);
  48. this.gridGroup.set("left", 0);
  49. this.gridGroup.set("top", 0);
  50. this.gridGroup.set("width", width2);
  51. this.gridGroup.set("height", height2);
  52. this.gridGroup.set("selectable", false);
  53. this.gridGroup.set("hoverCursor", "default");
  54. for (let i = 0; i <= wCount; ++i) {
  55. let x = i * size;
  56. let line = new fabric.Line([x, 0, x, height2], {stroke: lineColor, strokeWidth: 2, selectable: false});
  57. if (i % hightlightInterval == 0) {
  58. line.set("stroke", highlightColor);
  59. }
  60. this.gridGroup.addWithUpdate(line);
  61. }
  62. for (let i = 0; i <= hCount; ++i) {
  63. let y = i * size;
  64. let line = new fabric.Line([0, y, width2, y], {stroke: lineColor, strokeWidth: 2, selectable: false});
  65. if (i % hightlightInterval == 0) {
  66. line.set("stroke", highlightColor);
  67. }
  68. this.gridGroup.addWithUpdate(line);
  69. }
  70. }
  71. moveGrid() {
  72. const size = this.gridOptions.size * this.gridOptions.hightlightInterval;
  73. const [x, y] = this.canvas.viewportTransform.slice(4).map(n => -n);
  74. const xOffset = (x % size) + size;
  75. const yOffset = (y % size) + size;
  76. this.gridGroup.set("left", x - xOffset);
  77. this.gridGroup.set("top", y - yOffset);
  78. this.gridGroup.setCoords();
  79. console.log(this.gridGroup);
  80. }
  81. setupPanning() {
  82. const parent = this;
  83. this.canvas.on('mouse:wheel', ({e}) => {
  84. if (e.shiftKey === false) {
  85. return;
  86. }
  87. let delta = e.deltaY;
  88. let zoom = this.canvas.getZoom();
  89. zoom = zoom - delta/1000;
  90. if (zoom > 5) {
  91. zoom = 5;
  92. }
  93. if (zoom < 0.25) {
  94. zoom = 0.25;
  95. }
  96. this.canvas.setZoom(zoom);
  97. this.redrawGrid();
  98. this.moveGrid();
  99. e.preventDefault();
  100. e.stopPropagation();
  101. })
  102. this.canvas.on('mouse:down', function(opt) {
  103. var evt = opt.e;
  104. if (evt.shiftKey === true) {
  105. this.isDragging = true;
  106. this.selection = false;
  107. this.lastPosX = evt.clientX;
  108. this.lastPosY = evt.clientY;
  109. }
  110. });
  111. this.canvas.on('mouse:move', function(opt) {
  112. if (this.isDragging) {
  113. var e = opt.e;
  114. this.viewportTransform[4] += e.clientX - this.lastPosX;
  115. this.viewportTransform[5] += e.clientY - this.lastPosY;
  116. this.requestRenderAll();
  117. this.lastPosX = e.clientX;
  118. this.lastPosY = e.clientY;
  119. parent.moveGrid();
  120. }
  121. });
  122. this.canvas.on('mouse:up', function(opt) {
  123. this.isDragging = false;
  124. this.selection = true;
  125. });
  126. }
  127. }