2022-04-21 18:20:39 +08:00
|
|
|
<script lang="ts" setup>
|
2022-05-05 17:18:58 +08:00
|
|
|
import { ElMessage } from "element-plus"
|
2022-04-22 01:16:02 +08:00
|
|
|
import screenfull from "screenfull"
|
2024-11-18 19:40:44 +08:00
|
|
|
import { computed, ref, watchEffect } from "vue"
|
2022-04-21 18:20:39 +08:00
|
|
|
|
2023-06-20 18:40:18 +08:00
|
|
|
interface Props {
|
2023-06-29 12:43:01 +08:00
|
|
|
/** 全屏的元素,默认是 html */
|
2023-06-20 18:40:18 +08:00
|
|
|
element?: string
|
2023-06-29 12:43:01 +08:00
|
|
|
/** 打开全屏提示语 */
|
2023-06-20 18:40:18 +08:00
|
|
|
openTips?: string
|
2023-06-29 12:43:01 +08:00
|
|
|
/** 关闭全屏提示语 */
|
2023-06-20 18:40:18 +08:00
|
|
|
exitTips?: string
|
2023-06-29 12:43:01 +08:00
|
|
|
/** 是否只针对内容区 */
|
|
|
|
content?: boolean
|
2023-06-20 18:40:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
|
|
element: "html",
|
|
|
|
openTips: "全屏",
|
2023-06-29 12:43:01 +08:00
|
|
|
exitTips: "退出全屏",
|
|
|
|
content: false
|
2022-11-12 10:17:05 +08:00
|
|
|
})
|
|
|
|
|
2024-11-14 20:07:24 +08:00
|
|
|
const CONTENT_LARGE = "content-large"
|
|
|
|
const CONTENT_FULL = "content-full"
|
|
|
|
const classList = document.body.classList
|
|
|
|
|
2024-11-18 19:40:44 +08:00
|
|
|
// #region 全屏
|
2024-11-14 20:07:24 +08:00
|
|
|
const isEnabled = screenfull.isEnabled
|
2022-11-12 13:53:32 +08:00
|
|
|
const isFullscreen = ref<boolean>(false)
|
2024-11-14 20:07:24 +08:00
|
|
|
const fullscreenTips = computed(() => (isFullscreen.value ? props.exitTips : props.openTips))
|
|
|
|
const fullscreenSvgName = computed(() => (isFullscreen.value ? "fullscreen-exit" : "fullscreen"))
|
|
|
|
|
2024-11-18 19:40:44 +08:00
|
|
|
function handleFullscreenClick() {
|
2023-05-22 13:35:04 +08:00
|
|
|
const dom = document.querySelector(props.element) || undefined
|
2024-11-14 20:07:24 +08:00
|
|
|
isEnabled ? screenfull.toggle(dom) : ElMessage.warning("您的浏览器无法工作")
|
2022-04-21 18:20:39 +08:00
|
|
|
}
|
2024-11-18 19:40:44 +08:00
|
|
|
function handleFullscreenChange() {
|
2022-08-22 15:29:29 +08:00
|
|
|
isFullscreen.value = screenfull.isFullscreen
|
2024-11-14 20:07:24 +08:00
|
|
|
// 退出全屏时清除相关的 class
|
|
|
|
isFullscreen.value || classList.remove(CONTENT_LARGE, CONTENT_FULL)
|
2022-08-22 15:29:29 +08:00
|
|
|
}
|
2023-05-22 13:35:04 +08:00
|
|
|
watchEffect((onCleanup) => {
|
2024-11-14 20:07:24 +08:00
|
|
|
if (isEnabled) {
|
|
|
|
// 挂载组件时自动执行
|
|
|
|
screenfull.on("change", handleFullscreenChange)
|
|
|
|
// 卸载组件时自动执行
|
|
|
|
onCleanup(() => screenfull.off("change", handleFullscreenChange))
|
|
|
|
}
|
2022-08-22 15:29:29 +08:00
|
|
|
})
|
2024-11-18 19:40:44 +08:00
|
|
|
// #endregion
|
2023-06-29 12:43:01 +08:00
|
|
|
|
2024-11-18 19:40:44 +08:00
|
|
|
// #region 内容区
|
2023-06-29 12:43:01 +08:00
|
|
|
const isContentLarge = ref<boolean>(false)
|
2024-11-14 20:07:24 +08:00
|
|
|
const contentLargeTips = computed(() => (isContentLarge.value ? "内容区复原" : "内容区放大"))
|
|
|
|
const contentLargeSvgName = computed(() => (isContentLarge.value ? "fullscreen-exit" : "fullscreen"))
|
2024-11-18 19:40:44 +08:00
|
|
|
function handleContentLargeClick() {
|
2023-06-29 12:43:01 +08:00
|
|
|
isContentLarge.value = !isContentLarge.value
|
2024-03-22 18:58:56 +08:00
|
|
|
// 内容区放大时,将不需要的组件隐藏
|
2024-11-14 20:07:24 +08:00
|
|
|
classList.toggle(CONTENT_LARGE, isContentLarge.value)
|
2024-03-22 18:58:56 +08:00
|
|
|
}
|
2024-11-18 19:40:44 +08:00
|
|
|
function handleContentFullClick() {
|
2024-03-22 18:58:56 +08:00
|
|
|
// 取消内容区放大
|
|
|
|
isContentLarge.value && handleContentLargeClick()
|
|
|
|
// 内容区全屏时,将不需要的组件隐藏
|
2024-11-14 20:07:24 +08:00
|
|
|
classList.add(CONTENT_FULL)
|
2024-03-22 18:58:56 +08:00
|
|
|
// 开启全屏
|
|
|
|
handleFullscreenClick()
|
2023-06-29 12:43:01 +08:00
|
|
|
}
|
2024-11-18 19:40:44 +08:00
|
|
|
// #endregion
|
2022-04-21 18:20:39 +08:00
|
|
|
</script>
|
2022-04-22 12:47:04 +08:00
|
|
|
|
|
|
|
<template>
|
2023-06-29 12:43:01 +08:00
|
|
|
<div>
|
|
|
|
<!-- 全屏 -->
|
|
|
|
<el-tooltip v-if="!content" effect="dark" :content="fullscreenTips" placement="bottom">
|
|
|
|
<SvgIcon :name="fullscreenSvgName" @click="handleFullscreenClick" />
|
2022-04-22 12:47:04 +08:00
|
|
|
</el-tooltip>
|
2023-06-29 12:43:01 +08:00
|
|
|
<!-- 内容区 -->
|
2024-03-22 18:58:56 +08:00
|
|
|
<el-dropdown v-else :disabled="isFullscreen">
|
2023-06-29 12:43:01 +08:00
|
|
|
<SvgIcon :name="contentLargeSvgName" />
|
|
|
|
<template #dropdown>
|
|
|
|
<el-dropdown-menu>
|
|
|
|
<!-- 内容区放大 -->
|
2024-11-18 19:40:44 +08:00
|
|
|
<el-dropdown-item @click="handleContentLargeClick">
|
|
|
|
{{ contentLargeTips }}
|
|
|
|
</el-dropdown-item>
|
2023-06-29 12:43:01 +08:00
|
|
|
<!-- 内容区全屏 -->
|
2024-11-18 19:40:44 +08:00
|
|
|
<el-dropdown-item @click="handleContentFullClick">
|
|
|
|
内容区全屏
|
|
|
|
</el-dropdown-item>
|
2023-06-29 12:43:01 +08:00
|
|
|
</el-dropdown-menu>
|
|
|
|
</template>
|
|
|
|
</el-dropdown>
|
2022-04-22 12:47:04 +08:00
|
|
|
</div>
|
|
|
|
</template>
|
2022-08-22 15:29:29 +08:00
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
.svg-icon {
|
|
|
|
font-size: 20px;
|
|
|
|
&:focus {
|
|
|
|
outline: none;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</style>
|