当前位置:   article > 正文

uniapp开发epub阅读器保姆级教程_uniapp小说阅读器

uniapp小说阅读器

前言

阅读器的基本功能:翻页、字体大小设置、切换背景主题色、进度条功能、目录与跳转、添加书签、获取电子书信息、获取当前章节总页码和页数等

功能的实现

 1.引入epubjs

使用命令安装0.3.71版本 epubjs

npm i epubjs@0.3.71

注:这里之前踩过坑,其他版本进行切换主题时,每一个背景颜色只能切换一次,再次选择其他主题不生效。

解决方法:将版本更换到 0.3.71

2.为电子书准备容器

添加一个 id read view 标签。

<view id="read" />

3.渲染电子书

onLoad 生命周期中对电子书进行渲染。

通过 new 一个 Epub 对电子书进行初始化解析,生成 book

  1. onLoad() {
  2. this.showEpub();
  3. },
  4. methods:{
  5. showEpub(){
  6. // 对电子书进行初始化解析,路径可以是相对路径或者绝对路径
  7. this.book = new Epub("https://mp-9281e2b4-5558-4603-841a-433fcefa275b.cdn.bspapp.com/cloudstorage/108ca182-d460-4f65-be1b-5819d82d4dfd.epub"
  8. );
  9. }
  10. }

有了电子书的路径后,对电子书进行渲染。

  •  book 通过 renderTo 方法对电子书进行渲染,生成 rendition 对象。
  •  renderTo 有两个参数:第一个参数是 view 标签的 id ,将生成的 dom 挂在该 id 的容器上;第二个参数是用来指定电子书的样式和属性,包括宽高,翻页方式等。
  •  rendition 再通过 display 方法渲染完成, display 支持两种参数:①章节目录中的 href 链接,可以跳转至指定章节;② cfi 值,为 epubcfi 规范的一个值,不用细究他的构成,能获取到就行。 display 后面不传参数时默认为 0 ,渲染到首页。
  1. showEpub(){
  2. // 通过new一个Epub对电子书进行初始化解析,生成book,路径可以是相对路径或者绝对路径
  3. this.book = new Epub("https://mp-9281e2b4-5558-4603-841a-433fcefa275b.cdn.bspapp.com/cloudstorage/108ca182-d460-4f65-be1b-5819d82d4dfd.epub");
  4. // book通过renderTo方法对电子书进行渲染,生成rendition对象
  5. this.rendition = this.book.renderTo("read",{
  6. allowScriptedContent: true,
  7. snap: true,
  8. restore: false,
  9. width: "100vw",
  10. height: "100vh",
  11. manager: "continuous",
  12. spread: "none",
  13. flow:
  14. this.flowIndex === 0
  15. ? "scrolled-doc"
  16. : this.flowIndex === 1
  17. ? "paginated"
  18. : "", //scrolled-doc滚动 paginated分页
  19. })
  20. // 通过display方法进行渲染
  21. this.rendition.display()
  22. }

4.翻页功能

此处为点击翻页功能,可以为点击屏幕左侧 25% ,或者点击屏幕右侧 25% 进行翻上一页和下一页操作。

翻页方法是异步的,会返回一个 promise ,进行后续的操作。

  1. // 上一页
  2. prevPage() {
  3. if (this.rendition) {
  4. this.rendition.prev().then(() => {
  5. // 其他逻辑代码
  6. });
  7. }
  8. },
  9. // 下一页
  10. nextPage() {
  11. if (this.rendition) {
  12. this.rendition.next().then(() => {
  13. // 其他逻辑代码
  14. });
  15. }
  16. },

5.字体大小设置

定义一个 theme ,通过 rendition 中的 Theme 对象属性进行字号主题等功能设置。

在这里可以用一个进度条控件,动态设置 fontsize 大小,并且保存到缓存中,以便下次进入电子书时获取字体大小。字体大小单位为 "px"

  1. this.themes = this.rendition.themes
  2. this.themes.fontSize(this.fontsize + "px")

 6.切换背景主题色

