|
|
@@ -0,0 +1,253 @@
|
|
|
+<template>
|
|
|
+ <div class="box-ppt">
|
|
|
+ <div class="ppt-box">
|
|
|
+ <!-- 添加翻页动画容器 -->
|
|
|
+ <div ref="pptContainer" class="ppt-container">
|
|
|
+ <VueOfficePptx
|
|
|
+ ref="pptRef"
|
|
|
+ :src="pptPath"
|
|
|
+ @error="handlePptError"
|
|
|
+ @rendered="handlePptRendered"
|
|
|
+ :animation="true"
|
|
|
+ :animation-speed="1.0"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 视频切换按钮 - 始终显示 -->
|
|
|
+ <div class="ppt-switch">
|
|
|
+ <div class="caret-left" @click="prevPage">
|
|
|
+ <el-button type="warning" round
|
|
|
+ :disabled="currentPage <= 1">
|
|
|
+ <img :src="leftImg" alt="Left" />上一页
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <span class="page-info">{{ currentPage }} / {{ totalPages }}</span>
|
|
|
+
|
|
|
+ <div class="caret-right" @click="nextPage">
|
|
|
+ <el-button type="warning" round
|
|
|
+ :disabled="currentPage >= totalPages"
|
|
|
+ >下一页<img :src="rightImg" alt="Right" />
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import {
|
|
|
+ ref,
|
|
|
+ onMounted,
|
|
|
+ defineProps,
|
|
|
+} from 'vue'
|
|
|
+
|
|
|
+import { ElMessage } from 'element-plus'
|
|
|
+// 导入图标
|
|
|
+import leftImg from '@/assets/icon/backward.png'
|
|
|
+import rightImg from '@/assets/icon/f-backward.png'
|
|
|
+// PPT
|
|
|
+import VueOfficePptx from '@vue-office/pptx'
|
|
|
+
|
|
|
+// 新增PPT翻页相关变量
|
|
|
+const pptRef = ref(null)
|
|
|
+const currentPage = ref(1)
|
|
|
+const totalPages = ref(10)
|
|
|
+
|
|
|
+// 定义props
|
|
|
+const props = defineProps({
|
|
|
+ pptPath: { type: String }, // PPT路径
|
|
|
+})
|
|
|
+
|
|
|
+// 修改PPT渲染完成处理
|
|
|
+const handlePptRendered = (pptInfo) => {
|
|
|
+ console.log('PPT渲染完成', pptInfo);
|
|
|
+ // 获取总页数
|
|
|
+ const pageCount = pptInfo?.slides?.length || 1;
|
|
|
+ totalPages.value = pageCount;
|
|
|
+ // 确保当前页在有效范围内
|
|
|
+ if (currentPage.value > pageCount) {
|
|
|
+ currentPage.value = pageCount;
|
|
|
+ }
|
|
|
+ // 初始化滚动位置
|
|
|
+ scrollToPage(currentPage.value);
|
|
|
+}
|
|
|
+
|
|
|
+// 添加页面变更处理函数
|
|
|
+const handlePageChange = (newPage) => {
|
|
|
+ // 验证页码有效性
|
|
|
+ const normalizedPage = Math.max(1, Math.min(newPage + 1, totalPages.value));
|
|
|
+ if (currentPage.value !== normalizedPage) {
|
|
|
+ currentPage.value = normalizedPage;
|
|
|
+ console.log('页码已更新:', currentPage.value);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+// 新增滚动控制变量
|
|
|
+const pptContainer = ref(null)
|
|
|
+const pageHeight = ref(620) // 单页高度
|
|
|
+
|
|
|
+const nextPage = () => {
|
|
|
+ if (currentPage.value < totalPages.value) {
|
|
|
+ currentPage.value++;
|
|
|
+ scrollToPage(currentPage.value);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 新增翻页方法
|
|
|
+const prevPage = () => {
|
|
|
+ if (currentPage.value > 1) {
|
|
|
+ currentPage.value--;
|
|
|
+ scrollToPage(currentPage.value);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 新增滚动到指定页方法
|
|
|
+const scrollToPage = (pageNum) => {
|
|
|
+ if (pptContainer.value) {
|
|
|
+ // 计算目标滚动位置
|
|
|
+ const targetPosition = (pageNum - 1) * pageHeight.value;
|
|
|
+ // 设置滚动位置
|
|
|
+ pptContainer.value.scrollTop = targetPosition;
|
|
|
+ console.log(`滚动到第${pageNum}页,位置: ${targetPosition}`);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 初始化滚动位置
|
|
|
+onMounted(() => {
|
|
|
+ // 获取容器元素
|
|
|
+ pptContainer.value = document.querySelector('.ppt-container');
|
|
|
+ // 初始滚动到第一页
|
|
|
+ scrollToPage(1);
|
|
|
+})
|
|
|
+
|
|
|
+// PPT错误处理事件
|
|
|
+const handlePptError = (error) => {
|
|
|
+ console.error('PPT加载错误:', error)
|
|
|
+ ElMessage.error('PPT加载失败,请检查文件路径或格式')
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+@use 'sass:math';
|
|
|
+// 定义rpx转换函数
|
|
|
+@function rpx($px) {
|
|
|
+ @return math.div($px, 750) * 100vw;
|
|
|
+}
|
|
|
+
|
|
|
+.box-ppt {
|
|
|
+ width: 100%;
|
|
|
+ height: rpx(300);
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ .d-player-wrap {
|
|
|
+ height: rpx(289);
|
|
|
+ width: 68.5%;
|
|
|
+ border-radius: rpx(12);
|
|
|
+ object-fit: cover;
|
|
|
+ }
|
|
|
+}
|
|
|
+.ppt-box{
|
|
|
+ width: 100%;
|
|
|
+ height: rpx(200);
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+// 添加翻页动画样式
|
|
|
+.page-transition-enter-active,
|
|
|
+.page-transition-leave-active {
|
|
|
+ transition: all .5s ease;
|
|
|
+}
|
|
|
+.page-transition-enter-from {
|
|
|
+ opacity: .5;
|
|
|
+ transform: translateX(50px) scale(0.95);
|
|
|
+}
|
|
|
+.page-transition-leave-to {
|
|
|
+ opacity: .5;
|
|
|
+ transform: translateX(-50px) scale(0.95);
|
|
|
+}
|
|
|
+// 修改PPT内部预览容器样式
|
|
|
+::v-deep .pptx-preview-wrapper {
|
|
|
+ height: auto !important;
|
|
|
+}
|
|
|
+.ppt-container ::v-deep(.pptx-preview-wrapper) {
|
|
|
+ height: auto !important;
|
|
|
+ // 滚动条整体样式
|
|
|
+ &::-webkit-scrollbar {
|
|
|
+ width: rpx(0); // 滚动条宽度
|
|
|
+ height: rpx(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 滚动条滑块样式
|
|
|
+ &::-webkit-scrollbar-thumb {
|
|
|
+ background-color: #e2ddfc; // 滑块颜色
|
|
|
+ border-radius: rpx(4); // 滑块圆角
|
|
|
+ }
|
|
|
+
|
|
|
+ // 滚动条轨道样式
|
|
|
+ &::-webkit-scrollbar-track {
|
|
|
+ background-color: rgba(143, 116, 255, 0.2); // 轨道颜色
|
|
|
+ border-radius: rpx(4); // 轨道圆角
|
|
|
+ }
|
|
|
+ // border-radius: rpx(12);
|
|
|
+}
|
|
|
+
|
|
|
+.ppt-switch {
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ margin-top: rpx(5);
|
|
|
+ margin-bottom: rpx(15);
|
|
|
+}
|
|
|
+.caret-right,
|
|
|
+.caret-left {
|
|
|
+ width: rpx(50);
|
|
|
+ margin: auto;
|
|
|
+ display: flex;
|
|
|
+}
|
|
|
+.page-info{
|
|
|
+ color: #fff;
|
|
|
+}
|
|
|
+
|
|
|
+.caret-left ::v-deep(.el-button.is-round),
|
|
|
+.caret-right ::v-deep(.el-button.is-round) {
|
|
|
+ width: rpx(50);
|
|
|
+ height: rpx(15);
|
|
|
+ color: white;
|
|
|
+ font-size: rpx(7);
|
|
|
+ border-radius: none;
|
|
|
+ border: 1px white solid;
|
|
|
+ background-color: rgb(255, 255, 255, 0.5);
|
|
|
+ box-shadow: 0 4px 8px rgba(202, 52, 52, 0.1);
|
|
|
+}
|
|
|
+
|
|
|
+.caret-right img,
|
|
|
+.caret-left img {
|
|
|
+ width: rpx(12);
|
|
|
+}
|
|
|
+
|
|
|
+.ppt-container {
|
|
|
+ overflow: hidden; /* 禁用滚动条 */
|
|
|
+ border-radius: rpx(12);
|
|
|
+ width: 70%;
|
|
|
+ position: relative;
|
|
|
+ height: calc(50vw * 0.75); /* 使用vw单位实现响应式高度 */
|
|
|
+ max-height:80vh; /* 限制最大高度 */
|
|
|
+}
|
|
|
+
|
|
|
+// 修改PPT内部预览容器样式
|
|
|
+::v-deep .pptx-preview-wrapper {
|
|
|
+ height: auto !important;
|
|
|
+ transition: transform 0.3s ease; /* 添加平滑过渡 */
|
|
|
+}
|
|
|
+
|
|
|
+// 确保每张幻灯片占满容器高度
|
|
|
+::v-deep .slide-item {
|
|
|
+ height: rpx(620) !important;
|
|
|
+ width: 100% !important;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+</style>
|