فهرست منبع

fix: 二轮测试修复;单击添加图片

wzl 1 سال پیش
والد
کامیت
b41fd4621f

+ 86 - 25
packages/core/src/editor/add_image.js

@@ -96,11 +96,12 @@ export default class AddImage {
   }
 
   handleMouseUp () {
-    let initStartPoint = this.initStartPoint
-    let initEndPoint = this.initEndPoint
-    if (initEndPoint && initStartPoint.x !== initEndPoint.x && initStartPoint.y !== initEndPoint.y) {
-      let start = getInitialPoint(initStartPoint, this.viewport, this.viewport.scale)
-      let end = getInitialPoint(initEndPoint, this.viewport, this.viewport.scale)
+    const initStartPoint = this.initStartPoint
+    const initEndPoint = this.initEndPoint
+
+    if (initEndPoint && initStartPoint.x !== initEndPoint.x && initStartPoint.y !== initEndPoint.y) { // 绘制区域
+      const start = getInitialPoint(initStartPoint, this.viewport, this.viewport.scale)
+      const end = getInitialPoint(initEndPoint, this.viewport, this.viewport.scale)
       
       const newStart = {
         x: Math.min(start.x, end.x),
@@ -111,11 +112,11 @@ export default class AddImage {
         y: Math.max(start.y, end.y)
       }
       
-      const rect = {
+      const area = {
         left: newStart.x,
         top: newStart.y,
         right: newEnd.x,
-        bottom: newStart.y,
+        bottom: newEnd.y,
         width: newEnd.x - newStart.x,
         height: newEnd.y - newStart.y
       }
@@ -125,35 +126,94 @@ export default class AddImage {
           const { imageBase64, width, height } = data
 
           const imageRatio = width / height
-          const rectRatio = rect.width / rect.height
+          const rectRatio = area.width / area.height
           let scaledWidth, scaledHeight
 
           if (imageRatio > rectRatio) {
-            scaledWidth = rect.width
-            scaledHeight = rect.width / imageRatio
+            scaledWidth = area.width
+            scaledHeight = area.width / imageRatio
           } else {
-            scaledWidth = rect.height * imageRatio
-            scaledHeight = rect.height
+            scaledWidth = area.height * imageRatio
+            scaledHeight = area.height
           }
           
-          let left, right, bottom, top
           const centerPoint = {
-            x: rect.left + rect.width / 2,
-            y: rect.top + rect.height / 2
+            x: area.left + area.width / 2,
+            y: area.top + area.height / 2
           }
 
-          left = centerPoint.x - scaledWidth / 2
-          right = centerPoint.x + scaledWidth / 2
-          bottom = centerPoint.y + scaledHeight / 2
-          top = centerPoint.y - scaledHeight / 2
+          const rect = {
+            left: centerPoint.x - scaledWidth / 2,
+            top: centerPoint.y - scaledHeight / 2,
+            right: centerPoint.x + scaledWidth / 2,
+            bottom: centerPoint.y + scaledHeight / 2,
+          }
 
           this.contentContainer.addImageEditor({
-            rect: {
-              left,
-              right,
-              bottom,
-              top
-            },
+            rect,
+            imageBase64
+          })
+        })
+        .catch((error) => {
+          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
+
+      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
+          }
+
+          this.contentContainer.addImageEditor({
+            rect,
             imageBase64
           })
         })
@@ -161,6 +221,7 @@ export default class AddImage {
           console.error(error)
         })
     }
+
     // this.reset()
     this.initStartPoint = null
     this.initEndPoint = null

+ 25 - 9
packages/core/src/editor/image_editor.js

@@ -1,5 +1,5 @@
 import { getActualPoint, getClickPoint, createSvg, createElement } from '../annotation/utils';
-import { onClickOutside, setCss, isMobileDevice } from '../ui_utils';
+import { onClickOutsideUp, setCss, isMobileDevice } from '../ui_utils';
 
 export class ImageEditor {
   constructor({
@@ -31,7 +31,6 @@ export class ImageEditor {
     this.pageViewer = pageViewer
     this.$t = $t
 
-    // this.deleteSvgStr = `<path xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" d="M14 1.5V4.5H19V5.5H16.5V18.5H3.5V5.5H1V4.5H6V1.5H14ZM4.5 5.5V17.5H15.5V5.5H4.5ZM13 2.5V4.5H7V2.5H13ZM8.5 8V15H7.5V8H8.5ZM12.5 15V8H11.5V15H12.5Z" fill="#333333"/>`
     this.deleteSvgStr = `<rect width="30" height="30" rx="2" fill="#DDE9FF"/>
       <path fill-rule="evenodd" clip-rule="evenodd" d="M19 6.5V9.5H24V10.5H21.5V23.5H8.5V10.5H6V9.5H11V6.5H19ZM9.5 10.5V22.5H20.5V10.5H9.5ZM18 7.5V9.5H12V7.5H18ZM13.5 13V20H12.5V13H13.5ZM17.5 20V13H16.5V20H17.5Z" fill="#333333"/>
     `
@@ -44,6 +43,7 @@ export class ImageEditor {
     this.selectedCharRange = null
     this.state = 0 // 0 未选中;1 已选中;2 裁剪状态
     this.mouseDown = false
+    this.moving = false
     this.ratio = window.devicePixelRatio || 1
     this.opacity = 1
     this.imageRatio = 1
@@ -408,6 +408,7 @@ export class ImageEditor {
     if (!this.mouseDown) return
 
     this.mouseDown = false
+    this.moving = false
     this.frameContainer.classList.add('selected')
 
     if (e.type === 'touchend') {
@@ -421,6 +422,7 @@ export class ImageEditor {
       this.state = 1
       this.contentContainer.selectedFrameIndex = this.editAreaIndex
       this.container.append(this.outerLineContainer)
+      this.eventBus.dispatch('changeRightPanelBtnDisabled', false)
     }
 
     if (this.mouseMoved) {
@@ -432,6 +434,7 @@ export class ImageEditor {
         start: this.newStart,
         end: this.newEnd
       }
+      console.log(oldPoint, newPoint)
   
       const { pageX, pageY } = getClickPoint(e)
       if (!(pageX === this.startState?.clickX && pageY === this.startState?.clickY) && this.newStart && this.newEnd) {
@@ -461,15 +464,16 @@ export class ImageEditor {
       this.updateCanvas({oldPoint, newPoint})
     }
 
-    onClickOutside([this.imageContainer, this.outerLine, this.deletetButton, document.querySelector('.editor-panel'), document.getElementById('propertyPanelButton')], this.handleOutside.bind(this))
+    onClickOutsideUp([this.imageContainer, this.outerLine, this.deletetButton, 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)
   }
 
   async handleMouseMove (e) {
     if (this.contentContainer.selectedFrameIndex !== -1 && this.contentContainer.selectedFrameIndex !== this.editAreaIndex && this.state === 0) return
+
+    this.moving = true
     
     if (e.type === 'touchmove') {
       document.body.style.overscrollBehavior = 'none';
@@ -510,7 +514,7 @@ export class ImageEditor {
       let x = pageX - (startState.clickX - start.x)
 
       x = Math.min(end.x - 2, x)
-      x = Math.max(this.state === 2 ? start.x : 0, x)
+      x = Math.max(this.state === 2 ? start.x : 7, x)
 
       this.updateOutline({
         start: { x, y: start.y },
@@ -655,6 +659,8 @@ export class ImageEditor {
   }
 
   async handleOutside () {
+    if (this.moving) return
+
     this.state = 0
     this.imageUrl = null
     this.contentContainer.selectedFrameIndex = -1
@@ -669,10 +675,15 @@ export class ImageEditor {
     this.frameContainer.classList.remove('editing')
     this.frameContainer.classList.remove('selected')
     this.outerLineContainer.remove()
+    this.outerLineContainer.append(this.deletetButton)
 
-    this.eventBus.dispatch('contentPropertyChange', { type: 'image', isOpen: false })
-
-    document.getElementById('propertyPanelButton').click()
+    setTimeout(() => {
+      const hasItem = document.querySelector('.frame-container.selected')
+      if (!hasItem) {
+        this.eventBus.dispatch('contentPropertyChange', { type: 'image', isOpen: false })
+        this.eventBus.dispatch('changeRightPanelBtnDisabled', true)
+      }
+    }, 1)
   }
 
   // 获取rect
@@ -1050,6 +1061,7 @@ export class ImageEditor {
         if (this.state === 2) return
         this.state = 2
         this.frameContainer.classList.add('editing')
+        this.deletetButton.remove()
         this.moveRect.style.cursor = 'auto'
         this.updateRectStyle()
         return
@@ -1104,7 +1116,7 @@ export class ImageEditor {
     this.container.append(this.outerLineContainer)
     if (!this.imageUrl) this.updateOriginalImageUrl()
 
-    onClickOutside([this.imageContainer, this.outerLine, this.deletetButton, document.querySelector('.editor-panel'), document.getElementById('propertyPanelButton')], this.handleOutside.bind(this))
+    onClickOutsideUp([this.imageContainer, this.outerLine, this.deletetButton, document.querySelector('.editor-panel'), document.getElementById('propertyPanelButton')], this.handleOutside.bind(this))
   }
 
   // 删除区域
@@ -1272,9 +1284,13 @@ export class ImageEditor {
       )
     } else {
       this.LeftRect.setAttribute('height', this.pointHeight)
+      this.LeftRect.style.cursor = 'w-resize'
       this.topRect.setAttribute('width', this.pointWidth)
+      this.topRect.style.cursor = 'n-resize'
       this.rightRect.setAttribute('height', this.pointHeight)
+      this.rightRect.style.cursor = 'e-resize'
       this.bottomRect.setAttribute('width', this.pointWidth)
+      this.bottomRect.style.cursor = 's-resize'
 
       this.topLeftRect = createSvg(
         "rect",

+ 52 - 28
packages/core/src/editor/text_editor.js

@@ -1,5 +1,5 @@
 import { getActualPoint, getClickPoint, createSvg, createElement } from '../annotation/utils';
-import { onClickOutside, setCss, isMobileDevice } from '../ui_utils';
+import { onClickOutsideUp, setCss, isMobileDevice } from '../ui_utils';
 import copy from 'copy-to-clipboard';
 
 export class TextEditor {
@@ -35,11 +35,17 @@ export class TextEditor {
     this.borderWidth = 2
     this.pointWidth = 6
     this.pointHeight = 6
-    this.activeCharPlace = null
+    this.activeCharPlace = {
+      SectionIndex: 0,
+      LineIndex: 0,
+      RunIndex: 0,
+      CharIndex: 0
+    }
     this.selectedRects = null
     this.selectedCharRange = null
     this.state = 0 // 0 未选中;1 已选中;2 编辑状态
     this.mouseDown = false
+    this.moving = false
     this.ratio = window.devicePixelRatio || 1
 
     this.start = null
@@ -440,6 +446,7 @@ export class TextEditor {
 
     if (!this.mouseDown) return
     this.mouseDown = false
+    this.moving = false
 
     if (e.type === 'touchend') {
       document.body.style.overscrollBehavior = 'auto';
@@ -450,7 +457,10 @@ export class TextEditor {
       this.state = 1
       flag = false
 
+      this.getTextStyle()
+
       this.contentContainer.selectedFrameIndex = this.editAreaIndex
+      this.eventBus.dispatch('changeRightPanelBtnDisabled', false)
     }
 
     if (this.state === 1) {
@@ -491,9 +501,7 @@ export class TextEditor {
 
       } else if (!this.mouseMoved && flag) {
         this.state = 2
-        if (isMobileDevice) {
-          this.eventBus.dispatch('changeIsEditorPanelDisabled')
-        } else {
+        if (!isMobileDevice) {
           this.eventBus.dispatch('contentPropertyChange', { type: 'text', isOpen: true })
         }
       }
@@ -577,7 +585,7 @@ export class TextEditor {
     this.frameContainer.classList.add('selected')
 
     if (this.state === 1) {
-      onClickOutside([this.textContainer, this.outerLine, document.querySelector('.editor-panel'), document.getElementById('propertyPanelButton')], this.handleOutside.bind(this))
+      onClickOutsideUp([this.textContainer, this.outerLine, document.querySelector('.editor-panel'), document.getElementById('propertyPanelButton')], this.handleOutside.bind(this))
     }
     
     document.removeEventListener(this.mousemove, this.onMousemove)
@@ -588,6 +596,8 @@ export class TextEditor {
 
   async handleMouseMove (e) {
     if (this.contentContainer.selectedFrameIndex !== -1 && this.contentContainer.selectedFrameIndex !== this.editAreaIndex && this.state === 0) return
+
+    this.moving = true
     
     if (e.type === 'touchmove') {
       document.body.style.overscrollBehavior = 'none';
@@ -762,27 +772,32 @@ export class TextEditor {
   }
 
   async handleOutside () {
+    if (this.moving) return
+    
     this.state = this.state === 2 ? 1 : this.state === 1 ? 0 : this.state
 
     this.frameContainer.classList.remove('editing')
 
-    this.eventBus.dispatch('contentPropertyChange', { type: 'text', isOpen: false })
-
     this.clearSelectText()
     this.cursor?.remove()
     this.cursor = null
 
     if (this.state === 0) {
       this.frameContainer.classList.remove('selected')
-
       this.outerLine.remove()
 
       this.contentContainer.selectedFrameIndex = -1
+
+      setTimeout(() => {
+        const hasItem = document.querySelector('.frame-container.selected')
+        if (!hasItem) {
+          this.eventBus.dispatch('contentPropertyChange', { type: 'text', isOpen: false })
+          this.eventBus.dispatch('changeRightPanelBtnDisabled', true)
+        }
+      }, 1)
     }
 
     if (this.state === 1) {
-      document.getElementById('propertyPanelButton').click()
-
       const text = await this.getText()
       if (text.length === 0) {
         await this.outerLine.remove()
@@ -795,7 +810,7 @@ export class TextEditor {
 
       this.textContainer.removeEventListener(this.mousemove, this.onMousemove)
 
-      onClickOutside([this.textContainer, this.outerLine, document.querySelector('.editor-panel'), document.getElementById('propertyPanelButton')], this.handleOutside.bind(this))
+      onClickOutsideUp([this.textContainer, this.outerLine, document.querySelector('.editor-panel'), document.getElementById('propertyPanelButton')], this.handleOutside.bind(this))
     }
 
     this.textarea.removeEventListener('blur', this.onBlur)
@@ -1092,7 +1107,7 @@ export class TextEditor {
     
     const style = {
       color: `rgb(${textStyle.R}, ${textStyle.G}, ${textStyle.B})`,
-      opacity: textStyle.Transparency * 100,
+      opacity: Math.round(textStyle.Transparency * 100),
       fontStyle: textStyle.IsBold && textStyle.IsItalic ? 3 : !textStyle.IsBold && !textStyle.IsItalic ? 0 : textStyle.IsBold ? 1 : 2,
       fontSize: Math.round(textStyle.FontSize)
     }
@@ -1402,10 +1417,14 @@ export class TextEditor {
 
   // 属性面板 修改属性
   async handlePropertyPanelChanged (props) {
-    if (this.state !== 2) return
+    if (this.state === 0) return
 
     let changed = false
 
+    if (!this.selectedCharRange && this.state === 1) {
+      await this.selectAllText()
+    }
+
     for (const item in props) {
       if (props[item] === this.textStyle[item]) continue
 
@@ -1426,7 +1445,7 @@ export class TextEditor {
         }
       }
 
-      if (!this.selectedCharRange && item !== 'alignType') {
+      if (!this.selectedCharRange && item !== 'alignType' && this.state === 2) {
         await this.selectAllText()
       }
       
@@ -1491,20 +1510,25 @@ export class TextEditor {
     const oldRect = this.rect
     await this.updateCanvas(null, oldRect)
 
-    const { start, end } = await this.messageHandler.sendWithPromise('RefreshRange', {
-      editAreaPtr: this.editAreaPtr,
-      start: this.selectedCharRange.start,
-      end: this.selectedCharRange.end,
-    })
-    this.selectedCharRange = { start, end }
+    if (this.selectedCharRange && this.state === 2) {
+      const { start, end } = await this.messageHandler.sendWithPromise('RefreshRange', {
+        editAreaPtr: this.editAreaPtr,
+        start: this.selectedCharRange.start,
+        end: this.selectedCharRange.end,
+      })
+      this.selectedCharRange = { start, end }
 
-    if (this.activeCharPlace.CharIndex === start.CharIndex) {
-      this.activeCharPlace = start
-    } else {
-      this.activeCharPlace = end
+      if (this.activeCharPlace.CharIndex === start.CharIndex) {
+        this.activeCharPlace = start
+      } else {
+        this.activeCharPlace = end
+      }
     }
     
-    this.updateSelectedRect()
+    if (this.state === 2) {
+      this.updateSelectedRect()
+      this.updateCursorLine()
+    }
   }
 
   // 设置文本样式
@@ -1609,7 +1633,7 @@ export class TextEditor {
       this.textarea.addEventListener('compositionend', this.onCompositionend)
     }
 
-    onClickOutside([this.textContainer, this.outerLine, document.querySelector('.editor-panel'), document.getElementById('propertyPanelButton')], this.handleOutside.bind(this))
+    onClickOutsideUp([this.textContainer, this.outerLine, document.querySelector('.editor-panel'), document.getElementById('propertyPanelButton')], this.handleOutside.bind(this))
   }
 
   // 删除区域
@@ -1644,6 +1668,6 @@ export class TextEditor {
   async selectAllText () {
     const { start, end } = await this.messageHandler.sendWithPromise('GetBeginAndEndCharPlace', this.editAreaPtr)
     this.selectedCharRange = { start, end }
-    this.selectedRectList = await this.getCharsRect(start, end)
+    if (this.state === 2) this.selectedRectList = await this.getCharsRect(start, end)
   }
 }

+ 4 - 1
packages/webview/src/components/ContentEditorPanel/ContentEditorPanel.vue

@@ -462,7 +462,10 @@
           .n-base-selection-label {
             height: 28px;
             background: var(--c-right-side-content-fillbox-bg);
-            color: var(--c-text);
+
+            .n-base-selection-input, .n-base-selection-input__content {
+              color: var(--c-text);
+            }
           }
           .n-base-selection__border {
             border: 1px solid var(--c-right-side-content-fillbox-border);

+ 1 - 1
packages/webview/src/components/Outlines/Outlines.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="outline-container">
+  <div class="outlines">
     <div class="outline-item" :class="isOutlineActive && 'selected'" @click="goToOutline">
       <div class="outline-item-toggle" :class="isExpanded && 'active'" :style="{ marginLeft: 12 * outline.level + 'px' }">
         <TreeArrow v-if="outline.children.length" @click="toggleOutline" />

+ 9 - 19
packages/webview/src/components/ToggleRightPanelButton/index.vue

@@ -23,7 +23,7 @@
   let isEditorPanelDisabled = ref(true)
 
   watch(() => contentEditorPanel.value, (newValue, oldValue) => {
-    isEditorPanelDisabled.value = !contentEditorPanel.value && !document.querySelector(contentEditorType.value === 'text' ? '.frame-container.editing' : '.frame-container.selected')
+    isEditorPanelDisabled.value = !contentEditorPanel.value && !document.querySelector('.frame-container.selected')
   })
 
   watch(toolMode, (newValue, oldValue) => {
@@ -35,32 +35,22 @@
 
   const onClick = () => {
     setTimeout(() => {
-      if (toolMode.value === 'form') {
-        isDisabled.value = document.getElementsByClassName('outline-container').length === 0
-      } else if (toolMode.value === 'editor') {
-        const disable = document.querySelector(contentEditorType.value === 'text' ? '.frame-container.editing' : '.frame-container.selected')
-        if (!disable && !contentEditorPanel.value) {
-          isEditorPanelDisabled.value = true
-        } else {
-          useViewer.toggleElement('contentEditorPanel')
-          if (!disable) {
-            isEditorPanelDisabled.value = true
-          }
-        }
-      }
+      isDisabled.value = document.getElementsByClassName('outline-container').length === 0
 
-      if (toolMode.value !== 'form' && document.getElementsByClassName('outline-container').length === 0) return
-      if (isDisabled.value && document.getElementsByClassName('right-panel')[0].className.indexOf('closed') !== -1) return
+      if (toolMode.value === 'form' && isDisabled.value && document.getElementsByClassName('right-panel')[0].className.indexOf('closed') !== -1) return
 
       if (toolMode.value === 'form') {
         useViewer.toggleElement(item.element)
+      } else if (toolMode.value === 'editor') {
+        useViewer.toggleElement('contentEditorPanel')
       }
       core.toggleSidebar()
     }, 1);
   }
 
-  const changeDisabled = () => {
-    isEditorPanelDisabled.value = false
+  const changeDisabled = (val) => {
+    isEditorPanelDisabled.value = val
+    isDisabled.value = document.getElementsByClassName('outline-container').length === 0
   }
-  core.addEvent('changeIsEditorPanelDisabled', changeDisabled)
+  core.addEvent('changeRightPanelBtnDisabled', changeDisabled)
 </script>