소스 검색

防止快速切换任务后的重复/重叠渲染

Michael Wang 4 년 전
부모
커밋
b3dbe9421a
1개의 변경된 파일30개의 추가작업 그리고 21개의 파일을 삭제
  1. 30 21
      src/features/mark/MarkBody.vue

+ 30 - 21
src/features/mark/MarkBody.vue

@@ -116,24 +116,41 @@ export default defineComponent({
     let maxSliceWidth = 0; // 最大的裁切块宽度,图片容器以此为准
     let theFinalHeight = 0; // 最终宽度,用来定位轨迹在第几张图片,不包括image-seperator高度
 
+    async function getImageUsingDataUrl(
+      dataUrl: string
+    ): Promise<HTMLImageElement> {
+      return new Promise((resolve) => {
+        const image = new Image();
+        image.src = dataUrl;
+        image.onload = function () {
+          resolve(image);
+        };
+      });
+    }
+
     async function processSliceConfig() {
       // check if have MarkResult for currentTask
       let markResult = store.currentMarkResult;
 
       if (!markResult || !store.currentTask) return;
 
+      const images = [];
+      const urls = [];
       // 必须要先加载一遍,把“选择整图”的宽高重置后,再算总高度
       for (const sliceConfig of store.currentTask.sliceConfig) {
         const url = filters.toCompleteUrl(
           store.currentTask.sliceUrls[sliceConfig.i - 1]
         );
         const image = await loadImage(url);
+        images.push(image);
+        urls.push(url);
         if (sliceConfig.w === 0 && sliceConfig.h === 0) {
           // 选择整图时,w/h 为0
           sliceConfig.w = image.naturalWidth;
           sliceConfig.h = image.naturalHeight;
         }
       }
+
       theFinalHeight = store.currentTask.sliceConfig
         .map((v) => v.h)
         .reduce((acc, v) => (acc += v));
@@ -144,12 +161,13 @@ export default defineComponent({
       // 用来保存sliceImage在整个图片容器中(不包括image-seperator)的高度范围
       let accumTopHeight = 0;
       let accumBottomHeight = 0;
+      const tempSliceImagesWithTrackList = [] as Array<SliceImage>;
       for (const sliceConfig of store.currentTask.sliceConfig) {
         accumBottomHeight += sliceConfig.h;
         const url = filters.toCompleteUrl(
           store.currentTask.sliceUrls[sliceConfig.i - 1]
         );
-        const image = await loadImage(url);
+        const image = images[urls.indexOf(url)];
 
         const dataUrl = getDataUrlForSliceConfig(
           image,
@@ -164,9 +182,9 @@ export default defineComponent({
         const thisImageTagList = markResult.specialTagList.filter(
           (v) => v.offsetIndex === sliceConfig.i
         );
-        const sliceImage = new Image();
-        sliceImage.src = dataUrl;
-        sliceImagesWithTrackList.push({
+
+        const sliceImage = await getImageUsingDataUrl(dataUrl);
+        tempSliceImagesWithTrackList.push({
           url: dataUrl,
           indexInSliceUrls: sliceConfig.i,
           // 通过positionY来定位是第几张slice的还原,并过滤出相应的track
@@ -189,6 +207,7 @@ export default defineComponent({
         });
         accumTopHeight = accumBottomHeight;
       }
+      sliceImagesWithTrackList.push(...tempSliceImagesWithTrackList);
     }
 
     async function processSplitConfig() {
@@ -218,11 +237,10 @@ export default defineComponent({
 
       let accumTopHeight = 0;
       let accumBottomHeight = 0;
+      const tempSliceImagesWithTrackList = [] as Array<SliceImage>;
       for (const url of store.currentTask.sliceUrls) {
-        const completeUrl = filters.toCompleteUrl(url);
-
         for (const config of splitConfigPairs) {
-          const image = await loadImage(completeUrl);
+          const image = images[store.currentTask.sliceUrls.indexOf(url)];
 
           accumBottomHeight += image.naturalHeight;
 
@@ -245,9 +263,8 @@ export default defineComponent({
               (store.currentTask &&
                 store.currentTask.sliceUrls.indexOf(url) + 1)
           );
-          const sliceImage = new Image();
-          sliceImage.src = dataUrl;
-          sliceImagesWithTrackList.push({
+          const sliceImage = await getImageUsingDataUrl(dataUrl);
+          tempSliceImagesWithTrackList.push({
             url: dataUrl,
             indexInSliceUrls: store.currentTask.sliceUrls.indexOf(url) + 1,
             trackList: thisImageTrackList.filter(
@@ -270,6 +287,7 @@ export default defineComponent({
           accumTopHeight = accumBottomHeight;
         }
       }
+      sliceImagesWithTrackList.push(...tempSliceImagesWithTrackList);
     }
     const renderPaperAndMark = async () => {
       if (__lock) {
@@ -277,31 +295,22 @@ export default defineComponent({
           console.log("重复渲染,返回");
           return;
         }
+        console.log("上个任务还未渲染完毕,稍等一秒再尝试渲染");
         await new Promise((res) => setTimeout(res, 1000));
         await renderPaperAndMark();
+        return;
       }
       __lock = true;
       __currentLibraryId = store.currentTask?.libraryId ?? -1;
       sliceImagesWithTrackList.splice(0);
       // check if have MarkResult for currentTask
       let markResult = store.currentMarkResult;
-      // if (!store.currentTask) {
-      //   sliceImagesWithTrackList.splice(0);
-      //   _studentId = -1;
-      // }
 
       if (!markResult || !store.currentTask) {
         __lock = false;
         return;
       }
 
-      // reset sliceImagesWithTrackList ,当切换任务时,要重新绘制图片和轨迹
-      // if (_studentId !== store.currentTask.studentId) {
-      //   // 还原轨迹用得上
-      //   sliceImagesWithTrackList.splice(0);
-      //   _studentId = store.currentTask.studentId;
-      // }
-
       try {
         rendering.value = true;
         if (hasSliceConfig()) {