与字体大小设置一样,切换主题时用的也是 theme 对象属性。

通过 theme.register() 为电子书添加主题,通过 theme.select(name) 选择已经添加好的主题。

  1. // data中定义好主题数组
  2. themeList:[
  3. {
  4. name: "default", // 主题名字
  5. style: { // 主题样式
  6. body: {
  7. color: "#494948", // 文字颜色
  8. background: "#F4F3EF", // 背景颜色
  9. lineColor: "#E4E3DF", // 主题中并无该属性,该属性为自定义目录下划线颜色
  10. },
  11. },
  12. },
  13. {
  14. name: "twoTheme",
  15. style: {
  16. body: {
  17. color: "#39342B",
  18. background: "#D5C6A9",
  19. lineColor: "#C6B89B",
  20. },
  21. },
  22. },
  23. {
  24. name: "threeTheme",
  25. style: {
  26. body: {
  27. color: "#94938F",
  28. background: "#3A3031",
  29. lineColor: "#3F3939",
  30. },
  31. },
  32. },
  33. {
  34. name: "fourTheme",
  35. style: {
  36. body: {
  37. color: "#313635",
  38. background: "#CCE8D1",
  39. lineColor: "#BCD8C1",
  40. },
  41. },
  42. },
  43. {
  44. name: "fiveTheme",
  45. style: {
  46. body: {
  47. color: "rgb(100,110,119)",
  48. background: "#051827",
  49. lineColor: "#0C1E2D",
  50. },
  51. },
  52. },
  53. ]
  54. methods:{
  55. // 渲染电子书后调用
  56. registerTheme() {
  57. this.themeList.forEach((item) => {
  58. this.themes.register(item.name, item.style);
  59. });
  60. },
  61. // 触发改变电子书背景主题时调用
  62. setTheme(index) {
  63. this.themes.select(this.themeList[index].name);
  64. },
  65. }

7.进度条功能

  1. 进度条功能需要获取 locations 对象,由于 locations 对象的生成比较消耗性能,所以默认是不会生成 locations 对象的。
  2. 通过 epubjs 的钩子函数来实现。借助 book 解析完成之后回调的 ready 方法来生成。
  3. 通过 book locations.cfiFromPercentage() 方法获取当前百分比所对应的 epubcfi ,通过 this.rendition.display(epubcfi) 渲染即可跳到相应位置。

注:在进度条可操作之前,必须是分页执行完之后得到 location 对象才可对进度条进行操作。(可添加一标识,判断 locations 对象是否得到,未得到时提示进度条加载中,完成后显示在操作)。

  1. showEpub(){
  2. // 通过new一个Epub对电子书进行初始化解析,生成book,路径可以是相对路径或者绝对路径
  3. this.book = new Epub("https://mp-9281e2b4-5558-4603-841a-433fcefa275b.cdn.bspapp.com/cloudstorage/108ca182-d460-4f65-be1b-5819d82d4dfd.epub");
  4. // book通过renderTo方法对电子书进行渲染,生成rendition对象
  5. this.rendition = this.book.renderTo("read",{
  6. allowScriptedContent: true,
  7. snap: true,
  8. restore: false,
  9. width: "100vw",
  10. height: "100vh",
  11. manager: "continuous",
  12. spread: "none",
  13. flow:
  14. this.flowIndex === 0
  15. ? "scrolled-doc"
  16. : this.flowIndex === 1
  17. ? "paginated"
  18. : "", //scrolled-doc滚动 paginated分页
  19. })
  20. // 通过display方法进行渲染
  21. this.rendition.display()
  22. this.book.ready
  23. .then(() => {
  24. return this.book.locations.generate();
  25. })
  26. .then((result) => {
  27. // result为book生成电子书的cfi的一个数组。与下面this.locations中的_locations属性一致
  28. this.locations = this.book.locations;
  29. console.log("locations", this.locations);
  30. // bookAvailable标识,默认为false,为true时代表进度条可操作
  31. this.bookAvailable = true;
  32. })
  33. }

