当前位置: 首页 > news >正文

网站建设协网站是干嘛用的

网站建设协,网站是干嘛用的,杭州做网站好的公司排名,广告制作的软件实现样式 需求 实现PDF上传预览,并且不能下载 第一次实现:用vue-pdf,将上传的文件用base64传给前端展示 问题: 水印第一次加载有后面又没有了。当上传大的pdf文件后,前端获取和渲染又长又慢,甚至不能用 修…

实现样式

在这里插入图片描述

需求

实现PDF上传预览,并且不能下载

第一次实现:用vue-pdf,将上传的文件用base64传给前端展示
问题:

  1. 水印第一次加载有后面又没有了。
  2. 当上传大的pdf文件后,前端获取和渲染又长又慢,甚至不能用

修改实现模式

  1. 前端上传PDF,后端将PDF转化成一页一页的图片
  2. 前端根据page去获取一页一页的PDF图片,类似于百度文库

实现思路

配合后端实现思路

  1. 获取全部页数,先把侧边栏的元素画出来占个位置
  2. 获取已经看到的页数,没有默认1
  3. 渲染上次看到的页数,同时侧边栏滚动到相同的index位置,通过监听元素是否进入视口去获取base64图片
  4. 已经获取回来的图片不再去请求

主要重点难点是侧边栏懒加载定位等比例展示图片

 <div class="pdf-viewer"><div class="pdf-main"><canvas id="pdf-view"></canvas></div><div class="pdf-list" :class="{ collapse: collapse }"><divclass="pdf-item":class="{ active: currentPage === index }"v-for="index in pageTotalNum":key="index"@click="changePage(index)":data-index="index"><img :src="imgList[index - 1]" alt="" /></div></div></div><script>
