Browse Source

add: 内容编辑修改添加图片逻辑

liutian 7 months ago
parent
commit
50dd858334

+ 0 - 2
packages/core/src/annotation/utils.js

@@ -26,8 +26,6 @@ export function getAbsoluteCoordinate (ele, event) {
   const coordinate = {
     x: pageX - rect.left - offsetX,
     y: pageY - rect.top - offsetY,
-    width: rect.width - offsetX,
-    height: rect.height - offsetY
   };
 
   return coordinate

+ 60 - 55
packages/core/src/editor/add_image.js

@@ -32,8 +32,6 @@ export default class AddImage {
     this.onMousedown = this.handleMouseDown.bind(this)
     this.onMouseup = this.handleMouseUp.bind(this)
     this.onMousemove = this.handleMouseMove.bind(this)
-
-    this.init()
   }
 
   init () {
@@ -80,6 +78,58 @@ export default class AddImage {
     this.container.removeEventListener('touchstart', this.onMousedown)
   }
 
+  getRect (width, height, point) {
+    const pageWidth = this.viewport.viewBox[2]
+    const pageHeight = this.viewport.viewBox[3]
+    const fixedWidth = pageWidth / 2
+    const fixedHeight = pageHeight / 2
+
+    let scaledWidth = width
+    let scaledHeight = height
+
+    if (width > fixedWidth || height > fixedHeight) {
+      const imageRatio = width / height
+      const rectRatio = fixedWidth / fixedHeight
+
+      if (imageRatio > rectRatio) {
+        scaledWidth = fixedWidth
+        scaledHeight = fixedWidth / imageRatio
+      } else {
+        scaledWidth = fixedHeight * imageRatio
+        scaledHeight = fixedHeight
+      }
+    }
+
+    const rect = {
+      left: point.x - scaledWidth / 2,
+      top: point.y - scaledHeight / 2,
+      right: point.x + scaledWidth / 2,
+      bottom: point.y + scaledHeight / 2,
+    }
+
+    if (rect.left < 7) {
+      const offset = 7 - rect.left
+      rect.left += offset
+      rect.right += offset
+    }
+    if (rect.top < 7) {
+      const offset = 7 - rect.top
+      rect.top += offset
+      rect.bottom += offset
+    }
+    if (rect.right > pageWidth) {
+      const offset = rect.right - pageWidth + 7
+      rect.right -= offset
+      rect.left -= offset
+    }
+    if (rect.bottom > pageHeight) {
+      const offset = rect.bottom - pageHeight + 7
+      rect.bottom -= offset
+      rect.top -= offset
+    }
+    return rect
+  }
+
   handleMouseDown (event) {
     if (this.contentContainer.selectedFrameIndex !== -1) return
     if (!event.target.className && !event.target.className.includes('contentContainer')) return
@@ -88,6 +138,7 @@ export default class AddImage {
     const { x, y } = getAbsoluteCoordinate(this.container, event)
     this.initStartPoint = { x, y }
 
+    if (this.contentContainer.pageViewer.toolMode === 'annotation')  return
     document.addEventListener('mousemove', this.onMousemove)
     document.addEventListener('mouseup', this.onMouseup)
     
@@ -137,16 +188,16 @@ export default class AddImage {
             scaledHeight = area.height
           }
           
-          const centerPoint = {
+          const point = {
             x: area.left + area.width / 2,
             y: area.top + area.height / 2
           }
 
           const rect = {
-            left: centerPoint.x - scaledWidth / 2,
-            top: centerPoint.y - scaledHeight / 2,
-            right: centerPoint.x + scaledWidth / 2,
-            bottom: centerPoint.y + scaledHeight / 2,
+            left: point.x - scaledWidth / 2,
+            top: point.y - scaledHeight / 2,
+            right: point.x + scaledWidth / 2,
+            bottom: point.y + scaledHeight / 2,
           }
 
           this.contentContainer.addImageEditor({
@@ -158,59 +209,13 @@ export default class AddImage {
           console.error(error)
         })
     } else { // 单击区域
-      const centerPoint = getInitialPoint(initStartPoint, this.viewport, this.viewport.scale)
-      const pageWidth = this.viewport.viewBox[2]
-      const pageHeight = this.viewport.viewBox[3]
-      const fixedWidth = pageWidth / 2
-      const fixedHeight = pageHeight / 2
+      const point = getInitialPoint(initStartPoint, this.viewport, this.viewport.scale)
 
       this.uploadFile()
         .then((data) => {
           const { imageBase64, width, height } = data
 
-          let scaledWidth = width
-          let scaledHeight = height
-
-          if (width > fixedWidth || height > fixedHeight) {
-            const imageRatio = width / height
-            const rectRatio = fixedWidth / fixedHeight
-      
-            if (imageRatio > rectRatio) {
-              scaledWidth = fixedWidth
-              scaledHeight = fixedWidth / imageRatio
-            } else {
-              scaledWidth = fixedHeight * imageRatio
-              scaledHeight = fixedHeight
-            }
-          }
-
-          const rect = {
-            left: centerPoint.x - scaledWidth / 2,
-            top: centerPoint.y - scaledHeight / 2,
-            right: centerPoint.x + scaledWidth / 2,
-            bottom: centerPoint.y + scaledHeight / 2,
-          }
-
-          if (rect.left < 7) {
-            const offset = 7 - rect.left
-            rect.left += offset
-            rect.right += offset
-          }
-          if (rect.top < 7) {
-            const offset = 7 - rect.top
-            rect.top += offset
-            rect.bottom += offset
-          }
-          if (rect.right > pageWidth) {
-            const offset = rect.right - pageWidth + 7
-            rect.right -= offset
-            rect.left -= offset
-          }
-          if (rect.bottom > pageHeight) {
-            const offset = rect.bottom - pageHeight + 7
-            rect.bottom -= offset
-            rect.top -= offset
-          }
+          const rect = this.getRect(width, height, point)
 
           this.contentContainer.addImageEditor({
             rect,

+ 75 - 4
packages/core/src/editor/content_container.js

@@ -221,10 +221,8 @@ export class ContentContainer {
     }
   }
 
-  addImageManager () {
-    if (this.imageManager) {
-      this.imageManager.init()
-    } else {
+  async addImageManager (imageData) {
+    if (!this.imageManager) {
       this.imageManager = new AddImage({
         tool: this.tool,
         color: this.color,
@@ -237,6 +235,79 @@ export class ContentContainer {
         $t: this.$t
       })
     }
+    if (imageData) {
+      const { imageBase64, width, height, point, preview } = imageData
+      const rect = this.getRect(width, height, point)
+
+      if (preview)  {
+        await this.addImageEditor({
+          rect,
+          imageBase64
+        })
+        return
+      }
+      await this.messageHandler.sendWithPromise('CreateNewImageAreaByStream', {
+        pagePtr: this.pagePtr,
+        editPagePtr: this.editPagePtr,
+        rect,
+        imageBase64
+      })
+      await this.messageHandler.sendWithPromise('EndEdit', this.editPagePtr)
+    } else {
+      this.imageManager.init()
+    }
+  }
+
+  getRect (width, height, point) {
+    const pageWidth = this.viewport.viewBox[2]
+    const pageHeight = this.viewport.viewBox[3]
+    const fixedWidth = pageWidth / 2
+    const fixedHeight = pageHeight / 2
+
+    let scaledWidth = width
+    let scaledHeight = height
+
+    if (width > fixedWidth || height > fixedHeight) {
+      const imageRatio = width / height
+      const rectRatio = fixedWidth / fixedHeight
+
+      if (imageRatio > rectRatio) {
+        scaledWidth = fixedWidth
+        scaledHeight = fixedWidth / imageRatio
+      } else {
+        scaledWidth = fixedHeight * imageRatio
+        scaledHeight = fixedHeight
+      }
+    }
+
+    const rect = {
+      left: point.x - scaledWidth / 2,
+      top: point.y - scaledHeight / 2,
+      right: point.x + scaledWidth / 2,
+      bottom: point.y + scaledHeight / 2,
+    }
+
+    if (rect.left < 7) {
+      const offset = 7 - rect.left
+      rect.left += offset
+      rect.right += offset
+    }
+    if (rect.top < 7) {
+      const offset = 7 - rect.top
+      rect.top += offset
+      rect.bottom += offset
+    }
+    if (rect.right > pageWidth) {
+      const offset = rect.right - pageWidth + 7
+      rect.right -= offset
+      rect.left -= offset
+    }
+    if (rect.bottom > pageHeight) {
+      const offset = rect.bottom - pageHeight + 7
+      rect.bottom -= offset
+      rect.top -= offset
+    }
+    return rect
   }
 
   // 添加编辑区域

+ 10 - 35
packages/core/src/index.js

@@ -968,10 +968,10 @@ class ComPDFKitViewer {
   scrollPageIntoView({
     pageNumber,
   }) {
-    // if (this.currentPage)
   }
 
   async search(value) {
+    if (!value) return
     const result = await this.messageHandler.sendWithPromise('Search', {
       pagesPtr: this.pagesPtr,
       value
@@ -3575,44 +3575,19 @@ class ComPDFKitViewer {
   }
 
   // iOS添加Editor图片
-  addEditorImage(data) {
+   async addEditorImage(data) {
     if (!data) return
-    const { imageBase64, width, height, pageNum } = data
-    
+    const { imageBase64, width, height, pageNum, point, preview } = data
+
     let pageView = this.pdfViewer.getPageView(pageNum - 1)
 
     if (pageView) {
-      let pageWidth = pageView.viewport.viewBox[2] * 0.9
-      let pageHeight = pageView.viewport.viewBox[3] * 0.9
-
-      const imageRatio = width / height
-      const rectRatio = pageWidth / pageHeight
-      let scaledWidth, scaledHeight
-
-      if (imageRatio > rectRatio) {
-        scaledWidth = pageWidth
-        scaledHeight = pageWidth / imageRatio
-      } else {
-        scaledWidth = pageHeight * imageRatio
-        scaledHeight = pageHeight
-      }
-
-      const imgWidth = Math.min(pageWidth, scaledWidth)
-      const imgHeight = Math.min(pageHeight, scaledHeight)
-
-      const offsetX = pageView.viewport.viewBox[2] * 0.1
-      const offsetY = pageView.viewport.viewBox[3] * 0.1
-
-      const rect = {
-        left: (pageWidth - imgWidth) / 2 + offsetX,
-        top: (pageHeight - imgHeight) / 2 + offsetY,
-        right: (pageWidth + imgWidth) / 2,
-        bottom: (pageHeight + imgHeight) / 2,
-      }
-
-      pageView.contentContainer.addImageEditor({
-        rect,
-        imageBase64
+      await pageView.contentContainer.addImageManager({
+        width,
+        height,
+        imageBase64,
+        point,
+        preview,
       })
     }
   }

+ 1 - 1
packages/core/src/worker/compdfkit_worker.js

@@ -606,7 +606,7 @@ class CPDFWorker {
         const ptr = pagesPtr[i]
         const pagePtr = ptr.pagePtr
         const textPtr = ptr.textPtr
-        const textFindPtr = Module._InitTextFind(textPtr)
+        const textFindPtr = Module._InitTextFind()
         Module._FindStart(textPtr, textFindPtr, text, 0, 0)
         result = licenseErrorMessage('PDF VIEWER SEARCH')
         if (result.code) {

+ 4 - 0
packages/webview/src/assets/main.scss

@@ -53,6 +53,10 @@ input, textarea, select {
   }
 }
 
+button {
+  outline: none;
+}
+
 #app {
   display: flex;
   flex-direction: column;

+ 117 - 3
packages/webview/src/components/Annotate/Annotate.vue

@@ -46,7 +46,7 @@
       <EditImage />
     </Button>
     <Button v-else-if="tool.type === 'addImage' && !tool.hidden" :data-element="tool.dataElement" :class="{ active: activeTool === 'addImage' }" @click="changeActiveTool('addImage')" :title="$t('header.addImage')">
-      <AddImage />
+      <AddImage /><input type="file" ref="addImageInput" accept=".png, .jpg, .jpeg" style="display: none;" @change="handleFile" @click.stop="">
     </Button>
   </template>
   <div class="divider pc"></div>
@@ -71,7 +71,7 @@
 </template>
 
 <script setup>
-  import { computed, onUnmounted } from 'vue'
+  import { computed, onUnmounted, ref } from 'vue'
   import { useViewerStore } from '@/stores/modules/viewer'
   import { useDocumentStore } from '@/stores/modules/document'
   import core from '@/core'
@@ -79,8 +79,11 @@
 
   const { item } = defineProps(['item'])
 
+  const addImageInput = ref()
   const useDocument = useDocumentStore()
   const useViewer = useViewerStore()
+  const imageData = ref(null)
+  const imgUiElement = ref(null)
 
   const activeTool = computed(() => useDocument.getActiveTool)
   const markupActive = computed(() => {
@@ -109,7 +112,7 @@
     }
 
     useDocument.setToolState(tool)
-    
+
     useViewer.toggleActiveHand(false)
     switchTool(0)
     
@@ -124,6 +127,117 @@
     if (activeTool.value === 'image') {
       document.getElementById('signImageInput').click()
     }
+
+    if (activeTool.value === 'addImage') {
+      addImageInput.value[0].click()
+    }
+  }
+
+  const handleFile = (e) => {
+    const file = e.target.files[0]
+
+    if (file) {
+      const reader = new FileReader()
+      reader.onload = function (e) {
+        const base64Image = e.target.result
+        showPreview(base64Image)
+        core.addEvent('click', handleClick)
+      }
+      reader.onerror = function (error) {
+        console.log(error)
+      }
+      reader.readAsDataURL(file)
+    }
+  }
+
+  const getMouseLocation = e => {
+    const scrollElement = core.getScrollViewElement()
+    const scrollLeft = scrollElement.scrollLeft || 0
+    const scrollTop = scrollElement.scrollTop || 0
+
+    return {
+      x: e.pageX + scrollLeft,
+      y: e.pageY + scrollTop
+    };
+  }
+
+  const handleClick = (e) => {
+    let windowCoordinates = getMouseLocation(e)
+    const page = core.getSelectedPage(windowCoordinates, windowCoordinates)
+
+    const clickPageNumber = (page.first !== null) ? page.first : core.getCurrentPage()
+    const pagePoint = core.windowToPage(windowCoordinates, clickPageNumber)
+
+    const data = {
+      imageBase64: imageData.value.base64Image,
+      width: imageData.value.width,
+      height: imageData.value.height,
+      pageNum: clickPageNumber,
+      point: pagePoint,
+    }
+    core.addEditorImage(data)
+
+    resetAddImageInput()
+  }
+
+  const resetAddImageInput = () => {
+    core.removeEvent('click', handleClick)
+    imgUiElement.value.remove()
+    imgUiElement.value = null
+    imageData.value = null
+
+    useDocument.setToolState('addImage')
+    switchTool(0)
+  }
+
+  const showPreview = (base64Image) => {
+    const image = new Image()
+    image.onload = function() {
+      let docDiv = document.querySelector('.content')
+      if (docDiv) {
+        let imgUi = imgUiElement.value
+        if (!imgUi) {
+          imgUi = imgUiElement.value = document.createElement('img')
+          imgUi.style.position = 'absolute'
+          imgUi.style.zIndex = 10
+          imgUi.style.pointerEvents = 'none'
+          imgUi.style.maxHeight = '220px'
+          imgUi.style.maxWidth = '568px'
+          imgUi.style.border = '2px solid blue'
+          imgUi.style.cursor = 'crosshair'
+          imgUi.id = 'edit-image-save'
+        }
+
+        imgUi.setAttribute('src', base64Image)
+        imgUi.style.left = '50%'
+        imgUi.style.top = '50%'
+        imgUi.style.display = 'hidden'
+
+        let imgWidth = 0
+        let imgHeight = 0
+        docDiv.append(imgUi)
+        if (imgUi.offsetWidth > 0 && imgUi.offsetHeight > 0) {
+          imgWidth = imgUi.offsetWidth
+          imgHeight = imgUi.offsetHeight
+          imageData.value = {
+            width: imgWidth,
+            height: imgHeight,
+            base64Image
+          }
+        }
+
+        let offsetX = Math.min(parseInt(imgWidth / 2), 568 / 2)
+        let offsetY = Math.min(parseInt(imgHeight / 2), 220 / 2)
+        imgUi.style.left = 'calc(50% -' + offsetX + ')'
+        imgUi.style.top = 'calc(50% -' + offsetY + ')'
+        imgUi.style.display = 'block'
+        docDiv.onmousemove = function (evt) {
+          imgUi.style.left = (evt.clientX - offsetX) + 'px'
+          imgUi.style.top = (evt.clientY - offsetY) + 'px'
+        }
+      }
+    }
+    image.src = base64Image
   }
 
   const changeMarkupTool = (tool) => {

+ 24 - 18
packages/webview/src/components/ContentEditorToolBar/ContentEditorToolBar.vue

@@ -49,6 +49,7 @@
 
   const handleFile = (e) => {
     const file = e.target.files[0]
+    if (!file) return
     if (file.size > 10 * 1024 * 1024) {
       window.$message.error(instance.$t('editorPanel.maximum'), {
         duration: 3000,
@@ -58,30 +59,35 @@
       return;
     }
 
-    if (file) {
-      const reader = new FileReader()
-      reader.onload = function (e) {
-        const image = new Image()
-        image.onload = function () {
-          const data = {
-            imageBase64: e.target.result,
-            width: image.width,
-            height: image.height,
-            pageNum: currentPage.value
-          }
-          console.log(data)
-          core.addEditorImage(data)
+    const reader = new FileReader()
+    reader.onload = function (e) {
+      const image = new Image()
+      image.onload = function () {
+        const pageWidth = core.getPageWidth(currentPage.value)
+        const pageHeight = core.getPageHeight(currentPage.value)
+        const point = {
+          x: pageWidth / 2,
+          y: pageHeight / 2
         }
-        image.onerror = function (error) {
-          console.log(error)
+        const data = {
+          imageBase64: e.target.result,
+          width: image.width,
+          height: image.height,
+          pageNum: currentPage.value,
+          point,
+          preview: true,
         }
-        image.src = e.target.result
+        core.addEditorImage(data)
       }
-      reader.onerror = function (error) {
+      image.onerror = function (error) {
         console.log(error)
       }
-      reader.readAsDataURL(file)
+      image.src = e.target.result
     }
+    reader.onerror = function (error) {
+      console.log(error)
+    }
+    reader.readAsDataURL(file)
   }
 </script>
 

+ 2 - 0
packages/webview/src/components/DocumentContainer/DocumentContainer.vue

@@ -354,11 +354,13 @@ window.instances.UI.loadDocument = async (file) => {
   transform-origin: 0 0;
   cursor: auto;
   z-index: 2;
+  outline: none;
 }
 
 .annotationLayer svg {
   display: block;
   pointer-events: auto;
+  outline: none;
 }
 
 .inkEditor .inkEditorCanvas {

+ 3 - 0
packages/webview/src/core/getPageHeight.js

@@ -0,0 +1,3 @@
+import core from '@/core'
+
+export default (pageNumber) => core.getDocumentViewer().getPageHeight(pageNumber)

+ 3 - 0
packages/webview/src/core/getPageWidth.js

@@ -0,0 +1,3 @@
+import core from '@/core'
+
+export default (getPageHeight) => core.getDocumentViewer().getPageWidth(getPageHeight)

+ 4 - 0
packages/webview/src/core/index.js

@@ -59,6 +59,8 @@ import pageToWindow from './pageToWindow'
 import windowToPage from './windowToPage'
 import addEditorImage from './addEditorImage'
 import flattenPdf from './flattenPdf'
+import getPageWidth from './getPageWidth'
+import getPageHeight from './getPageHeight'
 
 export default {
   getDocumentViewer,
@@ -125,4 +127,6 @@ export default {
   windowToPage,
   addEditorImage,
   flattenPdf,
+  getPageWidth,
+  getPageHeight,
 }