1
0
tangning 22 часов назад
Родитель
Сommit
b762ca1cf6

+ 124 - 33
src/view/case/photos/canvas-photo-editor.js

@@ -26,7 +26,7 @@ export class CanvasPhotoEditor {
     this.show = options.show || false // true 纯显示,不编辑
 
     // 响应式数据
-    this._layoutMode = 'single'//全局的页面布局
+    this._layoutMode = 'double'//全局的页面布局
     this._pages = [{
       list: [null],
       layoutMode: this._layoutMode,//排版模式
@@ -62,6 +62,14 @@ export class CanvasPhotoEditor {
       end: null,      // { x, y }
       drawing: false  // 是否正在绘制
     };
+    //修改pages页码
+    this.dragPageData = {
+      drawing: false,//是否正在绘制页面移动
+      index: -1,
+      start: null,    // { x, y }
+      end: null,      // { x, y }
+      movedIndex: -1,//移动到的索引位置
+    }
     //标引状态
     this.indexing = false//是否开启
     this.indexingNum = 0 //0 未点击  1 已生成开始点位 2 结束点位已生成
@@ -187,17 +195,19 @@ export class CanvasPhotoEditor {
   }
 
   // --- 核心:拖拽仅改坐标,不重绘 ---
-  handleMouseDown(e) {
+  async handleMouseDown(e) {
     if (e.target !== this.canvas) return
     // ==========================================
     // 🔥 页面拖拽排序:按下时记录
     // ==========================================
-    // if (this.selectedPageIndex !== -1 && !this.indexing) {
-    //   this.isPageDragging = true
-    //   this.dragPageStartY = e.clientY
-    //   this.dragPageMoved = false
-    //   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
+    if (this.dragPageData.drawing) {
+      this.dragPageData.end = { x: mouseX, y: mouseY }
+      this.drawAllPages()
+      return
+    }
     // 记录拖拽起始状态
     if (this.indexing) {
       if (this.indexingNum == 0) return this.starIindexing(e)
@@ -206,20 +216,6 @@ export class CanvasPhotoEditor {
     }
     const pageIndex = this.getPageIndexByClick(e)
     const oldPageIndex = this.selectedPageIndex; // 保存旧选中页
-    // if(pageIndex == this.selectedPageIndex && pageIndex != -1){
-    //   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
-    //   this.tempArrow.start = { x: mouseX, y: mouseY }
-    //   this.tempArrow.drawing = true;
-    //   return
-    // }
-    this.isDragging = true
-    this.dragStartX = e.clientX
-    this.dragStartY = e.clientY
-    this.lastDrawOffsetX = this.drawOffsetX
-    this.lastDrawOffsetY = this.drawOffsetY
-    this.canvas.style.cursor = 'grabbing'
     if (!this.show && pageIndex != undefined && pageIndex != -1 && (pageIndex !== this.selectedPageIndex || this._selectedPageItem.pageIndex != -1)) {
       // 1. 清除旧页面的边框
       // this.clearOldBorder(oldPageIndex);
@@ -232,22 +228,51 @@ export class CanvasPhotoEditor {
         pageIndex: -1,
       }
     }
+    console.log('pageIndex', this.pages, this.selectedPageItem, pageIndex)
+    if(oldPageIndex == pageIndex == this.selectedPageIndex == this.selectedPageItem.pageIndex && pageIndex != -1 && this.selectedPageItem.index == -1){
+      if(this.indexingLineList.length){
+        await this.checkIndexing('修改页面排序将会清除所有标引是否继续?')
+        this.drawAllPages()
+        return
+      }
+      this.dragPageData.start = { x: mouseX, y: mouseY }
+      this.dragPageData.drawing = true;
+      this.dragPageData.index = pageIndex;
+      this.dragPageData.movedIndex = pageIndex;
+      this.canvas.style.cursor = 'copy'
+      this.drawAllPages()
+      return
+    }
+    this.isDragging = true
+    this.dragStartX = e.clientX
+    this.dragStartY = e.clientY
+    this.lastDrawOffsetX = this.drawOffsetX
+    this.lastDrawOffsetY = this.drawOffsetY
+    this.canvas.style.cursor = 'grabbing'
     console.log('pageIndex', this.pages, this._selectedPageItem, this.selectedPageItem, pageIndex)
     this.drawAllPages()
   }
 
   handleMouseMove(e) {
     const drawing = this.tempArrow?.drawing
+    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
     if (this.indexing && drawing) {
-      const { x, y, } = this.tempArrow?.start
-      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
       this.tempArrow.end = {x: mouseX, y: mouseY }
       this.drawAllPages()
       return
     }
-    
+    if(this.dragPageData.drawing){
+      let endIndex = Math.round(mouseX / this.pageWidth)
+      this.dragPageData.end = { x: mouseX, y: mouseY }
+      let newEndIndex = endIndex<0?0:endIndex>this.pages.length-1?this.pages.length-1:endIndex
+      if(newEndIndex != this.dragPageData.movedIndex){
+        this.dragPageData.movedIndex = newEndIndex
+        this.drawAllPages()
+      }
+      return
+    }
     if (!this.isDragging) return
     // 仅更新坐标偏移,不触发重绘(核心优化)
     const deltaX = e.clientX - this.dragStartX
@@ -299,18 +324,33 @@ export class CanvasPhotoEditor {
     console.log('handleMouseUp', this.isDragging)
     this.isDragging = false
     this.canvas.style.cursor = 'grab'
+    if(this.dragPageData.drawing){//鼠标释放左键时,移动页面到指定位置)
+    // 末尾必须加分号!!!
+    let newPagelist = this.moveItem(this.pages, this.dragPageData.index, this.dragPageData.movedIndex)
+    this.pages = newPagelist;
+      this.drawAllPages()
+    }
+    this.dragPageData.drawing = false
+    this.dragPageData.movedIndex = 0
     // 松开鼠标后仅重绘一次,确认最终位置
     // this.drawDragPreview()
     // 选中页面(仅点击时重绘一次)
     console.log('pageIndex', this.indexing, this.indexingNum)
   }
-
+  moveItem(arr, fromIndex, toIndex) {
+    const newArr = [...arr]
+    const item = newArr.splice(fromIndex, 1)[0]
+    newArr.splice(toIndex, 0, item)
+    return newArr
+  }
   handleMouseLeave() {
     console.log('handleMouseLeave', this.isDragging)
     this.isDragging = false
+    this.dragPageData.drawing = false
+    this.dragPageData.movedIndex = 0
     this.canvas.style.cursor = 'grab'
     // 离开画布后重绘一次
-    // this.drawDragPreview()
+    this.drawDragPreview()
   }
 
   // --- 缩放逻辑(缩放必须重绘,无法通过坐标偏移实现)---
@@ -813,7 +853,7 @@ export class CanvasPhotoEditor {
         ctx.strokeStyle = pageIndex === this.selectedPageIndex
           ? this.selectedPageColor
           : '#dddddd'
-        ctx.lineWidth = pageIndex === this.selectedPageIndex ? 4 / this.scale : 2 / this.scale
+        ctx.lineWidth = pageIndex === this.selectedPageIndex ? 4 * this.scale : 2 * this.scale
         ctx.strokeRect(pageX, 0, this.pageWidth, this.pageHeight)
       }
 
@@ -861,10 +901,13 @@ export class CanvasPhotoEditor {
       })
     })
     ctx.restore()
-    console.log('this.tempArrow', this.tempArrow)
+    console.log('this.tempArrow', this.selectedPageItem)
     if(this.tempArrow.drawing && this.indexing){//绘制实时鼠标标引
         this.drawInterimLine([this.tempArrow.start,this.tempArrow.end])
     }
+    if(this.dragPageData.drawing && this.dragPageData.movedIndex){//绘制实时鼠标标引
+        this.drawPlusIcon(this.dragPageData.movedIndex)
+    }
     this.drawGuideLineAll(true)//绘制标引
   }
 
@@ -1643,10 +1686,10 @@ exportToPDF(paperType, name, fileType = 'pdf'){
     this.exportPagesAsImages(paperType, name);
   }
 }
-async checkIndexing(){
+async checkIndexing(mes = '此操作将会清除所有标引是否继续?'){
   let length = this.indexingLineList.length;
   // try {
-    if ( length && await ElMessageBox.confirm('此操作将会清除所有标引是否继续?', '提示') ) {
+    if ( length && await ElMessageBox.confirm(mes, '提示') ) {
       this.saveHistory();
       this.indexingLineList = [];
       return true;
@@ -1656,4 +1699,52 @@ async checkIndexing(){
   // }
   return false
 }
+//绘制移动page的目的地提示
+drawPlusIcon = (pageIndex) => {
+    const ctx = this.ctx;
+    const color = '#1677ff';
+    const lineWidth = 2;
+    const size = 60 * this.scale;
+    const r = 24 * this.scale 
+    // 1. 保存当前上下文状态(避免污染)
+    ctx.save();
+
+    // 2. 应用和全量绘制一致的偏移/缩放(保证坐标对齐)
+    ctx.translate(this.drawOffsetX, this.drawOffsetY);
+    ctx.scale(this.scale, this.scale);
+    const pageX = (pageIndex * (this.pageWidth + this.pageMargin)) - this.pageMargin / 2;
+    const arcY = 0-(size/2)
+    // 蓝色圆形
+    ctx.beginPath();
+    ctx.arc(pageX, arcY, r, 0, Math.PI * 2);
+    ctx.fillStyle = color;
+    ctx.fill();
+
+    // 白色加号
+    ctx.beginPath();
+    ctx.moveTo(pageX - size / 3, arcY);
+    ctx.lineTo(pageX + size / 3, arcY);
+    ctx.moveTo(pageX, arcY - size / 3);
+    ctx.lineTo(pageX, arcY + size / 3);
+    ctx.strokeStyle = '#fff';
+    ctx.lineWidth = lineWidth;
+    ctx.lineCap = 'round';
+    ctx.fill();
+    ctx.stroke();
+
+    ctx.beginPath();
+    ctx.moveTo(pageX, 0);
+    ctx.lineTo(pageX, this.pageHeight);
+    ctx.strokeStyle = color;
+    ctx.lineWidth = this.pageMargin;
+    ctx.fill();
+
+    ctx.stroke();
+    ctx.restore();
+  };
+  insertItemToArray(arr, item, toIndex) {
+    const newArr = [...arr]
+    newArr.splice(toIndex, 0, item)
+    return newArr
+  }
 }

+ 4 - 4
src/view/case/photos/index.vue

@@ -86,12 +86,12 @@
               >
               <el-dropdown-item command="single">
                 <i class="iconfont icon-layout_h"></i>
-                一页一
+                一张横板
               </el-dropdown-item
               >
               <el-dropdown-item command="landscape"
                 >
-                <i class="iconfont icon-layout_h"></i>竖版</el-dropdown-item
+                <i class="iconfont icon-layout_h"></i>一张竖版</el-dropdown-item
               >
             </el-dropdown-menu>
           </template>
@@ -203,12 +203,12 @@ const selectedPhotosbf = ref([]);
 const pages = ref([
   {
     list: [],
-    layoutMode: "single", //排版模式
+    layoutMode: "double", //排版模式
     coordinate: [], //坐标信息
   },
 ]);
 const scale = ref(1.0);
-const layoutMode = ref("single");
+const layoutMode = ref("double");
 const selectedPageIndex = ref(-1);
 const draggedPhoto = ref(null);
 const historylength = ref(0);

+ 1 - 1
src/view/material/sceneImg.vue

@@ -1144,7 +1144,7 @@ const handlemtk = (item) => {
 };
 const handleConfirm = async () => {
       let value = casePhotoItem.value.name;
-      if(!value){
+      if(!value || value.trim() == ""){
         return  ElMessage.error("请输入修改名称");;
       }
       await casePhotoUpdate({