let observer = null;
export default {name: "PDFView",data() {return {currentPage: 1, //当前页数pageTotalNum: 1, //总页数imgList: [], //base64图片列表updateTimer: null};},watch: {/*** @description 监听当前页变化 滚动列表到顶部*/currentPage() {this.$nextTick(() => {const activeEl = document.querySelector(".pdf-list .active");if (activeEl) {document.querySelector(".pdf-list").scrollTo({top: activeEl.offsetTop - 20,behavior: "smooth",});// 解决进来会请求当前页数 前面所有图片setTimeout(() => {if (observer) {observer.disconnect();}this.isEnter();}, 500);}// 切换页面 将查看区域滚动到最上面const mainEl = document.querySelector(".pdf-main");mainEl.scrollTo({top: 0,});});},},mounted() {this.getPageTotal();},beforeDestroy() {if (observer) {observer.disconnect();}},methods: {/*** @description 获取pdf总页数*/getPageTotal() {const params = {id: this.$route.query.id,};apiGetViewPdfPageTotal(params).then((response) => {this.pageTotalNum = response.data;this.updateStudy(true);});},/*** @description 切换当前页*/changePage(index) {this.currentPage = index;this.updateStudy();if (this.imgList[index - 1]) {this.drawImage(this.imgList[index - 1]);} else {this.getPdf();}},/*** @description 上一页*/prePage() {let page = this.currentPage;if (page !== 1) {page = page > 1 ? page - 1 : this.pageTotalNum;this.currentPage = page;this.updateStudy();if (this.imgList[page - 1]) {this.drawImage(this.imgList[page - 1]);} else {this.getPdf();}}},/*** @description 下一页*/nextPage() {let page = this.currentPage;if (page !== this.pageTotalNum) {page = page < this.pageTotalNum ? page + 1 : 1;this.currentPage = page;this.updateStudy();if (this.imgList[page - 1]) {this.drawImage(this.imgList[page - 1]);} else {this.getPdf();}}},/*** @description 更新学习 flag=true第一次进入*/updateStudy(flag = false) {const params = {courseId: this.$route.query.id,pageRate: this.currentPage,flag,totalPageRate: this.pageTotalNum,};apiUpdateStudy(params).then((response) => {this.currentPage = response.data.pageRate;if (flag) {this.updateTimer = setInterval(() => {this.updateStudy();}, 1000 * 10);}if (flag) {this.getPdf();// 解决第一页进来不请求的问题,一页大概能展示4-5张if (this.currentPage < 5) {this.isEnter();}}})},/*** @description 查看资料*/getPdf() {const params = {id: this.$route.query.id,page: this.currentPage,};apiGetPdf(params).then((response) => {let base64 = "data:image/png;base64," + response.data;this.drawImage(base64);});},/*** @description 将base64图片 画到canvas上*/drawImage(base64) {const canvas = document.getElementById("pdf-view");const context = canvas.getContext("2d");const image = new Image();image.src = base64;image.onload = () => {const proportion = image.width / image.height;// 获取style设置width:100% 的canvas宽度const canvasWidth = canvas.offsetWidth;// 图片宽度与canvas宽度比例const canvasWidthProportion = image.width / canvasWidth;// canvas宽度设置为宽度canvas.width = image.width;// 根据图片比例和宽度比例计算出canvas高度canvas.height = (canvasWidth / proportion) * canvasWidthProportion;context.drawImage(image, 0, 0);};},/*** @description 监听元素进入视口*/isEnter() {observer = new IntersectionObserver((entries) => {entries.forEach((entry) => {const target = entry.target;const index = target.dataset.index;if (entry.isIntersecting) {if (!this.imgList[index - 1]) {this.getImgList(index);}} else {// console.log("元素离开视口", index);}});});this.$nextTick(() => {//将所有侧边栏的元素进行监听const els = document.querySelectorAll(".pdf-item");Array.from(els).forEach((el) => {observer.observe(el);});});},/*** @description 滚动获取图片*/getImgList(index) {const params = {id: this.$route.query.id,page: index,};apiGetPdf(params).then((response) => {let base64 = "data:image/png;base64," + response.data;this.imgList[index - 1] = base64;// 解决请求回来页面没更新的问题this.$forceUpdate();});},},
};
</script><style lang="scss" scoped>
.pdf-container {width: 100%;height: 100%;color: #999;
}
.pdf-viewer {width: 100%;height: calc(100vh - 50px - 30px - 60px - 6px);position: relative;display: flex;
}
.pdf-list {width: 240px;overflow-y: auto;display: flex;flex-direction: column;padding: 20px;background: #000;box-sizing: border-box;// transition: all 0.3s ease-in-out;border-left: 1px solid #999;&::-webkit-scrollbar {width: 0px;}.pdf-item {height: 183px;min-height: 183px;display: inline-flex;justify-content: center;align-items: center;cursor: pointer;overflow: hidden;&:hover {::v-deep img {transition: all 0.5s ease-in-out;transform: scale(1.1);}}&.active {box-shadow: 0px 0px 0px 4px #e6a23c;}&:not(:last-child) {margin-bottom: 10px;}img {pointer-events: none;width: 100%;// height: 100%;}}&.collapse {width: 0;padding: 0;}
}
.pdf-main {flex: 1;// width: 100%;// height: 100%;overflow-y: auto;background: #000;position: relative;padding: 10px 0;&::-webkit-scrollbar {width: 0px;}
}
.handle-btn {background: #000;display: flex;font-size: 12px;position: relative;height: 60px;padding: 0 6px;border-bottom: 1px solid #999;.right {width: 240px;display: flex;align-items: center;justify-content: flex-end;font-size: 32px;}.main {flex: 1;display: flex;align-items: center;justify-content: center;font-size: 32px;margin-left: 250px;.pagination {display: flex;align-items: center;margin: 0 10px;.pagination-info {font-size: 14px;margin: 0 8px;}}.zoom {display: flex;align-items: center;margin: 0 10px;.scale {font-size: 14px;margin: 0 8px;}}}.tips {color: #e6a23c;font-size: 12px;}.start-test {display: flex;align-items: center;}.time {position: absolute;left: 6px;top: 50%;transform: translateY(-50%);> span {display: inline-block;margin-left: 10px;}}
}
i {cursor: pointer;&:hover {color: #fff;}
}
#pdf-view {width: 100%;// height: 100%;padding: 10px;
}
</style>
http://www.yayakq.cn/news/546577/

相关文章:

  • 简单学校网站模板网站备案不能访问
  • 主题资源网站建设反思微商软件代理
  • 做外贸站推广简述网站规划的一般步骤
  • 如何分析一个网站wordpress英文变成中文
  • 美容营销型网站网站建设哪家比较好
  • 陕西网站建设开发什么网站可以做章
  • 化工网站建站模板下载服务器用来做网站和数据库
  • 长春做网站外包wordpress写文章分段
  • 做外贸需要哪些网站wordpress景点展示插件
  • 网站备案核验单怎么填预装wordpress主机
  • 网站一年多少钱?云南响应式网站建设
  • 兴国做网站工作室装修网站源码
  • 黄金网站app在线观看下载10网站的ftp地址是什么
  • 滨州网站建设铭盛信息阿里云网站建设详细教程
  • 做网站 钱如何设计自己的网站
  • 国外网站设计风格todoist wordpress
  • 下列关于网站开发中网页发布厦门正规网站建设多少
  • 建wiki网站自己做的网站可以卖
  • 响应式网站模版建站电脑宽带网站
  • 网站设建设网站建设基本费用
  • 网站横幅怎么更换合肥市中小企业局网站
  • 富连网网站开发店铺首页设计步骤
  • 河北提供网站制作公司报价上海公司买房最新政策2021
  • 关于成立网站建设项目小组的通知建设公司logo
  • 开发公司把已经出售的房子一房二卖卖给股东个人百度seo公司电话
  • 网站开发数据接口如何利用建瓯市建设局网站
  • 为何只有建设银行网站打不开南阳建设网站制作
  • 江苏网站集约化建设多平台网页制作
  • 做电脑网站手机能显示不出来网页怎么制作视频
  • 建设网站用图片需要版权网站建设优化经验