Jelajahi Sumber

add: 裁剪图片

wzl 1 tahun lalu
induk
melakukan
eb8e68f7b3

+ 370 - 252
packages/core/src/editor/image_editor.js

@@ -351,7 +351,7 @@ export class ImageEditor {
   handleMouseDown (e) {
     if (e.button === 2) return // 右键点击不执行
 
-    if (this.state === 1) {
+    if (this.state > 0) {
       const operatorId = e.target.getAttribute('data-id')
     
       const { pageX, pageY } = getClickPoint(e)
@@ -362,27 +362,6 @@ export class ImageEditor {
       }
 
       document.addEventListener(this.mousemove, this.onMousemove)
-      
-    } else if (this.state === 2) {
-      if (isMobileDevice) {
-        const offsetX = e.changedTouches[0].clientX - this.pageViewer.div.getBoundingClientRect().left
-        const offsetY = e.changedTouches[0].clientY - this.pageViewer.div.getBoundingClientRect().top
-
-        this.startPoint = {
-          x: offsetX / this.scale,
-          y: offsetY / this.scale
-        }
-      } else {
-        const offsetX = e.offsetX
-        const offsetY = e.offsetY
-
-        this.startPoint = {
-          x: (offsetX + this.rect.left) / this.scale,
-          y: (offsetY + this.rect.top) / this.scale
-        }
-      }
-
-      this.imageContainer.addEventListener(this.mousemove, this.onMousemove)
     }
 
     document.addEventListener(this.mouseup, this.onMouseup)
@@ -410,23 +389,23 @@ export class ImageEditor {
       this.contentContainer.selectedFrameIndex = this.editAreaIndex
     }
 
-    if (this.state === 1) {
-      // this.frameContainer.classList.remove('editing')
+    const oldPoint = {
+      start: this.start,
+      end: this.end
+    }
+    const newPoint = {
+      start: this.newStart,
+      end: this.newEnd
+    }
 
-      const oldPoint = {
-        start: this.start,
-        end: this.end
-      }
-      const newPoint = {
-        start: this.newStart,
-        end: this.newEnd
-      }
+    const { pageX, pageY } = getClickPoint(e)
+    if (!(pageX === this.startState?.clickX && pageY === this.startState?.clickY) && this.newStart && this.newEnd) {
+      this.start = this.newStart
+      this.end = this.newEnd
+    }
 
-      const { pageX, pageY } = getClickPoint(e)
-      if (!(pageX === this.startState?.clickX && pageY === this.startState?.clickY) && this.newStart && this.newEnd) {
-        this.start = this.newStart
-        this.end = this.newEnd
-      }
+    if (this.state === 1) {
+      // this.frameContainer.classList.remove('editing')
       
       this.container.append(this.outerLine)
 
@@ -444,64 +423,37 @@ export class ImageEditor {
           editAreaPtr: this.editAreaPtr,
           rect
         })
-        this.updateCanvas({oldPoint, newPoint})
 
+        this.updateCanvas({oldPoint, newPoint})
+        this.frameContainer.classList.add('selected')
       }
-      // else if (!this.mouseMoved && flag) {
-      //   this.state = 2
-      //   if (isMobileDevice) {
-      //     this.eventBus.dispatch('changeIsEditorPanelDisabled')
-      //   } else {
-      //     this.eventBus.dispatch('contentPropertyChange', { type: 'image', isOpen: true })
-      //   }
-      // }
-    }
-    
-    if (this.state === 2) {
-      this.outerLine.remove()
-      this.frameContainer.classList.add('editing')
-
-      let endPoint
-      if (isMobileDevice) {
-        const offsetX = e.changedTouches[0].clientX - this.pageViewer.div.getBoundingClientRect().left
-        const offsetY = e.changedTouches[0].clientY - this.pageViewer.div.getBoundingClientRect().top
-
-        endPoint = {
-          x: offsetX / this.scale,
-          y: offsetY / this.scale
-        }
-      } else {
-        const offsetX = e.offsetX
-        const offsetY = e.offsetY
-
-        endPoint = {
-          x: (offsetX + this.rect.left) / this.scale,
-          y: (offsetY + this.rect.top) / this.scale
-        }
-      }
-      
-      if (this.mouseMoved) {
-        endPoint = this.endPoint
-        this.cursor.style.display = 'block'
-      }
-      if (!this.startPoint) {
-        this.startPoint = endPoint
+    } else if (this.state === 2 && this.mouseMoved) {
+      const { start, end } = this.getInitialPoint(this.newStart, this.newEnd)
+      const rect = {
+        left: start.x,
+        top: start.y,
+        right: end.x,
+        bottom: end.y
       }
+      console.log(this.rect)
 
-      // this.textarea.focus()
-      // this.textarea.addEventListener('keydown', this.onKeydown)
-      // this.textarea.addEventListener(this.textInput, this.onTextInput)
-    }
+      await this.messageHandler.sendWithPromise('CutWithRect', {
+        pagePtr: this.pagePtr,
+        editAreaPtr: this.editAreaPtr,
+        rect
+      })
 
-    this.frameContainer.classList.add('selected')
+      await this.saveEdit()
+      this.updateCanvas()
+      console.log(this.rect)
+    }
 
-    if (this.state === 1) {
+    if (this.state > 0) {
       onClickOutside([this.imageContainer, this.outerLine, document.querySelector('.editor-panel'), document.getElementById('propertyPanelButton')], this.handleOutside.bind(this))
     }
     
     document.removeEventListener(this.mousemove, this.onMousemove)
     document.removeEventListener(this.mouseup, this.onMouseup)
-
     this.imageContainer.removeEventListener(this.mousemove, this.onMousemove)
   }
 
@@ -512,133 +464,141 @@ export class ImageEditor {
       document.body.style.overscrollBehavior = 'none';
     }
 
-    if (this.state === 1) {
-      const { pageX, pageY } = getClickPoint(e)
-      const start = this.start
-      const end = this.end
-      const startState = this.startState
-      if (!startState) return
-      if (startState.clickX === pageX && startState.clickY === pageY) return
-
-      const { width, height } = this.viewport
-      if (startState.operator === 'nw-resize') {
-        let x1 = pageX - (startState.clickX - this.start.x);
-        let y1 = pageY - (startState.clickY - this.start.y);
-        x1 = Math.min(end.x - 5, x1)
-        x1 = Math.max(0, x1)
-        y1 = Math.min(end.y - 5, y1)
-        y1 = Math.max(0, y1)
-
-        this.updateOutline({
-          start: { x: x1, y: y1 },
-          end,
-        });
-      } else if (startState.operator === 'w-resize') {
-        let x1 = pageX - (startState.clickX - this.start.x);
-        x1 = Math.min(end.x - 5, x1)
-        x1 = Math.max(0, x1)
-
-        this.updateOutline({
-          start: { x: x1, y: start.y },
-          end,
-        });
-      } else if (startState.operator === 'sw-resize') {
-        let x1 = pageX - (startState.clickX - this.start.x);
-        let y1 = pageY - (startState.clickY - this.end.y);
-        x1 = Math.min(end.x - 5, x1)
-        x1 = Math.max(0, x1)
-        y1 = Math.min(height, y1)
-        y1 = Math.max(start.y + 5, y1)
-
-        this.updateOutline({
-          start: { x: x1, y: start.y },
-          end: { x: end.x, y: y1 },
-        });
-      } else if (startState.operator === 's-resize') {
-        let y1 = pageY - (startState.clickY - this.end.y);
-        y1 = Math.min(height, y1)
-        y1 = Math.max(start.y + 5, y1)
-        this.updateOutline({
-          start,
-          end: { x: end.x, y: y1 },
-        });
-      } else if (startState.operator === 'se-resize') {
-        let x = pageX - (startState.clickX - this.end.x);
-        let y = pageY - (startState.clickY - this.end.y);
-        x = Math.min(width, x)
-        x = Math.max(start.x + 5, x)
-        y = Math.min(height, y)
-        y = Math.max(start.y + 5, y)
-        this.updateOutline({
-          start,
-          end: { x, y },
-        });
-      } else if (startState.operator === 'e-resize') {
-        let x = pageX - (startState.clickX - this.end.x);
-        x = Math.min(width, x)
-        x = Math.max(start.x + 5, x)
-        this.updateOutline({
-          start,
-          end: { x, y: end.y },
-        });
-      } else if (startState.operator === 'ne-resize') {
-        let x = pageX - (startState.clickX - this.end.x);
-        let y = pageY - (startState.clickY - this.start.y);
-        x = Math.min(width, x)
-        x = Math.max(start.x + 5, x)
-        y = Math.min(end.y - 5, y)
-        y = Math.max(0, y)
-        this.updateOutline({
-          start: { x: start.x, y },
-          end: { x, y: end.y },
-        });
-      } else if (startState.operator === 'n-resize') {
-        let y = pageY - (startState.clickY - this.start.y);
-        y = Math.min(end.y - 5, y)
-        y = Math.max(0, y)
-        this.updateOutline({
-          start: { x: start.x, y },
-          end,
-        });
-      } else if (startState.operator === 'move') {
-        let x1 = pageX - (startState.clickX - this.start.x);
-        let y1 = pageY - (startState.clickY - this.start.y);
-        let x2 = pageX - (startState.clickX - this.end.x);
-        let y2 = pageY - (startState.clickY - this.end.y);
+    const { pageX, pageY } = getClickPoint(e)
 
-        const rect = {
-          width: Math.abs(start.x -end.x),
-          height: Math.abs(start.y -end.y)
-        }
-        if (x1 < x2) {
-          x1 = Math.max(0, x1)
-          x1 = Math.min(width - rect.width, x1)
-          x2 = Math.max(rect.width, x2)
-          x2 = Math.min(width, x2)
-        } else {
-          x2 = Math.max(0, x2)
-          x2 = Math.min(width - rect.width, x2)
-          x1 = Math.max(rect.width, x1)
-          x1 = Math.min(width, x1)
-        }
+    const start = this.start
+    const end = this.end
+    const startState = this.startState
 
-        if (y1 < y2) {
-          y1 = Math.max(0, y1)
-          y1 = Math.min(height - rect.height, y1)
-          y2 = Math.max(rect.height, y2)
-          y2 = Math.min(height, y2)
-        } else {
-          y2 = Math.max(0, y2)
-          y2 = Math.min(height - rect.height, y2)
-          y1 = Math.max(rect.height, y1)
-          y1 = Math.min(height, y1)
-        }
+    if (!startState) return
+    if (startState.clickX === pageX && startState.clickY === pageY) return
+
+    const { width, height } = this.viewport
+    if (startState.operator === 'nw-resize') {
+      let x = pageX - (startState.clickX - start.x);
+      let y = pageY - (startState.clickY - start.y);
+      x = Math.min(end.x - 2, x)
+      x = Math.max(this.state === 2 ? start.x : 0, x)
+      y = Math.min(end.y - 2, y)
+      y = Math.max(this.state === 2 ? start.y : 0, y)
+
+      this.updateOutline({
+        start: { x, y },
+        end: { x: end.x, y: end.y },
+      });
+    } else if (startState.operator === 'w-resize') {
+      let x = pageX - (startState.clickX - start.x);
+      x = Math.min(end.x - 2, x)
+      x = Math.max(this.state === 2 ? start.x : 0, x)
+
+      this.updateOutline({
+        start: { x, y: start.y },
+        end: { x: end.x, y: end.y },
+      });
+    } else if (startState.operator === 'sw-resize') {
+      let x = pageX - (startState.clickX - start.x);
+      let y = pageY - (startState.clickY - end.y);
+      x = Math.min(end.x - 2, x)
+      x = Math.max(this.state === 2 ? start.x : 0, x)
+      y = Math.min(this.state === 2 ? end.y : height, y)
+      y = Math.max(start.y + 2, y)
+
+      this.updateOutline({
+        start: { x, y: start.y },
+        end: { x: end.x, y },
+      });
+    } else if (startState.operator === 's-resize') {
+      let y = pageY - (startState.clickY - end.y);
+      y = Math.min(this.state === 2 ? end.y : height, y)
+      y = Math.max(start.y + 2, y)
+
+      this.updateOutline({
+        start: { x: start.x, y: start.y },
+        end: { x: end.x, y },
+      });
+    } else if (startState.operator === 'se-resize') {
+      let x = pageX - (startState.clickX - end.x);
+      let y = pageY - (startState.clickY - end.y);
+      x = Math.min(this.state === 2 ? end.x : width, x)
+      x = Math.max(start.x + 2, x)
+      y = Math.min(this.state === 2 ? end.y : height, y)
+      y = Math.max(start.y + 2, y)
+
+      this.updateOutline({
+        start: { x: start.x, y: start.y },
+        end: { x, y },
+      });
+    } else if (startState.operator === 'e-resize') {
+      let x = pageX - (startState.clickX - end.x);
+      x = Math.min(this.state === 2 ? end.x : width, x)
+      x = Math.max(start.x + 2, x)
+
+      this.updateOutline({
+        start: { x: start.x, y: start.y },
+        end: { x, y: end.y },
+      });
+    } else if (startState.operator === 'ne-resize') {
+      let x = pageX - (startState.clickX - end.x);
+      let y = pageY - (startState.clickY - start.y);
+      x = Math.min(this.state === 2 ? end.x : width, x)
+      x = Math.max(start.x + 2, x)
+      y = Math.min(end.y - 2, y)
+      y = Math.max(this.state === 2 ? start.y : 0, y)
+
+      this.updateOutline({
+        start: { x: start.x, y },
+        end: { x, y: end.y },
+      });
+    } else if (startState.operator === 'n-resize') {
+      let y = pageY - (startState.clickY - start.y);
+      y = Math.min(end.y - 2, y)
+      y = Math.max(this.state === 2 ? start.y : 0, y)
+
+      this.updateOutline({
+        start: { x: start.x, y },
+        end: { x: end.x, y: end.y },
+      });
+    } else if (startState.operator === 'move') {
+      if (this.state === 2) return
+
+      let x1 = pageX - (startState.clickX - start.x);
+      let y1 = pageY - (startState.clickY - start.y);
+      let x2 = pageX - (startState.clickX - end.x);
+      let y2 = pageY - (startState.clickY - end.y);
+
+      const rect = {
+        width: Math.abs(start.x - end.x),
+        height: Math.abs(start.y - end.y)
+      }
+      
+      if (x1 < x2) {
+        x1 = Math.max(this.state === 2 ? start.x : 0, x1)
+        x1 = Math.min(this.state === 2 ? end.x - rect.width : width - rect.width, x1)
+        x2 = Math.max(this.state === 2 ? start.x + rect.width : rect.width, x2)
+        x2 = Math.min(this.state === 2 ? end.x : width, x2)
+      } else {
+        x2 = Math.max(this.state === 2 ? start.x : 0, x2)
+        x2 = Math.min(this.state === 2 ? end.x - rect.width : width - rect.width, x2)
+        x1 = Math.max(this.state === 2 ? start.x + rect.width : rect.width, x1)
+        x1 = Math.min(this.state === 2 ? end.x : width, x1)
+      }
 
-        this.updateOutline({
-          start: { x: x1, y: y1 },
-          end: { x: x2, y: y2 },
-        });
+      if (y1 < y2) {
+        y1 = Math.max(this.state === 2 ? start.y : 0, y1)
+        y1 = Math.min(this.state === 2 ? end.y - rect.height : height - rect.height, y1)
+        y2 = Math.max(this.state === 2 ? start.y + rect.height : rect.height, y2)
+        y2 = Math.min(this.state === 2 ? end.y : height, y2)
+      } else {
+        y2 = Math.max(this.state === 2 ? start.y : 0, y2)
+        y2 = Math.min(this.state === 2 ? end.y - rect.height : height - rect.height, y2)
+        y1 = Math.max(this.state === 2 ? start.y + rect.height : rect.height, y1)
+        y1 = Math.min(this.state === 2 ? end.y : height, y1)
       }
+
+      this.updateOutline({
+        start: { x: x1, y: y1 },
+        end: { x: x2, y: y2 },
+      });
     }
 
     this.mouseMoved = true
@@ -654,43 +614,24 @@ export class ImageEditor {
   }
 
   async handleOutside () {
-    this.state = this.state === 2 ? 1 : this.state === 1 ? 0 : this.state
+    this.state = 0
 
-    this.frameContainer.classList.remove('editing')
+    this.updateRectStyle()
 
-    this.eventBus.dispatch('contentPropertyChange', { type: 'image', isOpen: false })
-
-    this.cursor?.remove()
-    this.cursor = null
-
-    if (this.state === 0) {
-      this.frameContainer.classList.remove('selected')
-
-      this.outerLine.remove()
-
-      this.contentContainer.selectedFrameIndex = -1
-    }
-
-    if (this.state === 1) {
-      document.getElementById('propertyPanelButton').click()
+    this.updateOutline({
+      start: this.start,
+      end: this.end
+    })
 
-      const text = await this.getText()
-      if (text.length === 0) {
-        await this.outerLine.remove()
-        this.contentContainer.selectedFrameIndex = -1
-        this.remove()
-        return
-      }
+    this.frameContainer.classList.remove('editing')
 
-      this.container.append(this.outerLine)
+    this.eventBus.dispatch('contentPropertyChange', { type: 'image', isOpen: false })
 
-      this.imageContainer.removeEventListener(this.mousemove, this.onMousemove)
+    this.frameContainer.classList.remove('selected')
 
-      onClickOutside([this.imageContainer, this.outerLine, document.querySelector('.editor-panel'), document.getElementById('propertyPanelButton')], this.handleOutside.bind(this))
-    }
+    this.outerLine.remove()
 
-    // this.textarea.removeEventListener('keydown', this.onKeydown)
-    // this.textarea.removeEventListener(this.textInput, this.onTextInput)
+    this.contentContainer.selectedFrameIndex = -1
   }
 
   async handleKeyDown (e) {
@@ -762,7 +703,7 @@ export class ImageEditor {
 
   // 获取rect
   async getRect () {
-    this.frame = await this.messageHandler.sendWithPromise('GetFrame', {
+    this.frame = await this.messageHandler.sendWithPromise('GetClipRect', {
       pagePtr: this.pagePtr,
       editAreaPtr: this.editAreaPtr
     })
@@ -910,8 +851,8 @@ export class ImageEditor {
   }
 
   // 保存编辑
-  saveEdit () {
-    this.messageHandler.sendWithPromise('EndEdit', this.editPagePtr)
+  async saveEdit () {
+    await this.messageHandler.sendWithPromise('EndEdit', this.editPagePtr)
   }
 
   // 更新outerline框的位置大小
@@ -930,26 +871,65 @@ export class ImageEditor {
 
     this.moveRect.setAttribute('width', rect.width - this.borderWidth)
     this.moveRect.setAttribute('height', rect.height - this.borderWidth)
-    
-    this.LeftRect.setAttribute("y", (rect.height - this.pointHeight + this.borderWidth) / 2)
 
-    this.bottomLeftRect.setAttribute("y", rect.height - this.pointHeight / 2 + this.borderWidth / 2)
+    this.LeftRect.setAttribute('y', (rect.height - this.pointHeight + this.borderWidth) / 2)
 
-    this.bottomRect.setAttribute("x", (rect.width - this.pointWidth + this.borderWidth) / 2)
-    this.bottomRect.setAttribute("y", rect.height - this.pointHeight / 2 + this.borderWidth / 2)
+    this.bottomRect.setAttribute('x', (rect.width - this.pointWidth + this.borderWidth) / 2)
+    this.bottomRect.setAttribute('y', rect.height - this.pointHeight / 2 + this.borderWidth / 2)
 
+    this.rightRect.setAttribute('x', rect.width - this.pointWidth / 2 + this.borderWidth / 2)
+    this.rightRect.setAttribute('y', (rect.height - this.pointHeight + this.borderWidth) / 2)
 
-    this.bottomRightRect.setAttribute("x", rect.width - this.pointWidth / 2 + this.borderWidth / 2)
-    this.bottomRightRect.setAttribute("y", rect.height - this.pointHeight / 2 + this.borderWidth / 2)
+    this.topRect.setAttribute('x', (rect.width - this.pointWidth + this.borderWidth) / 2)
 
+    if (this.state === 2) {
+      const long = 15
 
-    this.rightRect.setAttribute("x", rect.width - this.pointWidth / 2 + this.borderWidth / 2)
-    this.rightRect.setAttribute("y", (rect.height - this.pointHeight + this.borderWidth) / 2)
+      this.LeftRect.setAttribute('y', (rect.height - long + this.borderWidth) / 2)
+      this.topRect.setAttribute('x', (rect.width - long + this.borderWidth) / 2)
+      this.rightRect.setAttribute('y', (rect.height - long + this.borderWidth) / 2)
+      this.bottomRect.setAttribute('x', (rect.width - long + this.borderWidth) / 2)
 
-    
-    this.topRightRect.setAttribute("x", rect.width - this.pointWidth / 2 + this.borderWidth / 2)
+      this.topRightRect.setAttribute('d', `M${rect.width + this.borderWidth / 2 - long + this.pointWidth / 2},${this.pointWidth / 2} H${rect.width + this.borderWidth / 2} V${long}`)
+      
+      this.bottomLeftRect.setAttribute('d', `M${this.pointWidth / 2},${rect.height + this.borderWidth / 2 - long + this.pointWidth / 2} V${rect.height + this.borderWidth / 2} H${long}`)
+
+      this.bottomRightRect.setAttribute('d', `M${rect.width + this.borderWidth / 2},${rect.height + this.borderWidth / 2 - long + this.pointWidth / 2} V${rect.height + this.borderWidth / 2} H${rect.width + this.borderWidth / 2 - long + this.pointWidth / 2}`)
+
+      const offsetLeft = rect.left - this.rect.left
+      const offsetTop = rect.top - this.rect.top
+      const offsetRight = this.rect.left + this.rect.width - rect.left - rect.width
+      const offsetBottom = this.rect.top + this.rect.height - rect.top - rect.height
+
+      switch (this.startState.operator) {
+        case 'sw-resize':
+          this.frameContainer.style['box-shadow'] = `inset ${offsetLeft}px ${-offsetBottom}px rgba(0, 0, 0, 0.5)`
+          break;
+
+        case 'ne-resize':
+          this.frameContainer.style['box-shadow'] = `inset ${-offsetRight}px ${offsetTop}px rgba(0, 0, 0, 0.5)`
+          break;
+
+        case 'nw-resize':
+        case 'n-resize':
+        case 'w-resize':
+          this.frameContainer.style['box-shadow'] = `inset ${offsetLeft}px ${offsetTop}px rgba(0, 0, 0, 0.5)`
+          break;
+      
+        case 'se-resize':
+        case 's-resize':
+        case 'e-resize':
+          this.frameContainer.style['box-shadow'] = `inset ${-offsetRight}px ${-offsetBottom}px rgba(0, 0, 0, 0.5)`
+          break;
+      }
+    } else {
+      this.bottomLeftRect.setAttribute('y', rect.height - this.pointHeight / 2 + this.borderWidth / 2)
 
-    this.topRect.setAttribute("x", (rect.width - this.pointWidth + this.borderWidth) / 2)
+      this.bottomRightRect.setAttribute('x', rect.width - this.pointWidth / 2 + this.borderWidth / 2)
+      this.bottomRightRect.setAttribute('y', rect.height - this.pointHeight / 2 + this.borderWidth / 2)
+
+      this.topRightRect.setAttribute('x', rect.width - this.pointWidth / 2 + this.borderWidth / 2)
+    }
   }
 
   async setProperty(props) {
@@ -1100,6 +1080,15 @@ export class ImageEditor {
         const { imageArray } = await this.messageHandler.sendWithPromise('ExtractOriginalImage', this.editAreaPtr)
         console.log(imageArray)
       }
+
+      if (item === 'tool' && props.tool === 'crop') {
+        if (this.state === 2) return
+        this.state = 2
+        this.frameContainer.classList.add('editing')
+        this.moveRect.style.cursor = 'auto'
+        this.updateRectStyle()
+        return
+      }
     }
 
     const oldRect = this.rect
@@ -1250,4 +1239,133 @@ export class ImageEditor {
 
     this.eventBus.dispatch('contentPropertyChange', { type: 'image', overviewImageSrc })
   }
+
+  // 更新点的位置
+  updateRectStyle () {
+    this.topLeftRect.remove()
+    this.topRightRect.remove()
+    this.bottomLeftRect.remove()
+    this.bottomRightRect.remove()
+
+    if (this.state === 2) {
+      const long = 15
+
+      this.LeftRect.setAttribute('height', long)
+      this.LeftRect.setAttribute('y', (this.rect.height - long + this.borderWidth) / 2)
+      this.topRect.setAttribute('width', long)
+      this.topRect.setAttribute('x', (this.rect.width - long + this.borderWidth) / 2)
+      this.rightRect.setAttribute('height', long)
+      this.rightRect.setAttribute('y', (this.rect.height - long + this.borderWidth) / 2)
+      this.bottomRect.setAttribute('width', long)
+      this.bottomRect.setAttribute('x', (this.rect.width - long + this.borderWidth) / 2)
+
+      this.topLeftRect = createSvg(
+        "path",
+        {
+          class: "nw-resize",
+          'data-id': "nw-resize",
+          fill: "none",
+          stroke: "#1460F3",
+          'stroke-width': this.pointWidth,
+          // d: 'M15,3 H3 V15',
+          d: `M${long},${this.pointWidth / 2} H${this.pointWidth / 2} V${long}`
+        }
+      )
+      this.topRightRect = createSvg(
+        "path",
+        {
+          class: "ne-resize",
+          'data-id': "ne-resize",
+          fill: "none",
+          stroke: "#1460F3",
+          'stroke-width': this.pointWidth,
+          d: `M${this.rect.width + this.borderWidth / 2 - long + this.pointWidth / 2},${this.pointWidth / 2} H${this.rect.width + this.borderWidth / 2} V${long}`
+        }
+      )
+      this.bottomLeftRect = createSvg(
+        "path",
+        {
+          class: "sw-resize",
+          'data-id': "sw-resize",
+          fill: "none",
+          stroke: "#1460F3",
+          'stroke-width': this.pointWidth,
+          d: `M${this.pointWidth / 2},${this.rect.height + this.borderWidth / 2 - long + this.pointWidth / 2} V${this.rect.height + this.borderWidth / 2} H${long}`
+        }
+      )
+      this.bottomRightRect = createSvg(
+        "path",
+        {
+          class: "se-resize",
+          'data-id': "se-resize",
+          fill: "none",
+          stroke: "#1460F3",
+          'stroke-width': this.pointWidth,
+          d: `M${this.rect.width + this.borderWidth / 2},${this.rect.height + this.borderWidth / 2 - long + this.pointWidth / 2} V${this.rect.height + this.borderWidth / 2} H${this.rect.width + this.borderWidth / 2 - long + this.pointWidth / 2}`
+        }
+      )
+    } else {
+      this.LeftRect.setAttribute('height', this.pointHeight)
+      this.topRect.setAttribute('width', this.pointWidth)
+      this.rightRect.setAttribute('height', this.pointHeight)
+      this.bottomRect.setAttribute('width', this.pointWidth)
+
+      this.topLeftRect = createSvg(
+        "rect",
+        {
+          class: "nw-resize",
+          'data-id': "nw-resize",
+          fill: "#1460F3",
+          stroke: "none",
+          width: this.pointWidth,
+          height: this.pointHeight,
+          x: 0,
+          y: 0
+        }
+      )
+      this.topRightRect = createSvg(
+        "rect",
+        {
+          class: "ne-resize",
+          'data-id': "ne-resize",
+          fill: "#1460F3",
+          stroke: "none",
+          width: this.pointWidth,
+          height: this.pointHeight,
+          x: this.rect.width - this.pointWidth / 2 + this.borderWidth / 2,
+          y: 0
+        }
+      )
+      this.bottomLeftRect = createSvg(
+        "rect",
+        {
+          class: "sw-resize",
+          'data-id': "sw-resize",
+          fill: "#1460F3",
+          stroke: "none",
+          width: this.pointWidth,
+          height: this.pointHeight,
+          x: 0,
+          y: this.rect.height - this.pointHeight / 2 + this.borderWidth / 2
+        }
+      )
+      this.bottomRightRect = createSvg(
+        "rect",
+        {
+          class: "se-resize",
+          'data-id': "se-resize",
+          fill: "#1460F3",
+          stroke: "none",
+          width: this.pointWidth,
+          height: this.pointHeight,
+          x: this.rect.width - this.pointWidth / 2 + this.borderWidth / 2,
+          y: this.rect.height - this.pointHeight / 2 + this.borderWidth / 2
+        }
+      )
+    }
+    this.outerLine.append(this.topLeftRect)
+    this.outerLine.append(this.topRightRect)
+    this.outerLine.append(this.bottomLeftRect)
+    this.outerLine.append(this.bottomRightRect)
+  }
 }

+ 31 - 2
packages/core/src/worker/compdfkit_worker.js

@@ -31,7 +31,7 @@ let EditTextStyle = {}
 let U8StringData = ''
 let PDFRange = {}
 let TextRectArray = []
-let ImageAreaInfo = {}
+ImageAreaInfo = {}
 
 import MessageHandler from "../message_handler"
 import { convertFileToBuffer, convertBase64ToBytes } from '../fileHandler';
@@ -1291,10 +1291,39 @@ class CPDFWorker {
     })
 
     messageHandler.on('ExtractThumbImage', (data) => {
-      const { editAreaPtr, width, height } = data
+      // const { editAreaPtr, width, height } = data
       const imageArray = extractImage(data, 1)
       return { imageArray }
     })
+
+    messageHandler.on('CutWithRect', (data) => {
+      const { pagePtr, editAreaPtr, rect } = data
+
+      const res = Module._CutWithRect(
+        pagePtr,
+        editAreaPtr,
+        rect.left,
+        rect.right,
+        rect.bottom,
+        rect.top
+      )
+      console.log('CutWithRect: ', res)
+    })
+
+    messageHandler.on('GetClipRect', (data) => {
+      const { pagePtr, editAreaPtr } = data
+
+      Rect = {}
+
+      Module._GetFrame(pagePtr, editAreaPtr)
+
+      return {
+        left: Rect.Left,
+        top: Rect.Top,
+        right: Rect.Right,
+        bottom: Rect.Bottom
+      }
+    })
   }
 }
 

+ 2 - 2
packages/webview/src/components/ContentEditorPanel/ContentEditorPanel.vue

@@ -119,12 +119,12 @@
           </div>
           <div @click="setProperty('tool', 'export')" :title="$t('editorPanel.export')">
             <span>
-              <DownloadImage />
+              <ExportImage />
             </span>
           </div>
           <div @click="setProperty('tool', 'crop')" :title="$t('editorPanel.crop')">
             <span>
-              <TailorImage />
+              <CropImage />
             </span>
           </div>
         </div>

packages/webview/src/components/Icon/TailorImage.vue → packages/webview/src/components/Icon/CropImage.vue


packages/webview/src/components/Icon/DownloadImage.vue → packages/webview/src/components/Icon/ExportImage.vue