epub电子书渲染

epubjs的核心工作原理解析

  • epub电子书
    会通过epubjs生成一个book对象
    • book
      renderTo方法
      • Rendition:负责渲染
        • Theme:负责主题
      • Location:负责定位,如进度条
      • Navigation:提供电子书目录

image-20240312182221963

电子书解析和渲染

创建Ebook.vue

先在src中创建Ebook.vue文件,用于渲染电子书阅读器

导入epubjs组件

在index.js中导入epubjs组件,并且重定向到Ebook.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import Vue from 'vue'
import Router from 'vue-router'
import Ebook from '@/Ebook'

Vue.use(Router)

export default new Router({
routes: [
{
path: '/',
redirect: '/ebook'
},
{
path: '/ebook',
component: Ebook
}
]
})

解析和渲染电子书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<template>
<div class="ebook">
<div class="read-wrapper">
<div id="read"></div>
</div>
</div>
</div>
</template>
<script>
import Epub from 'epubjs'
const DOWNLOAD_URL = '/static/鲁迅.epub'
global.ePub = Epub
export default {
methods: {
// 电子书解析和渲染
showEpub () {
// 生成ebook对象
this.book = new Epub(DOWNLOAD_URL)
// 生成Rendition,通过Book.renderTo
this.rendition = this.book.renderTo('read', {
width: window.innerWidth,
height: window.innerHeight
})
// 通过Rendtion.dispLay染电子书
this.rendition.display()
}
},
mounted () {
this.showEpub()
}
}
</script>

电子书翻页功能

在read上做一个浮层,分为左中右三个部分

1
2
3
4
5
6
7
8
<div class="read-wrapper">
<div id="read"></div>
<div class="mask">
<div class="left" @click="prebPage"></div>
<div class="center" @click="toggleTitleAndMenu"></div>
<div class="right" @click="nextPage"></div>
</div>
</div>

样式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 阅读器样式
.read-wrapper {
.mask {
position: absolute;
top: 0;
left: 0;
z-index: 100%;
display: flex;
width: 100%;
height: 100%;
.left {
flex: 0 0 px2rem(100);
}
.center {
flex: 1;
}
.right {
flex: 0 0 px2rem(100);
}
}
}

翻页

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
methods: {
// 点击中间切换显示菜单状态
toggleTitleAndMenu () {
this.ifTitleAndMenuShow = !this.ifTitleAndMenuShow
},
// 实现翻页,使用rendition的方法
prebPage () {
if (this.rendition) {
this.rendition.props()
}
},
nextPage () {
if (this.rendition) {
this.rendition.next()
}
},