PDFProfile.vue代码存档
xx教学模式下生物课程某素养能力的提升探究
<template>
<v-container>
<v-row>
<v-col cols="12">
<div ref="pdfViewerContainer" class="pdf-viewer-container"></div>
</v-col>
</v-row>
</v-container>
<v-app>
<!-- 左侧按钮 -->
<v-btn color="success" class="left-button" @click="handleLeftButtonClick">
Left Button
</v-btn>
<!-- 按钮控制部分 -->
<v-btn color="primary" class="drawer-toggle-btn" @click="toggleDrawer">
<v-icon>{{ drawer ? 'mdi-chevron-right' : 'mdi-chevron-left' }}</v-icon>
</v-btn>
<!-- 抽屉 -->
<v-navigation-drawer v-model="drawer" location="right" app temporary :width="drawerWidth" class="custom-drawer"
:scrim="false" @click:outside="handleOutsideClick">
<!-- 抽屉内容 -->
<v-list>
<!-- <v-list-item>
<v-list-item-avatar>
<v-img src="https://randomuser.me/api/portraits/men/78.jpg" />
</v-list-item-avatar>
<v-list-item-content>
<v-list-item-title>John Leider</v-list-item-title>
</v-list-item-content>
</v-list-item> -->
<!-- <v-divider></v-divider> -->
<v-list density="compact" nav>
<v-row>
<v-list-item prepend-icon="mdi-view-dashboard" title="信息" value="home"></v-list-item>
<v-list-item prepend-icon="mdi-forum" title="书中图片" value="about"></v-list-item>
<v-list-item prepend-icon="mdi-account" title="外部资源" value="profile"></v-list-item>
<v-list-item prepend-icon="mdi-cog" title="智能问答" value="settings"></v-list-item>
</v-row>
</v-list>
</v-list>
</v-navigation-drawer>
</v-app>
</template>
<script>
import { onMounted, ref } from 'vue';
import * as pdfjsLib from 'pdfjs-dist';
export default {
name: 'TextbookDetail',
data () {
return {
textbookId: this.$route.params.id, // 获取教材的ID
pdfUrl: '', // 用于存储 PDF 文件的 URL
//关于抽屉组件
drawer: false, // 控制抽屉显示/隐藏状态
drawerWidth: 600, // 抽屉宽度
};
},
methods: {
async fetchPdfUrl () {
try {
const response = await fetch(`http://127.0.0.1:8000/api/get_textbook_pdf/${this.textbookId}/`);
if (!response.ok) {
throw new Error('Failed to fetch PDF URL');
}
else console.log("yes")
// const responseText = await response.text(); // 获取原始响应内容
// console.log('Response Text:', responseText); // 输出响应内容
const data = await response.json();
console.log('Returned data:', data);
this.pdfUrl = data.pdf_url;
console.log('PDF URL:', this.pdfUrl);
// this.renderPdf(); //渲染PDF
} catch (error) {
console.error('Failed to fetch PDF URL:', error);
}
},
async renderPdf() {
if (!this.pdfUrl) return;
const fullPdfUrl = `${this.pdfUrl}`;
// 设置 PDF.js 的 worker 路径
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.10.377/pdf.worker.min.js';
console.log("Fetching PDF from URL:", fullPdfUrl);
const pdf = await pdfjsLib.getDocument(fullPdfUrl).promise;
const numPages = pdf.numPages;
console.log("PDF successfully fetched. Total pages:", numPages);
const container = this.$refs.pdfViewerContainer;
container.innerHTML = ''; // 清空已有内容
for (let pageNum = 1; pageNum <= numPages; pageNum++) {
const page = await pdf.getPage(pageNum);
const scale = 1.5; // 缩放比例
const viewport = page.getViewport({ scale });
// 创建页面容器
const pageDiv = document.createElement('div');
pageDiv.setAttribute('id', `page-${page.pageIndex + 1}`);
pageDiv.setAttribute('style', 'position: relative; margin-bottom: 20px;');
container.appendChild(pageDiv);
// 创建 Canvas 渲染图层
const canvas = document.createElement('canvas');
pageDiv.appendChild(canvas);
const context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
const renderContext = {
canvasContext: context,
viewport: viewport,
};
// 渲染 Canvas 图层
await page.render(renderContext).promise;
// 渲染文本图层
const textContent = await page.getTextContent();
// 创建文本图层的容器
const textLayerDiv = document.createElement('div');
textLayerDiv.setAttribute('class', 'text-layer');
textLayerDiv.setAttribute('style', 'position: absolute; top: 0; left: 0; width: 100%; height: 100%;');
pageDiv.appendChild(textLayerDiv);
// PDF.js 提供的 TextLayer 渲染文本内容
pdfjsLib.renderTextLayer({
textContent: textContent,
container: textLayerDiv,
viewport: viewport,
textDivs: [] // 用于存放文本div元素
});
}
},
//抽屉判断
toggleDrawer () {
this.drawer = !this.drawer;
console.log('按钮点击,当前状态:', this.drawer);
},
// 处理点击空白区域的事件
handleOutsideClick () {
// 这里阻止默认行为,确保点击空白区域不关闭抽屉
},
//占位:左侧按钮
handleLeftButtonClick () {
console.log("Left button clicked!"); // 左侧按钮的点击处理
},
},
mounted () {
this.fetchPdfUrl();
}
};
</script>
<style scoped>
.pdf-viewer-container {
width: 100%;
height: 100%;
overflow: auto;
position: relative;
padding: 20px;
}
.text-layer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none; /* 防止文本层阻挡交互 */
z-index: 2; /* 确保文本层在 canvas 上方 */
}
/* 调整抽屉样式 */
.custom-drawer {
height: 100vh;
/* 抽屉高度占满页面 */
background-color: #f8f9fa;
/* 浅灰色背景 */
border-left: 1px solid #ddd;
}
/* 调整按钮位置 */
.drawer-toggle-btn {
position: fixed;
/* 固定定位 */
top: 50%;
/* 距离顶部 50% */
right: 0;
/* 靠页面最右边 */
transform: translate(50%, -50%);
/* 微调位置居中对齐 */
z-index: 1000;
/* 确保按钮在页面内容上方 */
border-radius: 50%;
width: 48px;
height: 48px;
box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
display: flex;
justify-content: center;
align-items: center;
}
/*-----------------------------------------------*/
canvas {
display: block;
margin-bottom: 20px;
}
</style>
我与你同行。