scrollbars.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import { ExcalidrawElement } from "../element/types";
  2. import {
  3. getElementAbsoluteX1,
  4. getElementAbsoluteX2,
  5. getElementAbsoluteY1,
  6. getElementAbsoluteY2
  7. } from "../element";
  8. const SCROLLBAR_MIN_SIZE = 15;
  9. const SCROLLBAR_MARGIN = 4;
  10. export const SCROLLBAR_WIDTH = 6;
  11. export const SCROLLBAR_COLOR = "rgba(0,0,0,0.3)";
  12. export function getScrollBars(
  13. elements: ExcalidrawElement[],
  14. canvasWidth: number,
  15. canvasHeight: number,
  16. scrollX: number,
  17. scrollY: number
  18. ) {
  19. let minX = Infinity;
  20. let maxX = 0;
  21. let minY = Infinity;
  22. let maxY = 0;
  23. elements.forEach(element => {
  24. minX = Math.min(minX, getElementAbsoluteX1(element));
  25. maxX = Math.max(maxX, getElementAbsoluteX2(element));
  26. minY = Math.min(minY, getElementAbsoluteY1(element));
  27. maxY = Math.max(maxY, getElementAbsoluteY2(element));
  28. });
  29. minX += scrollX;
  30. maxX += scrollX;
  31. minY += scrollY;
  32. maxY += scrollY;
  33. const leftOverflow = Math.max(-minX, 0);
  34. const rightOverflow = Math.max(-(canvasWidth - maxX), 0);
  35. const topOverflow = Math.max(-minY, 0);
  36. const bottomOverflow = Math.max(-(canvasHeight - maxY), 0);
  37. // horizontal scrollbar
  38. let horizontalScrollBar = null;
  39. if (leftOverflow || rightOverflow) {
  40. horizontalScrollBar = {
  41. x: Math.min(
  42. leftOverflow + SCROLLBAR_MARGIN,
  43. canvasWidth - SCROLLBAR_MIN_SIZE - SCROLLBAR_MARGIN
  44. ),
  45. y: canvasHeight - SCROLLBAR_WIDTH - SCROLLBAR_MARGIN,
  46. width: Math.max(
  47. canvasWidth - rightOverflow - leftOverflow - SCROLLBAR_MARGIN * 2,
  48. SCROLLBAR_MIN_SIZE
  49. ),
  50. height: SCROLLBAR_WIDTH
  51. };
  52. }
  53. // vertical scrollbar
  54. let verticalScrollBar = null;
  55. if (topOverflow || bottomOverflow) {
  56. verticalScrollBar = {
  57. x: canvasWidth - SCROLLBAR_WIDTH - SCROLLBAR_MARGIN,
  58. y: Math.min(
  59. topOverflow + SCROLLBAR_MARGIN,
  60. canvasHeight - SCROLLBAR_MIN_SIZE - SCROLLBAR_MARGIN
  61. ),
  62. width: SCROLLBAR_WIDTH,
  63. height: Math.max(
  64. canvasHeight - bottomOverflow - topOverflow - SCROLLBAR_WIDTH * 2,
  65. SCROLLBAR_MIN_SIZE
  66. )
  67. };
  68. }
  69. return {
  70. horizontal: horizontalScrollBar,
  71. vertical: verticalScrollBar
  72. };
  73. }
  74. export function isOverScrollBars(
  75. elements: ExcalidrawElement[],
  76. x: number,
  77. y: number,
  78. canvasWidth: number,
  79. canvasHeight: number,
  80. scrollX: number,
  81. scrollY: number
  82. ) {
  83. const scrollBars = getScrollBars(
  84. elements,
  85. canvasWidth,
  86. canvasHeight,
  87. scrollX,
  88. scrollY
  89. );
  90. const [isOverHorizontalScrollBar, isOverVerticalScrollBar] = [
  91. scrollBars.horizontal,
  92. scrollBars.vertical
  93. ].map(
  94. scrollBar =>
  95. scrollBar &&
  96. scrollBar.x <= x &&
  97. x <= scrollBar.x + scrollBar.width &&
  98. scrollBar.y <= y &&
  99. y <= scrollBar.y + scrollBar.height
  100. );
  101. return {
  102. isOverHorizontalScrollBar,
  103. isOverVerticalScrollBar
  104. };
  105. }