selection.ts 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import { ExcalidrawElement } from "../element/types";
  2. import { getElementAbsoluteCoords } from "../element";
  3. export function getElementsWithinSelection(
  4. elements: readonly ExcalidrawElement[],
  5. selection: ExcalidrawElement,
  6. ) {
  7. const [
  8. selectionX1,
  9. selectionY1,
  10. selectionX2,
  11. selectionY2,
  12. ] = getElementAbsoluteCoords(selection);
  13. return elements.filter(element => {
  14. const [
  15. elementX1,
  16. elementY1,
  17. elementX2,
  18. elementY2,
  19. ] = getElementAbsoluteCoords(element);
  20. return (
  21. element.type !== "selection" &&
  22. selectionX1 <= elementX1 &&
  23. selectionY1 <= elementY1 &&
  24. selectionX2 >= elementX2 &&
  25. selectionY2 >= elementY2
  26. );
  27. });
  28. }
  29. export function clearSelection(elements: readonly ExcalidrawElement[]) {
  30. const newElements = [...elements];
  31. newElements.forEach(element => {
  32. element.isSelected = false;
  33. });
  34. return newElements;
  35. }
  36. export function deleteSelectedElements(elements: readonly ExcalidrawElement[]) {
  37. return elements.filter(el => !el.isSelected);
  38. }
  39. export function getSelectedIndices(elements: readonly ExcalidrawElement[]) {
  40. const selectedIndices: number[] = [];
  41. elements.forEach((element, index) => {
  42. if (element.isSelected) {
  43. selectedIndices.push(index);
  44. }
  45. });
  46. return selectedIndices;
  47. }
  48. export const someElementIsSelected = (elements: readonly ExcalidrawElement[]) =>
  49. elements.some(element => element.isSelected);
  50. /**
  51. * Returns common attribute (picked by `getAttribute` callback) of selected
  52. * elements. If elements don't share the same value, returns `null`.
  53. */
  54. export function getCommonAttributeOfSelectedElements<T>(
  55. elements: readonly ExcalidrawElement[],
  56. getAttribute: (element: ExcalidrawElement) => T,
  57. ): T | null {
  58. const attributes = Array.from(
  59. new Set(
  60. elements
  61. .filter(element => element.isSelected)
  62. .map(element => getAttribute(element)),
  63. ),
  64. );
  65. return attributes.length === 1 ? attributes[0] : null;
  66. }