dragElements.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import { SHAPES } from "../shapes";
  2. import { updateBoundElements } from "./binding";
  3. import { getCommonBounds } from "./bounds";
  4. import { mutateElement } from "./mutateElement";
  5. import { getPerfectElementSize } from "./sizeHelpers";
  6. import Scene from "../scene/Scene";
  7. import { NonDeletedExcalidrawElement } from "./types";
  8. import { PointerDownState } from "../types";
  9. export const dragSelectedElements = (
  10. pointerDownState: PointerDownState,
  11. selectedElements: NonDeletedExcalidrawElement[],
  12. pointerX: number,
  13. pointerY: number,
  14. scene: Scene,
  15. lockDirection: boolean = false,
  16. distanceX: number = 0,
  17. distanceY: number = 0,
  18. ) => {
  19. const [x1, y1] = getCommonBounds(selectedElements);
  20. const offset = { x: pointerX - x1, y: pointerY - y1 };
  21. selectedElements.forEach((element) => {
  22. let x: number;
  23. let y: number;
  24. if (lockDirection) {
  25. const lockX = lockDirection && distanceX < distanceY;
  26. const lockY = lockDirection && distanceX > distanceY;
  27. const original = pointerDownState.originalElements.get(element.id);
  28. x = lockX && original ? original.x : element.x + offset.x;
  29. y = lockY && original ? original.y : element.y + offset.y;
  30. } else {
  31. x = element.x + offset.x;
  32. y = element.y + offset.y;
  33. }
  34. mutateElement(element, {
  35. x,
  36. y,
  37. });
  38. updateBoundElements(element, {
  39. simultaneouslyUpdated: selectedElements,
  40. });
  41. });
  42. };
  43. export const getDragOffsetXY = (
  44. selectedElements: NonDeletedExcalidrawElement[],
  45. x: number,
  46. y: number,
  47. ): [number, number] => {
  48. const [x1, y1] = getCommonBounds(selectedElements);
  49. return [x - x1, y - y1];
  50. };
  51. export const dragNewElement = (
  52. draggingElement: NonDeletedExcalidrawElement,
  53. elementType: typeof SHAPES[number]["value"],
  54. originX: number,
  55. originY: number,
  56. x: number,
  57. y: number,
  58. width: number,
  59. height: number,
  60. shouldMaintainAspectRatio: boolean,
  61. shouldResizeFromCenter: boolean,
  62. /** whether to keep given aspect ratio when `isResizeWithSidesSameLength` is
  63. true */
  64. widthAspectRatio?: number | null,
  65. ) => {
  66. if (shouldMaintainAspectRatio) {
  67. if (widthAspectRatio) {
  68. height = width / widthAspectRatio;
  69. } else {
  70. ({ width, height } = getPerfectElementSize(
  71. elementType,
  72. width,
  73. y < originY ? -height : height,
  74. ));
  75. if (height < 0) {
  76. height = -height;
  77. }
  78. }
  79. }
  80. let newX = x < originX ? originX - width : originX;
  81. let newY = y < originY ? originY - height : originY;
  82. if (shouldResizeFromCenter) {
  83. width += width;
  84. height += height;
  85. newX = originX - width / 2;
  86. newY = originY - height / 2;
  87. }
  88. if (width !== 0 && height !== 0) {
  89. mutateElement(draggingElement, {
  90. x: newX,
  91. y: newY,
  92. width,
  93. height,
  94. });
  95. }
  96. };