natasha před 2 dny
rodič
revize
829773c1b8

+ 143 - 70
src/views/book/courseware/create/components/question/image_text/ImageText.vue

@@ -72,68 +72,92 @@
             border: isText ? '2px solid #165DFF' : '2px solid #f90',
           }"
         ></div>
-        <template v-for="(itemh, indexh) in data.text_list">
-          <div
-            v-if="indexh === hotspotsActiveIndex"
-            :key="indexh"
+        <div
+          v-for="(itemh, indexh) in data.text_list"
+          :key="indexh"
+          :style="{
+            position: 'absolute',
+            top: `${itemh.y}`,
+            left: `${itemh.x}`,
+            width: `${itemh.width}`,
+            height: `${itemh.height}`,
+            border: indexh === hotspotsActiveIndex ? '2px solid #f00' : '2px solid #165DFF',
+          }"
+          @click="handleAcitveSelect('text', indexh)"
+        >
+          <label
             :style="{
               position: 'absolute',
-              top: `${itemh.y}`,
-              left: `${itemh.x}`,
-              width: `${itemh.width}`,
-              height: `${itemh.height}`,
-              border: '2px solid #165DFF',
+              top: '-13px',
+              right: '-13px',
+              width: '26px',
+              height: '26px',
+              border: indexh === hotspotsActiveIndex ? '2px solid #f00' : '2px solid #165DFF',
+              textAlign: 'center',
+              borderRadius: '50%',
+              boxShadow: ' 0px 5px 5px -3px #0000001A',
+              background: '#fff',
+              color: indexh === hotspotsActiveIndex ? '#f00' : '#165DFF',
             }"
+            >{{ indexh + 1 }}</label
           >
-            <label
-              :style="{
-                position: 'absolute',
-                top: '-13px',
-                right: '-13px',
-                width: '26px',
-                height: '26px',
-                border: '2px solid #165DFF',
-                textAlign: 'center',
-                borderRadius: '50%',
-                boxShadow: ' 0px 5px 5px -3px #0000001A',
-                background: '#fff',
-                color: '#165DFF',
-              }"
-              >{{ indexh + 1 }}</label
-            >
-          </div>
-        </template>
-        <template v-for="(itemh, indexhs) in data.input_list">
-          <div
-            v-if="indexhs === inputActiveIndex"
-            :key="indexhs"
+          <span
             :style="{
               position: 'absolute',
-              top: `${itemh.y}`,
-              left: `${itemh.x}`,
-              width: `${itemh.width}`,
-              height: `${itemh.height}`,
-              border: '2px solid #f90',
+              bottom: '0',
+              left: '0',
+              borderRadius: '0 2px 0 0',
+              background: indexh === hotspotsActiveIndex ? '#f00' : '#165DFF',
+              color: '#fff',
+              fontSize: '12px',
+              padding: '0 3px',
             }"
+            >文字框</span
           >
-            <label
-              :style="{
-                position: 'absolute',
-                top: '-13px',
-                right: '-13px',
-                width: '26px',
-                height: '26px',
-                border: '2px solid #f90',
-                textAlign: 'center',
-                borderRadius: '50%',
-                boxShadow: ' 0px 5px 5px -3px #0000001A',
-                background: '#fff',
-                color: '#f90',
-              }"
-              >{{ indexhs + 1 }}</label
-            >
-          </div>
-        </template>
+        </div>
+        <div
+          v-for="(itemh, indexhs) in data.input_list"
+          :key="indexhs"
+          :style="{
+            position: 'absolute',
+            top: `${itemh.y}`,
+            left: `${itemh.x}`,
+            width: `${itemh.width}`,
+            height: `${itemh.height}`,
+            border: indexhs === inputActiveIndex ? '2px solid #ff0000' : '2px solid #f90',
+          }"
+          @click="handleAcitveSelect('input', indexhs)"
+        >
+          <label
+            :style="{
+              position: 'absolute',
+              top: '-13px',
+              right: '-13px',
+              width: '26px',
+              height: '26px',
+              border: indexhs === inputActiveIndex ? '2px solid #ff0000' : '2px solid #f90',
+              textAlign: 'center',
+              borderRadius: '50%',
+              boxShadow: ' 0px 5px 5px -3px #0000001A',
+              background: '#fff',
+              color: '#f90',
+            }"
+            >{{ indexhs + 1 }}</label
+          >
+          <span
+            :style="{
+              position: 'absolute',
+              bottom: '0',
+              left: '0',
+              borderRadius: '0 2px 0 0',
+              background: indexhs === inputActiveIndex ? '#f00' : '#f90',
+              color: '#fff',
+              fontSize: '12px',
+              padding: '0 3px',
+            }"
+            >输入框</span
+          >
+        </div>
       </div>
       <template v-if="data.image_list[0] && data.text_list.length > 0">
         <h4>文本框内容</h4>
@@ -157,7 +181,10 @@
               v-if="hotspotsActiveIndex !== indexh"
               type="primary"
               size="small"
