range.ts 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import { toBrandedType } from "../excalidraw/utils";
  2. import type { InclusiveRange } from "./types";
  3. /**
  4. * Create an inclusive range from the two numbers provided.
  5. *
  6. * @param start Start of the range
  7. * @param end End of the range
  8. * @returns
  9. */
  10. export function rangeInclusive(start: number, end: number): InclusiveRange {
  11. return toBrandedType<InclusiveRange>([start, end]);
  12. }
  13. /**
  14. * Turn a number pair into an inclusive range.
  15. *
  16. * @param pair The number pair to convert to an inclusive range
  17. * @returns The new inclusive range
  18. */
  19. export function rangeInclusiveFromPair(pair: [start: number, end: number]) {
  20. return toBrandedType<InclusiveRange>(pair);
  21. }
  22. /**
  23. * Given two ranges, return if the two ranges overlap with each other e.g.
  24. * [1, 3] overlaps with [2, 4] while [1, 3] does not overlap with [4, 5].
  25. *
  26. * @param param0 One of the ranges to compare
  27. * @param param1 The other range to compare against
  28. * @returns TRUE if the ranges overlap
  29. */
  30. export const rangesOverlap = (
  31. [a0, a1]: InclusiveRange,
  32. [b0, b1]: InclusiveRange,
  33. ): boolean => {
  34. if (a0 <= b0) {
  35. return a1 >= b0;
  36. }
  37. if (a0 >= b0) {
  38. return b1 >= a0;
  39. }
  40. return false;
  41. };
  42. /**
  43. * Given two ranges,return ther intersection of the two ranges if any e.g. the
  44. * intersection of [1, 3] and [2, 4] is [2, 3].
  45. *
  46. * @param param0 The first range to compare
  47. * @param param1 The second range to compare
  48. * @returns The inclusive range intersection or NULL if no intersection
  49. */
  50. export const rangeIntersection = (
  51. [a0, a1]: InclusiveRange,
  52. [b0, b1]: InclusiveRange,
  53. ): InclusiveRange | null => {
  54. const rangeStart = Math.max(a0, b0);
  55. const rangeEnd = Math.min(a1, b1);
  56. if (rangeStart <= rangeEnd) {
  57. return toBrandedType<InclusiveRange>([rangeStart, rangeEnd]);
  58. }
  59. return null;
  60. };
  61. /**
  62. * Determine if a value is inside a range.
  63. *
  64. * @param value The value to check
  65. * @param range The range
  66. * @returns
  67. */
  68. export const rangeIncludesValue = (
  69. value: number,
  70. [min, max]: InclusiveRange,
  71. ): boolean => {
  72. return value >= min && value <= max;
  73. };