Transfer.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. import { DesignComp } from "@/modules/editor/defines/DesignTemp/DesignComp";
  2. import { css } from "@linaria/core";
  3. import { defineComponent, onMounted, ref } from "vue";
  4. import { string } from "vue-types";
  5. import { useEditor } from "../../..";
  6. export const Transfer = defineComponent({
  7. props: {
  8. compId: string().isRequired,
  9. },
  10. setup(props) {
  11. const { store, helper } = useEditor();
  12. const resizeRef = ref<HTMLElement>();
  13. const moveRef = ref<HTMLElement>();
  14. const start = {
  15. x: 0,
  16. y: 0,
  17. width: 0,
  18. height: 0,
  19. offsetX: 0,
  20. offsetY: 0,
  21. };
  22. const comp = store.designCompMap.get(props.compId) as DesignComp;
  23. let parentCompEl: HTMLElement;
  24. onMounted(() => {
  25. if (!resizeRef.value || !moveRef.value) return;
  26. resizeRef.value.addEventListener("mousedown", startDrag);
  27. moveRef.value.addEventListener("mousedown", startMove);
  28. const parentContentEl = getClosestParentWithClass(
  29. resizeRef.value,
  30. "view_content"
  31. );
  32. if (!parentContentEl) return;
  33. parentCompEl = parentContentEl;
  34. });
  35. function startMove(e: MouseEvent) {
  36. start.x = e.clientX;
  37. start.y = e.clientY;
  38. document.addEventListener("mousemove", move);
  39. document.addEventListener("mouseup", stopMove);
  40. }
  41. function move(e: MouseEvent) {
  42. const viewEl = parentCompEl.parentElement;
  43. if (!viewEl) return;
  44. start.offsetX = e.clientX - start.x;
  45. start.offsetY = e.clientY - start.y;
  46. viewEl.style.left = helper.designToNaturalSize(
  47. comp.value.position[0] + start.offsetX * 2
  48. );
  49. viewEl.style.top = helper.designToNaturalSize(
  50. comp.value.position[1] + start.offsetY * 2
  51. );
  52. }
  53. function stopMove(e: MouseEvent) {
  54. comp.value.position[0] += start.offsetX * 2;
  55. comp.value.position[1] += start.offsetY * 2;
  56. document.removeEventListener("mousemove", move);
  57. document.removeEventListener("mouseup", stopMove);
  58. }
  59. function startDrag(e: MouseEvent) {
  60. start.x = e.clientX;
  61. start.y = e.clientY;
  62. start.width = comp.layout.size?.[0] || 0;
  63. start.height = comp.layout.size?.[1] || 0;
  64. document.addEventListener("mousemove", drag);
  65. document.addEventListener("mouseup", stopDrag);
  66. }
  67. function drag(e: MouseEvent) {
  68. start.offsetX = e.clientX - start.x;
  69. start.offsetY = e.clientY - start.y;
  70. parentCompEl.style.width = helper.designToNaturalSize(
  71. start.width + start.offsetX * 2
  72. );
  73. parentCompEl.style.height = helper.designToNaturalSize(
  74. start.height + start.offsetY * 2
  75. );
  76. }
  77. function stopDrag() {
  78. comp.layout.size || (comp.layout.size = [0, 0]);
  79. comp.layout.size[0] = start.width + start.offsetX * 2;
  80. comp.layout.size[1] = start.height + start.offsetY * 2;
  81. document.removeEventListener("mousemove", drag);
  82. document.removeEventListener("mouseup", stopDrag);
  83. }
  84. return () => (
  85. <>
  86. <div ref={resizeRef} class={resizeStyle}></div>
  87. <div ref={moveRef} class={moveStyle}></div>
  88. </>
  89. );
  90. },
  91. });
  92. function getClosestParentWithClass(element: HTMLElement, className: string) {
  93. let parent = element.parentElement;
  94. while (parent) {
  95. if (parent.classList.contains(className)) {
  96. return parent;
  97. }
  98. parent = parent.parentElement;
  99. }
  100. return null;
  101. }
  102. const resizeStyle = css`
  103. position: absolute;
  104. bottom: 0;
  105. right: 0;
  106. width: 8px;
  107. height: 8px;
  108. border-bottom: 4px solid;
  109. border-right: 4px solid;
  110. border-color: @inf-primary-fade-color;
  111. cursor: nwse-resize;
  112. &:hover {
  113. border-color: @inf-primary-color;
  114. }
  115. `;
  116. const moveStyle = css`
  117. position: absolute;
  118. bottom: 0;
  119. left: 50%;
  120. width: 40px;
  121. height: 4px;
  122. transform: translate(-50%, 50%);
  123. background-color: @inf-primary-color;
  124. border-radius: 4px;
  125. cursor: all-scroll;
  126. &:hover {
  127. border-color: #fff;
  128. box-shadow: 0 0 3px 2px rgba(0, 0, 0, 0.5);
  129. outline: 2px solid #fff;
  130. }
  131. `;