|
|
@@ -12,8 +12,9 @@
|
|
|
class="rotate-wrapper"
|
|
|
:style="{ transform: `rotate(${elementInfo.rotate}deg)` }"
|
|
|
>
|
|
|
- <div
|
|
|
- class="element-content"
|
|
|
+ <div
|
|
|
+ class="element-content"
|
|
|
+ :class="{ 'is-interactive-widget': isSpeakingTool }"
|
|
|
v-contextmenu="contextmenus"
|
|
|
@mousedown="$event => handleSelectElement($event)"
|
|
|
@touchstart="$event => handleSelectElement($event)"
|
|
|
@@ -29,7 +30,7 @@
|
|
|
></video>
|
|
|
<!-- 英语口语预览(type 77):使用 Vue 组件直接渲染,url 字段即 configId -->
|
|
|
<TopicDiscussionPreview
|
|
|
- v-else-if="Number(elementInfo.toolType) === 77"
|
|
|
+ v-else-if="isSpeakingTool"
|
|
|
:configId="elementInfo.url"
|
|
|
:style="{ width: '100%', height: '100%' }"
|
|
|
/>
|
|
|
@@ -66,16 +67,21 @@
|
|
|
allow="camera *; microphone *; display-capture; midi; encrypted-media; fullscreen; geolocation; clipboard-read; clipboard-write; accelerometer; autoplay; gyroscope; payment; picture-in-picture; usb; xr-spatial-tracking;"
|
|
|
></iframe>
|
|
|
|
|
|
- <div class="drag-handler top"></div>
|
|
|
- <div class="drag-handler bottom"></div>
|
|
|
- <div class="drag-handler left"></div>
|
|
|
- <div class="drag-handler right"></div>
|
|
|
+ <!-- type 77(英语口语预览)是一个需要内部交互的 Vue 组件:
|
|
|
+ mask / drag-handler 会挡住 wheel 事件导致内部滚不了,
|
|
|
+ 所以对 77 不渲染这两层,选中/拖动走外层 .element-content 的 mousedown。 -->
|
|
|
+ <template v-if="!isSpeakingTool">
|
|
|
+ <div class="drag-handler top"></div>
|
|
|
+ <div class="drag-handler bottom"></div>
|
|
|
+ <div class="drag-handler left"></div>
|
|
|
+ <div class="drag-handler right"></div>
|
|
|
|
|
|
- <div class="mask"
|
|
|
- v-if="handleElementId !== elementInfo.id"
|
|
|
- @mousedown="$event => handleSelectElement($event, false)"
|
|
|
- @touchstart="$event => handleSelectElement($event, false)"
|
|
|
- ></div>
|
|
|
+ <div class="mask"
|
|
|
+ v-if="handleElementId !== elementInfo.id"
|
|
|
+ @mousedown="$event => handleSelectElement($event, false)"
|
|
|
+ @touchstart="$event => handleSelectElement($event, false)"
|
|
|
+ ></div>
|
|
|
+ </template>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -89,7 +95,7 @@ import { useSpeakingStore } from '@/store/speaking'
|
|
|
import type { PPTFrameElement } from '@/types/slides'
|
|
|
import TopicDiscussionPreview from '@/views/Editor/EnglishSpeaking/preview/TopicDiscussionPreview.vue'
|
|
|
import type { ContextmenuItem } from '@/components/Contextmenu/types'
|
|
|
-import { ref, watch } from 'vue'
|
|
|
+import { computed, ref, watch } from 'vue'
|
|
|
|
|
|
const props = defineProps({
|
|
|
elementInfo: {
|
|
|
@@ -109,6 +115,11 @@ const props = defineProps({
|
|
|
const { handleElementId } = storeToRefs(useMainStore())
|
|
|
const speakingStore = useSpeakingStore()
|
|
|
|
|
|
+// 英语口语预览工具(FRAME + toolType 77):产品上占满整页、不可拖动、不可缩放/旋转。
|
|
|
+// 这个 flag 在 template 里决定是否渲染 mask/drag-handler + interactive-widget class,
|
|
|
+// 在 handleSelectElement 里决定是否禁止 drag + 是否弹配置面板。
|
|
|
+const isSpeakingTool = computed(() => Number(props.elementInfo.toolType) === 77)
|
|
|
+
|
|
|
const iframeKey = ref(0)
|
|
|
|
|
|
watch(() => props.elementInfo.url, (newUrl, oldUrl) => {
|
|
|
@@ -119,11 +130,11 @@ watch(() => props.elementInfo.url, (newUrl, oldUrl) => {
|
|
|
|
|
|
const handleSelectElement = (e: MouseEvent | TouchEvent, canMove = true) => {
|
|
|
e.stopPropagation()
|
|
|
- props.selectElement(e, props.elementInfo, canMove)
|
|
|
- // 点击口语工具 frame → 弹出/切换到配置面板
|
|
|
- if (Number(props.elementInfo.toolType) === 77) {
|
|
|
- speakingStore.openConfigPanel()
|
|
|
- }
|
|
|
+ // 口语工具:强制 canMove=false 跳过 useSelectElement 的 dragElement 分支,禁止拖动。
|
|
|
+ // 点击后仍弹出/切换配置面板(业务需求)。
|
|
|
+ const finalCanMove = isSpeakingTool.value ? false : canMove
|
|
|
+ props.selectElement(e, props.elementInfo, finalCanMove)
|
|
|
+ if (isSpeakingTool.value) speakingStore.openConfigPanel()
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
@@ -139,6 +150,10 @@ const handleSelectElement = (e: MouseEvent | TouchEvent, canMove = true) => {
|
|
|
overflow: hidden;
|
|
|
position: absolute;
|
|
|
}
|
|
|
+// 英语口语预览(type 77)不可拖动,光标维持默认(让内部按钮/输入的 cursor 能生效)
|
|
|
+.element-content.is-interactive-widget {
|
|
|
+ cursor: default;
|
|
|
+}
|
|
|
.element-content iframe{
|
|
|
width: 100%;
|
|
|
height: 100%;
|