-              @click="hotspotsActiveIndex = indexh"
+              @click="
+                hotspotsActiveIndex = indexh;
+                inputActiveIndex = null;
+              "
               >编辑</el-button
             >
             <el-button v-else type="primary" size="small" @click="hotspotsActiveIndex = null">保存</el-button>
@@ -193,7 +220,10 @@
               v-if="inputActiveIndex !== indexh"
               type="primary"
               size="small"
-              @click="inputActiveIndex = indexh"
+              @click="
+                inputActiveIndex = indexh;
+                hotspotsActiveIndex = null;
+              "
             >
               编辑
             </el-button>
@@ -264,10 +294,10 @@ export default {
       acceptFileType: '.jpg,.png,.jpeg',
       iconClass: 'picture',
       isSelecting: false,
-      startX: 0,
-      startY: 0,
-      endX: 0,
-      endY: 0,
+      startX: null,
+      startY: null,
+      endX: null,
+      endY: null,
       hotspotsActiveIndex: null, // 当前编辑文本框热区索引
       genloading: false, // 字幕节点loading
       isText: true, // 框选是文本还是输入框
@@ -282,6 +312,8 @@ export default {
       showStyleFlag: false,
       styleData: null,
       randomId: Math.random().toString(36).substring(2, 12),
+      activeType: null,
+      activeIndex: null,
     };
   },
   watch: {
@@ -304,6 +336,15 @@ export default {
     'data.text_list': 'handleMindMap',
   },
   methods: {
+    handleAcitveSelect(type, index) {
+      this.activeType = type;
+      this.activeIndex = index;
+      if (type === 'text') {
+        this.hotspotsActiveIndex = index;
+      } else {
+        this.inputActiveIndex = index;
+      }
+    },
     updateFileList({ file_list, file_id_list, file_info_list }) {
       this.data.image_list = file_list;
       this.data.image_id_list = file_id_list;
@@ -333,7 +374,6 @@ export default {
     startSelection(event) {
       this.isSelecting = true;
       let clientRect = document.getElementById(`selectableArea${this.randomId}`).getBoundingClientRect();
-
       this.startX = event.clientX - clientRect.left;
       this.startY = event.clientY - clientRect.top;
     },
@@ -345,6 +385,12 @@ export default {
       this.endY = event.clientY - clientRect.top;
     },
     endSelection() {
+      console.log('this.startX' + this.startX);
+      console.log('this.endX' + this.endX);
+      console.log('this.startY' + this.startY);
+      console.log('this.endY' + this.endY);
+
+      if (!this.isSelecting || this.startX === this.endX || !this.endX) return;
       this.isSelecting = false;
       const width = Math.abs(this.endX - this.startX);
       const height = Math.abs(this.endY - this.startY);
@@ -358,16 +404,20 @@ export default {
         y,
         text: '',
       };
-      this.startX = 0;
-      this.endX = 0;
-      this.startY = 0;
-      this.endY = 0;
+      this.startX = null;
+      this.endX = null;
+      this.startY = null;
+      this.endY = null;
       if (width && height && this.isText) {
         this.data.text_list.push(obj);
+        this.activeType = 'text';
+        this.activeIndex = this.data.text_list.length - 1;
 
         this.hotspotsActiveIndex = this.data.text_list.length - 1;
       } else if (width && height && !this.isText) {
         this.data.input_list.push(obj);
+        this.activeType = 'input';
+        this.activeIndex = this.data.input_list.length - 1;
 
         this.inputActiveIndex = this.data.input_list.length - 1;
       }
@@ -563,20 +613,43 @@ export default {
     handleGlobalEsc(event) {
       if (event.key === 'Escape' || event.key === 'Esc' || event.keyCode === 27) {
         this.isSelecting = false;
-        this.startX = 0;
-        this.startY = 0;
-        this.endX = 0;
-        this.endY = 0;
+        this.startX = null;
+        this.startY = null;
+        this.endX = null;
+        this.endY = null;
+      }
+    },
+    handleGlobalDelete(event) {
+      if (event.keyCode === 8 || event.key === 'Backspace' || event.key === 'Delete') {
+        if (this.activeIndex !== null) {
+          if (this.activeType === 'text') {
+            this.data.text_list.splice(this.activeIndex, 1);
+            this.hotspotsActiveIndex = null;
+          } else {
+            this.data.input_list.splice(this.activeIndex, 1);
+            this.inputActiveIndex = null;
+          }
+          this.activeType = null;
+          this.activeIndex = null;
+          this.isSelecting = false;
+          this.startX = null;
+          this.startY = null;
+          this.endX = null;
+          this.endY = null;
+        }
       }
     },
   },
   mounted() {
-    // 添加全局事件监听器
+    // 添加全局事件监听器esc
     document.addEventListener('keyup', this.handleGlobalEsc);
+    // 添加全局事件监听器delete
+    document.addEventListener('keyup', this.handleGlobalDelete);
   },
   beforeDestroy() {
     // 移除全局事件监听器
     document.removeEventListener('keyup', this.handleGlobalEsc);
+    document.removeEventListener('keyup', this.handleGlobalDelete);
   },
 };
 </script>