ElemCompositionEdit.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. <template>
  2. <div class="elem-composition elem-composition-edit">
  3. <div
  4. v-if="data.showTitle"
  5. ref="ElemTitle"
  6. class="elem-title"
  7. :style="nameStyles"
  8. >
  9. {{ data.parent.topicName }}
  10. </div>
  11. <div class="elem-body" :style="bodyStyle">
  12. <div
  13. class="elem-composition-elements"
  14. @drop.prevent="dropInnerElement($event)"
  15. @dragover.prevent
  16. @dragleave.prevent
  17. >
  18. <elem-composition-element-edit
  19. v-for="element in data.elements"
  20. :key="element.id"
  21. :data="element"
  22. :transform-fit="rebuildGuides"
  23. @resize-over="elementResizeOver"
  24. ></elem-composition-element-edit>
  25. <!-- guide-lines -->
  26. <div class="element-guide-lines">
  27. <div
  28. class="guide-line guide-line-x"
  29. v-for="line in xLines"
  30. :key="`x-${line.top}`"
  31. :style="line"
  32. ></div>
  33. <div
  34. class="guide-line guide-line-y"
  35. v-for="line in yLines"
  36. :key="`y-${line.left}`"
  37. :style="line"
  38. ></div>
  39. </div>
  40. </div>
  41. </div>
  42. </div>
  43. </template>
  44. <script>
  45. import { mapState, mapMutations, mapActions } from "vuex";
  46. import ElemCompositionElementEdit from "./ElemCompositionElementEdit";
  47. import guideLinesMixins from "../../mixins/guideLines";
  48. export default {
  49. name: "elem-composition-edit",
  50. components: { ElemCompositionElementEdit },
  51. mixins: [guideLinesMixins],
  52. props: {
  53. data: {
  54. type: Object,
  55. },
  56. },
  57. data() {
  58. return {
  59. bodyStyle: {},
  60. };
  61. },
  62. computed: {
  63. ...mapState("card", ["curDragElement"]),
  64. nameStyles() {
  65. return {
  66. fontWeight: this.data.parent.nameFontWeight,
  67. fontSize: this.data.parent.nameFontSize,
  68. };
  69. },
  70. },
  71. watch: {
  72. "data.parent": {
  73. handler() {
  74. this.modifyBodyStyle();
  75. },
  76. },
  77. },
  78. mounted() {
  79. this.modifyBodyStyle();
  80. },
  81. methods: {
  82. ...mapMutations("card", ["setCurDragElement", "setCurElement"]),
  83. ...mapActions("card", ["rebuildPages", "modifyElementChild"]),
  84. modifyBodyStyle() {
  85. this.$nextTick(() => {
  86. let height = this.data.h;
  87. if (this.data.showTitle) {
  88. height = this.data.h - this.$refs.ElemTitle.clientHeight;
  89. }
  90. this.bodyStyle = {
  91. height: height + "px",
  92. };
  93. });
  94. },
  95. dropInnerElement(e) {
  96. let { offsetX: x, offsetY: y } = e;
  97. const { offsetLeft, offsetTop } = this.getOffsetInfo(
  98. e.target || e.srcElement
  99. );
  100. // 作文题的子元素中会新增container字段
  101. const curElement = {
  102. ...this.curDragElement,
  103. x: x + offsetLeft,
  104. y: y + offsetTop,
  105. container: {
  106. id: this.data.id,
  107. type: this.data.type,
  108. },
  109. };
  110. if (["LINES", "GRIDS"].includes(curElement.type)) {
  111. curElement.w = this.data.parent.w;
  112. curElement.x = 0;
  113. }
  114. this.elementResizeOver(curElement);
  115. this.setCurDragElement({});
  116. this.setCurElement(curElement);
  117. },
  118. getOffsetInfo(dom, endParentClass = "elem-composition-elements") {
  119. let parentNode = dom;
  120. let offsetTop = 0,
  121. offsetLeft = 0;
  122. while (!parentNode.className.includes(endParentClass)) {
  123. offsetTop += parentNode.offsetTop;
  124. offsetLeft += parentNode.offsetLeft;
  125. parentNode = parentNode.offsetParent;
  126. }
  127. return {
  128. offsetLeft,
  129. offsetTop,
  130. };
  131. },
  132. elementResizeOver(element) {
  133. this.clear();
  134. this.modifyElementChild(element);
  135. this.$nextTick(() => {
  136. this.rebuildPages();
  137. });
  138. },
  139. rebuildGuides(element, actionType) {
  140. return this.rebuild(this.data.elements, element, actionType);
  141. },
  142. },
  143. };
  144. </script>