|
@@ -1,19 +1,19 @@
|
|
|
<template>
|
|
|
- <Popup class="text-popup" v-if="showPopup && textPopup.length" :style="{ top: `${top}px`, left: `${left}px` }">
|
|
|
+ <Popup class="text-popup" :class="{ 'transform': isTranslateX }" ref="textPopupRef" v-if="showPopup && textPopup.length" :style="{ top: `${top}px`, left: `${left}px` }">
|
|
|
<template v-for="(item, index) in textPopup" :key="`${item.dataElement}-${index}`">
|
|
|
<CustomButton v-if="item.name === 'customButton'" :item="item" :data-element="item.dataElement" />
|
|
|
<Button v-else-if="item.type === 'copy'" @click="handleTextPopup('copy')" :title="$t('documentEditor.copy')" :data-element="item.dataElement"><CopyText /></Button>
|
|
|
<Button v-else-if="item.type === 'highlight'" @click="handleTextPopup('highlight')" :title="$t('header.highlight')" :data-element="item.dataElement"><HightlightGray /></Button>
|
|
|
<Button v-else-if="item.type === 'underline'" @click="handleTextPopup('underline')" :title="$t('header.underline')" :data-element="item.dataElement"><UnderlineGray /></Button>
|
|
|
<Button v-else-if="item.type === 'strikeout'" @click="handleTextPopup('strikeout')" :title="$t('header.strikeout')" :data-element="item.dataElement"><StrikeoutGray /></Button>
|
|
|
- <Button v-else-if="item.type === 'squiggly'" @click="handleTextPopup('squiggly')" :title="$t('header.squiggly')" :data-element="item.dataElement"><Squiggle /></Button>
|
|
|
+ <Button v-else-if="item.type === 'squiggly'" @click="handleTextPopup('squiggly')" :title="$t('header.squiggly')" :data-element="item.dataElement"><SquiggleGray /></Button>
|
|
|
<div v-else-if="['spacer', 'divider'].includes(item.type)" :class="item.type"></div>
|
|
|
</template>
|
|
|
</Popup>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import { ref, onMounted, onUnmounted, computed } from 'vue'
|
|
|
+import { ref, onMounted, onUnmounted, computed, nextTick } from 'vue'
|
|
|
import core from '@/core'
|
|
|
import { useViewerStore } from '@/stores/modules/viewer'
|
|
|
import { useDocumentStore } from '@/stores/modules/document'
|
|
@@ -26,6 +26,8 @@ const textPopup = computed(() => useViewer.getPopupItems('textPopup'))
|
|
|
const showPopup = ref(false)
|
|
|
const top = ref(0)
|
|
|
const left = ref(0)
|
|
|
+const textPopupRef = ref(null)
|
|
|
+const isTranslateX = ref(true)
|
|
|
|
|
|
let documentContainer
|
|
|
|
|
@@ -38,14 +40,44 @@ const handleTextPopup = (tool) => {
|
|
|
core.handleTextPopup(data)
|
|
|
}
|
|
|
|
|
|
-const updatePopupPosition = (data) => {
|
|
|
+const updatePopupPosition = async (data) => {
|
|
|
const { show, rect } = data
|
|
|
|
|
|
showPopup.value = show
|
|
|
+ await nextTick()
|
|
|
|
|
|
- if (rect) {
|
|
|
- top.value = rect.bottom
|
|
|
- left.value = rect.left + (rect.right - rect.left) / 2
|
|
|
+ if (rect && showPopup.value) {
|
|
|
+ const popup = textPopupRef.value
|
|
|
+ if (!popup) return
|
|
|
+
|
|
|
+ // 计算弹窗的初始位置
|
|
|
+ let initialLeft = rect.left + (rect.right - rect.left) / 2
|
|
|
+ let initialTop = rect.bottom
|
|
|
+
|
|
|
+ const popupWidth = popup.width
|
|
|
+ const popupHeight = popup.height + 10
|
|
|
+
|
|
|
+ const windowWidth = window.innerWidth
|
|
|
+ const windowHeight = window.innerHeight
|
|
|
+
|
|
|
+ isTranslateX.value = true
|
|
|
+
|
|
|
+ // 检查水平位置
|
|
|
+ if (initialLeft - popupWidth / 2 < 0) {
|
|
|
+ initialLeft = 0
|
|
|
+ isTranslateX.value = false
|
|
|
+ } else if (initialLeft + popupWidth / 2 > windowWidth) {
|
|
|
+ initialLeft = windowWidth - popupWidth
|
|
|
+ isTranslateX.value = false
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查垂直位置
|
|
|
+ if (initialTop + popupHeight > windowHeight) {
|
|
|
+ initialTop = Math.max(0, rect.top - popupHeight)
|
|
|
+ }
|
|
|
+
|
|
|
+ top.value = initialTop
|
|
|
+ left.value = initialLeft
|
|
|
}
|
|
|
}
|
|
|
core.addEvent('showTextPopup', updatePopupPosition)
|
|
@@ -66,7 +98,11 @@ onUnmounted(() => {
|
|
|
|
|
|
<style lang="scss">
|
|
|
.text-popup {
|
|
|
- transform: translateX(-50%) translateY(5px);
|
|
|
+ transform: translateY(5px);
|
|
|
+
|
|
|
+ &.transform {
|
|
|
+ transform: translateX(-50%) translateY(5px);
|
|
|
+ }
|
|
|
|
|
|
.button:last-child {
|
|
|
margin-right: 0
|