调整进度条跳转至对应页面。

  1. onProgressChange(e) {
  2. // e为进度条保留两位小数点的数字
  3. const percentage = e / 100;
  4. // location为根据进度生成的cfi值
  5. const location =
  6. percentage > 0 ? this.locations.cfiFromPercentage(percentage) : 0;
  7. console.log("location", location);
  8. this.rendition.display(location);
  9. },

8.目录与跳转

  1. 通过 book navigation 对象,可以获取到电子书的目录。
  2. 通过 epubjs 的钩子函数来实现。借助 book 解析完成之后回调的 ready 方法来生成。
  3. 由于目录为一个 tree 类型,所以页面上需用 tree 组件来渲染。
  1. this.book.ready
  2. .then(() => {
  3. this.navigation = this.book.navigation;
  4. // toc为总目录,目录可分级
  5. this.toc = this.book.navigation.toc;
  6. return this.book.locations.generate();
  7. })
  8. .then((result) => {
  9. // result为book生成电子书的cfi的一个数组。与下面this.locations中的_locations属性一致
  10. this.locations = this.book.locations;
  11. console.log("locations", this.locations);
  12. // bookAvailable标识,默认为false,为true时代表进度条可操作
  13. this.bookAvailable = true;
  14. })

 Navigation.toc 表示电子书的目录结构,是一个数组, toc 下的每一个元素对应一个目录, toc[n].href 表示目录路径(链接), toc[n].label 是当前目录的名字, toc[n].subitems 里面包含的是该目录下还有其他的二级(三级)目录,可根据需要使用几级目录。

获取到目录后,可以通过点击树组件中的章节获取到该章节对应的数据( toc 数组中某一项),再根据该项中的 href 属性进行跳转。

  1. jumpTo(item){
  2. this.rendition.display(item.href)
  3. }

9.添加书签

添加书签功能需要使用到 rendition 对象中的 currentLocation 方法。

 currentLocation.start.cfi 为当前页的 cfi 值,可根据该 cfi 值进行跳转。

  1. // 获取当前页cfi值并保存到数组中
  2. handleMark() {
  3. const currentLocation = this.book.rendition.currentLocation();
  4. this.bookmarks.push(currentLocation.start.cfi);
  5. },
  6. // 点击,根据cfi值跳转
  7. toMark(cfi) {
  8. this.rendition.display(cfi)
  9. },

 10.获取电子书信息

通过 book 中的 package 对象获取电子书信息:

  •  manifest 用来获取电子书的所有用到的文件信息;
  •  metadata 用来获取电子书的出版信息,其中 titile 为电子书的名字;
  •  ncxPath 为目录的路径;
  •  spine 为阅读顺序。
  1. this.book.loaded.metadata.then((meta) => {
  2. console.log("meta", meta);
  3. this.meta= meta;
  4. });

11.获取当前章节页码和总页数

获取当前章节页码和总页数与添加书签功能一样需要用到 rendition 对象中的 currentLocation 方法。

total:当前章节总页数;

page:当前页在当前章节页码。

  1. showPage(page) {
  2. const currentLocation = this.book.rendition.currentLocation();
  3. console.log("当前位置", {
  4. ...currentLocation.start.displayed,
  5. });
  6. this.bookInfo.pageInfo = {
  7. total: page?.total || currentLocation.start.displayed.total,
  8. page: page?.page || currentLocation.start.displayed.page,
  9. };
  10. },

总结

以上就完成了基于 epubjs 开发的基本的阅读器功能,样式和点击事件部分可以由各位根据需求来添加,如有问题和错误之处欢迎指出~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/820813
推荐阅读
相关标签
  

闽ICP备14008679号