简介
一个阅读英文版哈利波特的小网站reader,源码放到GitHub上了,感兴趣的可以看看。打开书籍后双击单词能够显示释义(如果有的话),如下图。推荐使用chromium-edge阅读,翻页动画更舒服。
动机
大概是一两年前吧,因为想看看哈利波特英文原版,就在网上找了epub格式的电子书来看。当时用win10的edge浏览器看epub还是非常舒服的,不过因为自带的翻译是英英互译的,所以就想要是能变成中文的就好了。搜罗了一些方法之后发现无果,就放弃了。后来2019下半年的时候,edge不支持看epub电子书了,很无奈,不过也更加坚定了做一个英文阅读网站的目标了。然后就有了reader这个项目。
功能实现
翻译
核心功能就是选中单词后显示单词翻译。因为有道、谷歌等的翻译API不是免费的,所以在GitHub上找了个词库,把词库导入导入到了数据库中用,但翻译的效果差强人意,还算凑合。另外,最初是打算做成鼠标悬浮显示翻译,搜索了一番发现只能通过将每个单词用标签包裹,设置标签的mousehover事件实现,但是这样的话,如果内容很多就会就会卡顿,体验极差。当然进一步的考虑就是每次只加载一页内容,按需加载,使用动画实现翻页等,摸索了一番,发现只会使网页更加复杂,难于实现。于是就改为了选中单词显示翻译,这样的话只需要考虑mouseup, selectionchange,selectstart
等事件,算是一种折中。
翻页动画
最初的想法其实是一个win客户端,并且核心功能还包括一个更好的翻页动画实现,参考edge的滚动动画。但是进一步考虑后发现完全可以做成一个网站,然后使用edge(chromium版)浏览这个网站,那就不用自己再考虑翻页动画的实现。当然后来发现完全可以使用CSS动画手动实现"翻页",通过三次贝塞尔曲线animation-timing-function: cubic-bezier(0.12, 1, 0.1, 1)
,在需要翻页的时候,使用动画,将下一页内容移入屏幕,将当前内容移除屏幕即可。另外,也可以使用requestAnimationFrame
使用类似的功能,可以参考我的另一篇文章requestAnimationFrame的使用。
其它
其它大大小小的功能,虽然实现就几行代码,但是也是挺麻烦的
- 横向翻页实现
首先是要让文本内容能够横向滚动,这个可以通过设置div的
column
属性以及overflow-y: hidden
实现,可以参考HTML横向滚动实现。文字排版的话,使用column
后容器会自动排列内容,效果也不错。起初是手动添加段落p
然后判断外层容器高度是否过大实现,但是这样问题很多,所以后来就放弃了。很好奇HTML是否提供了将一个div中的内容溢出到另一个div中这种功能。 - 复制
这个就很扯了,js没有直接的接口,当然你可以用其它的js库实现,但是一种最简单直白的方法就是:
设置一个看不见的
input
– 手动将待复制的内容设置为input
的内容 – 使用input.select()
函数选中 – 执行document.execCommand("copy", false)
- break-before
似乎只有
h
标签的break-before: column
会生效 - 手动触发动画
JavaScript没有提供触发动画的接口,需要手动设置以及清除动画属性。
触发动画: 设置元素的动画属性(
div.style.animation
),并且在动画结束后清除动画(style.animation = "none"
) - CSS中的calc函数
在设置
left, top
等属性时,可以使用calc
函数计算偏移量,比如left: calc(50% - 30px)
- 父元素
position: relative
, 子元素position: absolute
子元素按照父元素定位。如果不定义父元素的relative定位,子元素会根据整个网页定位
总结
绕了很多弯路,不过做出来后还是挺开心的,而且其它的书籍也能够处理一下放上来阅读。网站使用uWsgi
简单部署了一下,没什么可说的。代码可以看GitHub,如果文章内容不对,还望评论指出。