书签实现
书签布局初始为top:-0.35rem
在上面隐藏,高度也为0.35rem,绝对定位。当鼠标拖拽屏幕向下拉到一定程度时,会显示一个向上的箭头以及“松手添加书签”的文本和一个蓝色的书签icon
书签icon的实现主要由下面两个样式
//1.设置border的宽度
this.$refs.bookmark.style.borderWidth = `${(this.height - 5) / 100}rem ${(this.width / 2) / 100}rem ${(5) / 100}rem ${(this.width / 2) / 100}rem`
//2.书签下面的小三角
borderColor: `${this.color} ${this.color} transparent ${this.color}`
首先watch两个全局变量offsetY和isBookmark(true则当前页面时书签页,否则不是),
isBookmark
:根据isBookmark设置书签是否固定以及颜色
isBookmark(v) {
this.isFixed = v
if (v) { //如果是书签则更改颜色
this.color = BLUE
} else {
this.color = WHITE
}
}
offsetY
:ebook-reader中的屏幕拖拽高度,可以分为三个状态- 状态1,offsetY有变化并且向下拖拽的高度小于书签布局高度0.35rem:当isBookmark为false说明是想为当前添加书签,文本为"松手添加书签",书签为白色并且还未固定;当isBookmark为true,说明此时是想要删除书签,文本为“松手删除书签”,此时还未松手所以书签还是会固定在当前页,书签颜色为蓝色
beforeHight(){ //状态1:未超过书签高度 if (!this.isBookmark) { //第一次向下拉添加书签 this.text = this.$t('book.pulldownAddMark') this.color = WHITE this.isFixed = false } else { //第二次向下拉删除书签 this.text = this.$t('book.pulldownDeleteMark') this.color = BLUE this.isFixed = true } },
- 状态2,offsetY大于书签高度但是还没有到达设定的阈值(0.5rem),让书签一起被拖动实现相对静止,并再一次进行状态1的判断,让箭头不反转,书签不进行固定
beforeThreshold(v){ //状态2:未到达零界状态 //让ebookBookmark一起拖动,实现相对静止 this.$refs.ebookBookmark.style.top = `${-v / 100}rem` // console.log('ebookBookmark top:', this.$refs.ebookBookmark.style.top); const iconDown = this.$refs.iconDown this.beforeHight() if (iconDown.style.transform === 'rotate(180deg)') { iconDown.style.transform = 'rotate(0deg)' } this.isFixed = false },
- 状态3,offsetY大于设定阈值:让书签一起拖动,并且让书签进行180°的翻转向上,并且如果当前isBookmark为false,则添加书签,给文本赋值"松手添加书签",书签颜色变蓝,固定在表面;isBookmark为true,则删除书签,给文本赋值"松手删除书签",书签颜色变白,不固定
afterThreshold(v){ //状态3:超越零界状态 this.$refs.ebookBookmark.style.top = `${-v / 100}rem` if (this.$refs.iconDown.style.transform === 'rotate(0deg)' || this.$refs.iconDown.style.transform === '') { this.$refs.iconDown.style.transform = 'rotate(180deg)' } if (!this.isBookmark) { this.text = this.$t('book.releaseAddMark') //松手添加书签 this.color = BLUE this.isFixed = true } else { this.text = this.$t('book.releaseDeleteMark') //松手删除书签 this.color = WHITE this.isFixed = false } },
- 状态4,offsetY为0,这种情况是发生在添加或者删除书签向下拉拽后松手,offset归位到0,根据isFixed变量判断,如果在前面三种情况中将isFixed置为true则是要添加书签的情况,添加书签则将isBookmark变量置为true,并且调用addBookmark方法将书签页保存到localStorge中;否则是删除书签的情况,调用removeBookmark()将当前书签页从localStorge中删除
restore(){ //状态4:归位操作
setTimeout(() => {
this.$refs.bookmark.style.top = `${-this.height / 100}rem`
this.$refs.iconDown.style.transform = 'rotate(0deg)'
}, 200)
if (this.isFixed){ //如果已经固定了则将书签当前页内容保存到localStorge中
this.setIsBookmark(true)
this.addBookmark()
} else {
this.removeBookmark()
}
},
添加书签
addBookmark() {
this.bookmark = getBookmark(this.fileName)
if (!this.bookmark) {
this.bookmark = []
}
const currentLocation = this.currentBook.rendition.currentLocation()
// console.log('currentLocation:', currentLocation);
//找到!之后的内容
// const cfibase = currentLocation.start.cfi.replace(/!.*/, '').replace('epubcfi(', '')
// cfibase: epubcfi(6/4[A387243_1_En_Book Frontmatter_OnlinePDF])
const cfibase = currentLocation.start.cfi.replace(/!.*/, '')
// console.log('cfibase:', cfibase)
const cfistart = currentLocation.start.cfi.replace(/.*!/, '').replace(/\)$/, '')
const cfiend = currentLocation.end.cfi.replace(/.*!/, '').replace(/\)$/, '')
// console.log('cfistart:', cfistart, 'cfiend:', cfiend);
//cfiRange: epubcfi(epubcfi(/6/4!,/4/2/2/2/1:0,/4/2/6/16/6/1:243)
const cfiRange = `${cfibase}!,${cfistart},${cfiend})`
const cfi = currentLocation.start.cfi
//获取这个范围内的内容
this.currentBook.getRange(cfiRange).then(range => {
// console.log('range:', range);
let text = range.toString()
//查找两个空格
text = text.replace(/\s\s/g, '')
text = text.replace(/\r/g, '')
text = text.replace(/\n/g, '')
text = text.replace(/\t/g, '')
text = text.replace(/\f/g, '')
this.bookmark.push({
cfi: cfi,
text: text
})
this.setIsBookmark(true)
saveBookmark(this.fileName, this.bookmark)
})
},
删除书签
removeBookmark() {
const currentLocation = this.currentBook.rendition.currentLocation()
const cfi = currentLocation.start.cfi
this.bookmark = getBookmark(this.fileName)
if (this.bookmark) {
this.bookmark = this.bookmark.filter(item => item.cfi !== cfi)
saveBookmark(this.fileName, this.bookmark)
}
// console.log('bookmark:', this.bookmark)
this.setIsBookmark(false)
}
书签固定在表面的样式
fixedStyle() {
return {
position: 'fixed',
right: `${(window.innerWidth - this.$refs.ebookBookmark.clientWidth) / 2}px`,
top: 0
}
}