Quellcode durchsuchen

富文本图片编辑调整

zhangjie vor 2 Jahren
Ursprung
Commit
98ef0fb488

BIN
src/components/img/action_scale.png


+ 12 - 0
src/components/selection/CourseSelect.vue

@@ -34,6 +34,7 @@ export default {
     disabled: { type: Boolean, default: false },
     placeholder: { type: String, default: "请选择课程" },
     clearable: { type: Boolean, default: true },
+    selectOnlyOne: { type: Boolean, default: true },
   },
   data() {
     return {
@@ -59,6 +60,17 @@ export default {
       const res = await courseQueryApi(query);
       this.optionList = res.data || [];
       this.loading = false;
+
+      if (
+        !this.disabled &&
+        this.selectOnlyOne &&
+        this.optionList.length === 1
+      ) {
+        this.selected = this.optionList[0].id;
+        this.$emit("input", this.selected);
+        this.$emit("change", this.optionList[0]);
+        this.$emit("select-default", this.optionList[0]);
+      }
     },
     select() {
       this.$emit("input", this.selected);

+ 128 - 5
src/components/vEditor/VEditor.vue

@@ -123,6 +123,18 @@ export default {
         // this.$emit("on-result", json);
       }, 200);
     },
+    emitJsonStrict() {
+      if (this.emitType === "html") {
+        const content = this.$refs.editor.innerHTML;
+        this.$emit("input", content);
+        this.$emit("change", content);
+        return;
+      }
+
+      const json = toJSON(this.$refs.editor);
+      this.$emit("input", json);
+      this.$emit("change", json);
+    },
     wheelEventHandle(e) {
       // console.log(e);
       // console.dir(e.target);
@@ -149,12 +161,120 @@ export default {
       if (el.tagName && el.tagName === "IMG") {
         e.preventDefault();
         e.stopPropagation();
-        const selection = window.getSelection();
-        selection.removeAllRanges();
-        const range = document.createRange();
-        range.selectNode(el);
-        selection.addRange(range);
+
+        if (el.dataset.latex) {
+          const selection = window.getSelection();
+          selection.removeAllRanges();
+          const range = document.createRange();
+          range.selectNode(el);
+          selection.addRange(range);
+        }
+
+        this.clearActiveImg();
+        el.className = `${el.className} is-active`;
+        this.activeResize(el);
+        return;
+      }
+    },
+    clearActiveImg() {
+      this.$refs.editor.querySelectorAll("img").forEach((imgDom) => {
+        if (!imgDom.className.indexOf("is-active")) return;
+        let names = imgDom.className
+          .split(" ")
+          .filter((item) => item && item !== "is-active");
+
+        imgDom.className = names.join(" ");
+      });
+    },
+    activeResize(imgDom) {
+      const _this = this;
+      let _x = 0;
+      let { clientWidth, naturalWidth, naturalHeight } = imgDom;
+      let resizeDom = null;
+
+      removeResizeDom();
+      createResizeDom();
+
+      function createResizeDom() {
+        resizeDom = document.createElement("div");
+        resizeDom.id = "resize-elem";
+        resizeDom.style.position = "absolute";
+        resizeDom.style.width = "16px";
+        resizeDom.style.height = "16px";
+        resizeDom.style.backgroundColor = "#fff";
+        resizeDom.style.backgroundImage =
+          "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAX1JREFUWEftlTFLw1AQx+/S2dEvUbe8g05CHbroKm7iIHQW1LlxraAfQHDoKDjqJNhBhJJ32SzOrvoRSv/yJIEaoq8kxi7JFAi534//e3fHtOKHV8ynRqBJoEnAm4Ax5jFt1Xdmnqbvb8z8Gsfxc9U2XlagWwAaq+rWfwjcEdF2DjQNgmAvjuOX2gVEZAjgdBHEzA/W2l5VuPvfewQiEgEY5GHMfGut3a0q4RUIw/CImS+JaArghpmjDMrM19bawyoSXgER6c3n86jVavXdmYdhGDHzYiIjVT0oK+EVKCqclwAQJUlyVkailIADFdyNb23Z6XTak8kkmxs/upUWSCX2AYwWqn9JiMjApUJE66r68VsylQRc4YI7MSaibHBtqupTrQKuuDHmhIjO8yAA/SRJrmoXSCXczsiP7AtVPa5doOAYMua9qu7UKiAiXQDZxsyzvAur8iXMiK7tZrPZBoB2EAQGwJr75tuYfyZQZggttYzKFl72vyaBJoEmgU/j14shnky4jQAAAABJRU5ErkJggg==')";
+        resizeDom.style.backgroundSize = "100% 100%";
+        resizeDom.style.borderTop = "1px solid #1886fe";
+        resizeDom.style.borderLeft = "1px solid #1886fe";
+        resizeDom.style.cursor = "nwse-resize";
+        resizeDom.style.zIndex = 9999;
+        document.body.appendChild(resizeDom);
+
+        resizeResizeDom();
+
+        document.addEventListener("click", documentClickHanle);
+      }
+
+      function removeResizeDom() {
+        let dom = document.getElementById("resize-elem");
+        if (!dom) return;
+        document.body.removeChild(dom);
+        resizeDom = null;
+
+        document.removeEventListener("click", documentClickHanle);
+      }
+
+      function resizeResizeDom() {
+        const imgPos = imgDom.getBoundingClientRect();
+        resizeDom.style.left = imgPos.x + imgPos.width - 16 + "px";
+        resizeDom.style.top = imgPos.y + imgPos.height - 16 + "px";
+      }
+
+      function documentClickHanle() {
+        removeResizeDom();
+        _this.clearActiveImg();
+      }
+
+      function getValidSize(originSize, size) {
+        if (size <= 10) return Math.min(originSize, 10);
+        if (size >= 2 * originSize) return 2 * originSize;
+        return size;
+      }
+      // 只允许鼠标左键触发
+      function moveHandle(e) {
+        if (e.button !== 0) return;
+        e.preventDefault();
+        e.stopPropagation();
+
+        let width = getValidSize(naturalWidth, e.pageX - _x + clientWidth);
+        let height = (width * naturalHeight) / naturalWidth;
+
+        imgDom.style.width = width + "px";
+        imgDom.style.height = height + "px";
+
+        resizeResizeDom();
+      }
+
+      function upHandle(e) {
+        removeResizeDom();
+        _this.emitJsonStrict();
+
+        if (e.button !== 0) return;
+        e.preventDefault();
+        e.stopPropagation();
+
+        document.removeEventListener("mousemove", moveHandle);
+        document.removeEventListener("mouseup", upHandle);
       }
+
+      resizeDom.addEventListener("mousedown", function (e) {
+        if (e.button !== 0) return;
+        _x = e.pageX;
+
+        document.addEventListener("mousemove", moveHandle);
+        document.addEventListener("mouseup", upHandle);
+      });
     },
   },
 };
@@ -225,6 +345,9 @@ export default {
   /* max-height: 42px; */
   display: inline-block;
 }
+.v-editor-body img[data-is-image].is-active {
+  box-shadow: 0 0 1px 1px #1886fe;
+}
 
 .v-editor-body audio {
   height: 16px;

+ 1 - 18
src/modules/questions/views/CourseProperty.vue

@@ -11,24 +11,7 @@
           ></el-input>
         </el-form-item>
         <el-form-item label="课程名称">
-          <el-select
-            v-model="formSearch.courseId"
-            :remote-method="getCourses"
-            :loading="courseLoading4Search"
-            remote
-            filterable
-            clearable
-            placeholder="请选择"
-            @clear="getCourses('')"
-          >
-            <el-option
-              v-for="item in courseInfoSelect"
-              :key="item.courseId"
-              :label="item.courseInfo"
-              :value="item.courseId"
-            >
-            </el-option>
-          </el-select>
+          <course-select v-model="formSearch.courseId"> </course-select>
         </el-form-item>
         <el-form-item>
           <el-button type="danger" @click="searchFrom">查询</el-button>