tangning hace 1 día
padre
commit
73c503a2b8
Se han modificado 2 ficheros con 112 adiciones y 74 borrados
  1. 95 55
      src/view/case/photos/canvas-photo-editor.js
  2. 17 19
      src/view/case/photos/index.vue

+ 95 - 55
src/view/case/photos/canvas-photo-editor.js

@@ -209,12 +209,58 @@ export class CanvasPhotoEditor {
       return
     }
     if (e.target !== this.canvas) return
-    // ==========================================
-    // 🔥 页面拖拽排序:按下时记录
-    // ==========================================
     const rect = this.canvas.getBoundingClientRect()
     const mouseX = (e.clientX - rect.left - this.drawOffsetX) / this.scale
     const mouseY = (e.clientY - rect.top - this.drawOffsetY) / this.scale
+    //判断是否点击在标引上
+    
+    let isLine = this.indexingLineList.findIndex(item => {
+      let points = item.points || [];
+
+      // 点数量不足2个,直接不匹配
+      if (points.length < 2) return false;
+
+      // 遍历所有相邻两点,判断鼠标是否在任意一段上
+      for (let i = 0; i < points.length - 1; i++) {
+        const p1 = points[i];
+        const p2 = points[i + 1];
+
+        // 只要有一段满足,就返回 true
+        if (this.isPointOnLine(mouseX, mouseY, p1.x, p1.y, p2.x, p2.y)) {
+          return true;
+        }
+      }
+
+      // 所有线段都不满足
+      return false;
+    });
+    this.isLineDel = false
+    if (isLine != -1) {//选中已生成标引
+      // 阻止事件冒泡和默认行为,避免鼠标事件持续触发
+      e.stopPropagation();
+      e.preventDefault();
+      this.isLineDel = true
+      return ElMessageBox.confirm("确定删除当前选中标引?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      }).then(async () => {
+        this.indexingLineList.splice(isLine, 1);
+        this.indexingLineList = [...this.indexingLineList];
+        this.drawAllPages()
+        ElMessage({
+          type: "success",
+          message: "删除成功",
+        });
+        this.saveHistory()
+        this.isLineDel = false
+      });
+    } else {
+      this.isLineDel = false
+    }
+    // ==========================================
+    // 🔥 页面拖拽排序:按下时记录
+    // ==========================================
     if (this.dragPageData.drawing) {
       this.dragPageData.end = { x: mouseX, y: mouseY }
       this.drawAllPages()
@@ -411,50 +457,6 @@ export class CanvasPhotoEditor {
     const mouseY = (e.clientY - rect.top - this.drawOffsetY) / this.scale
     const PhotoIndex = this.getPhotoPositionInPage(e)
     console.log('indexingLineList', this.indexingLineList)
-    let isLine = this.indexingLineList.findIndex(item => {
-      let points = item.points || [];
-
-      // 点数量不足2个,直接不匹配
-      if (points.length < 2) return false;
-
-      // 遍历所有相邻两点,判断鼠标是否在任意一段上
-      for (let i = 0; i < points.length - 1; i++) {
-        const p1 = points[i];
-        const p2 = points[i + 1];
-
-        // 只要有一段满足,就返回 true
-        if (this.isPointOnLine(mouseX, mouseY, p1.x, p1.y, p2.x, p2.y)) {
-          return true;
-        }
-      }
-
-      // 所有线段都不满足
-      return false;
-    });
-    this.isLineDel = false
-    if (isLine != -1) {//选中已生成标引
-      // 阻止事件冒泡和默认行为,避免鼠标事件持续触发
-      e.stopPropagation();
-      e.preventDefault();
-      this.isLineDel = true
-      return ElMessageBox.confirm("确定删除当前选中标引?", "提示", {
-        confirmButtonText: "确定",
-        cancelButtonText: "取消",
-        type: "warning",
-      }).then(async () => {
-        this.indexingLineList.splice(isLine, 1);
-        this.indexingLineList = [...this.indexingLineList];
-        this.drawAllPages()
-        ElMessage({
-          type: "success",
-          message: "删除成功",
-        });
-        this.saveHistory()
-        this.isLineDel = false
-      });
-    } else {
-      this.isLineDel = false
-    }
     console.log('indexing', this.indexing, PhotoIndex, isLine)
     if (PhotoIndex.itemIndex == -1) {
       ElMessage.error("请选中对应的图片进行标引操作!");
@@ -739,7 +741,7 @@ export class CanvasPhotoEditor {
    * @param {number} r 允许的误差范围(线宽容错)
    * @return {boolean}
    */
-  isPointOnLine(px, py, x1, y1, x2, y2, r = 10) {
+  isPointOnLine(px, py, x1, y1, x2, y2, r = 20) {
     // 1. 计算点到线段的垂直距离
     const A = px - x1;
     const B = py - y1;
@@ -988,7 +990,7 @@ export class CanvasPhotoEditor {
     ctx.clip();
     //添加说明文字
     // 3. 绘制文字(基于图片实际区域居中,且在裁剪区内)
-    const text = photo && photo.name || '说明文字';
+    const text = photo && photo.id? photo.name : '说明文字';
     // 文字居中坐标:图片实际显示区域的正中心
 
     // 文字样式(适配缩放)
@@ -1311,10 +1313,48 @@ resizePageAndReflow(pages, pageIndex, itemValue) {
     const wrapperWidth = this.scrollWrapper.clientWidth
     const wrapperHeight = this.scrollWrapper.clientHeight
 
-    // 计算居中坐标偏移
-    this.drawOffsetX = (wrapperWidth - totalWidth) / 2
-    this.drawOffsetY = (wrapperHeight - totalHeight) / 2
+  // 1. 计算所有页面的总占用尺寸(横向排列:总宽度 = 单页宽 * 页数 + 页边距;高度 = 单页高)
+    const singlePageWidth = this.pageWidth + 2 * this.pageMargin; // 单页宽(含边距)
+    const singlePageHeight = this.pageHeight + 2 * this.pageMargin; // 单页高(含边距)
+    const totalPagesWidth = singlePageWidth * this.pages.length; // 所有页面总宽度
+    const totalPagesHeight = singlePageHeight; // 纵向仅单页高度(横向排列)
+
+    // 2. 获取画布可视区域尺寸
+    const canvasViewWidth = this.canvas.width || this.scrollWrapper.clientWidth;
+    const canvasViewHeight = this.canvas.height || this.scrollWrapper.clientHeight;
+
+    // 3. 计算自适应缩放比例(保证所有页面完整显示)
+    const scaleByWidth = canvasViewWidth / totalPagesWidth; // 按宽度适配的缩放比
+    const scaleByHeight = canvasViewHeight / totalPagesHeight; // 按高度适配的缩放比
+    const fitScale = Math.min(scaleByWidth, scaleByHeight, this._scaleMax); // 取最小值且不超过最大缩放
+
+    // 4. 重置缩放比例
+    this._scale = Math.max(fitScale, this._scaleMin); // 不低于最小缩放
+
+    // 5. 计算居中偏移量(让所有页面在画布中居中)
+    // 总内容的实际显示宽度/高度(缩放后)
+    const renderedTotalWidth = totalPagesWidth * this._scale;
+    const renderedTotalHeight = totalPagesHeight * this._scale;
+    
+    // 居中偏移:(画布尺寸 - 内容尺寸) / 2
+    this.drawOffsetX = (canvasViewWidth - renderedTotalWidth) / 2;
+    this.drawOffsetY = (canvasViewHeight - renderedTotalHeight) / 2;
+
+    // 6. 重置临时状态(拖拽/标引/页面移动)
+    this.isDragging = false;
+    this.dragPageData = {
+      drawing: false,
+      index: -1,
+      start: null,
+      end: null,
+      movedIndex: -1,
+    };
+    this.tempArrow = { start: null, end: null, drawing: false };
+    this.indexingNum = 0; // 重置标引状态
 
+    // 7. 重置选中状态(可选,根据需求)
+    this.selectedPageIndex = -1;
+    this.selectedPageItem = { index: -1, pageIndex: -1 };
     this.drawAllPages() // 重置位置时重绘一次
   }
 
@@ -1442,7 +1482,7 @@ resizePageAndReflow(pages, pageIndex, itemValue) {
     });
     this.currentIndex++;
     console.log("saveHistory", this.history, this.currentIndex);
-    if (this.history.length > 5) {
+    if (this.history.length > 20) {
       this.history.shift(); // 删除最早的一条
       this.currentIndex--;
     }
@@ -1582,7 +1622,7 @@ resizePageAndReflow(pages, pageIndex, itemValue) {
 
               // 文字
               ctx.fillStyle = "#000";
-              const text = photo.name || "说明文字";
+              const text = photo.id?photo.name:"说明文字";
               this.drawCenteredTextWithEllipsis(
                 ctx, text,
                 coord.x + coord.width / 2,
@@ -1752,7 +1792,7 @@ resizePageAndReflow(pages, pageIndex, itemValue) {
 
               // 文字
               ctx.fillStyle = "#000";
-              const text = photo.name || "说明文字";
+              const text = photo.id?photo.name:"说明文字";
               this.drawCenteredTextWithEllipsis(
                 ctx, text,
                 coord.x + coord.width / 2,

+ 17 - 19
src/view/case/photos/index.vue

@@ -507,26 +507,24 @@ const toggleSelect = (photoId) => {
 };
 // 切换全屏
 const toggleFullScreen = async () => {
-  const element = canvas.value.parentElement;
-  oldCanvas = element;
-  if (!element) return;
+  if (!editor.value) return;
+  editor.value.resetPosition();
+  // try {
+  //   if (element.requestFullscreen) {
+  //     await element.requestFullscreen();
+  //   } else if (element.webkitRequestFullscreen) {
+  //     await element.webkitRequestFullscreen();
+  //   } else if (element.msRequestFullscreen) {
+  //     await element.msRequestFullscreen();
+  //   }
+  //   editor.value.scrollWrapper = canvas.value.parentElement;
+  //   editor.value.resizeCanvas();
+  //   editor.value.resetPosition();
 
-  try {
-    if (element.requestFullscreen) {
-      await element.requestFullscreen();
-    } else if (element.webkitRequestFullscreen) {
-      await element.webkitRequestFullscreen();
-    } else if (element.msRequestFullscreen) {
-      await element.msRequestFullscreen();
-    }
-    editor.value.scrollWrapper = canvas.value.parentElement;
-    editor.value.resizeCanvas();
-    editor.value.resetPosition();
-
-    // }
-  } catch (err) {
-    console.warn("全屏操作失败:", err);
-  }
+  //   // }
+  // } catch (err) {
+  //   console.warn("全屏操作失败:", err);
+  // }
 };
 // 监听用户按 ESC 退出全屏,同步状态
 const fullScreenChange = () => {