用Epub.js引擎开发阅读器
实现功能
电子书解析渲染,获取文献封面,文献信息,获取阅读进度progress,高亮选中文本进而实现笔记功能。
使用node.js的npm安装epub.js引擎
npm install epubjs --save
script标签内的关键js代码
电子书解析和渲染,高亮文本(另外的dialog组件做笔记),获取文献信息,封面信息,上一页,下一页,更新进度等。
import Epub from 'epubjs'
export default {
name: 'index',
data () {
return {
drawer: false,
infoDrawer: false,
notesDrawer: false,
direction: 'rtl',
size: '400px',
book: {},
coverUrl: '',
rendition: {},
navigation: {},
bookAvailable: false,
metadata: {},
notes: [],
noteIndex: 0,
dialogFormVisible: false,
dialogNotesUpdate: '',
progress: 0,
selection: null
}
},
mounted () {
console.log('query: ', this.$route.query)
this.showEpub()
},
methods: {
updateProgress () {
// 获得当前章节的百分比并设置 保留6位小数
const currentLocation = this.book.rendition.currentLocation()
this.progress = currentLocation.end.percentage.toFixed(6)
console.log('updateProgress:', this.progress)
},
displayProgress (progress) {
this.progress = progress
// 获得cfi地址 // progress的范围: 0-1
const location = progress > 0 ? this.book.locations.cfiFromPercentage(progress) : 0
// 根据cfi地址渲染电子书
this.book.rendition.display(location)
},
showNoteDialog (index) {
this.noteIndex = index
this.dialogFormVisible = true
this.dialogNotesUpdate = this.notes[index].note
},
updateNotes (noteIndex) {
this.notes[noteIndex].note = this.dialogNotesUpdate
},
addNotes (text) {
this.$message.success('成功新增一条标记!')
this.notes.push({'mark': text, 'note': ''})
},
confirmDelete (index) {
this.notes.splice(index, 1)
this.$message.success('删除成功!')
},
// 返回上一页(书架)
goBack () {
this.$router.go(-1)
},
// 根据链接跳转到指定位置
jumpTo (href) {
this.drawer = false
this.rendition.display(href).then(() => {
this.updateProgress()
})
},
// 上一页
prevPage () {
if (this.rendition) {
this.rendition.prev().then(() => {
this.updateProgress()
})
}
},
// 下一页
nextPage () {
if (this.rendition) {
this.rendition.next().then(() => {
this.updateProgress()
})
// const location = percentage > 0 ? this.locations.cfiFromPercentage(percentage) : 0
// this.rendition.display(location)
}
},
showEpub () { // 电子书解析渲染
this.book = new Epub(this.$route.query.bookUrl) // 生成Book对象
// 获取文献信息
this.book.loaded.metadata.then(metadata => {
this.metadata = metadata
})
// 获取封面信息
this.book.loaded.cover.then(cover => {
this.book.archive.createUrl(cover).then(url => {
this.coverUrl = url
})
})
// 通过Book.renderTo生成Rendition对象
this.rendition = this.book.renderTo('read', {
width: window.innerWidth - 460,
height: window.innerHeight - 130,
method: 'default'
})
// Illustration of how to get text from a saved cfiRange
let that = this
this.rendition.on('selected', function (cfiRange, contents) {
this.book.getRange(cfiRange).then(function (range) {
if (range) {
const text = range.toString()
that.addNotes(text)
}
})
})
// Apply a class to selected text
this.rendition.themes.default({
'::selection': {
'background': 'rgba(255,255,0, 0.3)'
},
'.epubjs-hl': {
'fill': 'yellow', 'fill-opacity': '0.3', 'mix-blend-mode': 'multiply'
}
})
// Book对象的钩子函数ready
this.book.ready.then(() => {
this.navigation = this.book.navigation
// 生成Locations对象
return this.book.locations.generate()
}).then(result => {
// 保存locations对象
this.locations = this.book.locations
// 根据 progress 渲染电子书 // progress数值(0-1)小数
this.displayProgress(0.0092)
// 标记电子书为解析完毕状态
this.bookAvailable = true
})
}
}
}
</script>