mirror of
https://github.com/torappinfo/uweb.git
synced 2024-08-14 23:54:59 +00:00
352 lines
9.6 KiB
HTML
352 lines
9.6 KiB
HTML
<!DOCTYPE html>
|
||
<html>
|
||
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport"
|
||
content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no">
|
||
<title>EPUB</title>
|
||
<script src="https://cdn.bootcdn.net/ajax/libs/jszip/3.1.5/jszip.min.js"></script>
|
||
<script src="https://cdn.jsdelivr.net/npm/epubjs@0.3.88/dist/epub.min.js"></script>
|
||
<script>
|
||
document.addEventListener('DOMContentLoaded', () => {
|
||
const html = document.querySelector('html')
|
||
let fontSize = window.innerWidth / 10
|
||
fontSize = fontSize > 50 ? 50 : fontSize
|
||
html.style.fontSize = fontSize + 'px'
|
||
})
|
||
</script>
|
||
<style>
|
||
* {
|
||
padding: 0;
|
||
margin: 0;
|
||
}
|
||
|
||
.mask {
|
||
position: absolute;
|
||
display: flex;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.meun {
|
||
display: flex;
|
||
height: 1rem;
|
||
align-items: center;
|
||
}
|
||
|
||
#toc {
|
||
flex: 1;
|
||
z-index: 100;
|
||
font-size: .3rem;
|
||
padding-left: .4rem;
|
||
color: #333;
|
||
}
|
||
|
||
#page {
|
||
z-index: 100;
|
||
font-size: .3rem;
|
||
color: #333;
|
||
padding-right: 0.4rem;
|
||
text-align: right;
|
||
flex: 0 0 .5rem;
|
||
}
|
||
|
||
#load {
|
||
z-index: 100;
|
||
font-size: .3rem;
|
||
color: #333;
|
||
padding-right: 0.4rem;
|
||
text-align: right;
|
||
flex: 0 0 .5rem;
|
||
}
|
||
|
||
#toc-content {
|
||
position: absolute;
|
||
display: flex;
|
||
top: 0;
|
||
right: 0;
|
||
z-index: 102;
|
||
min-width: auto;
|
||
max-width: 80%;
|
||
height: 100%;
|
||
background: white;
|
||
flex-direction: column
|
||
}
|
||
|
||
#toc-mask {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
z-index: 101;
|
||
width: 100%;
|
||
height: 100%;
|
||
background: rgba(51, 51, 51, .8);
|
||
}
|
||
|
||
.intro {
|
||
width: 100%;
|
||
height: 2.4rem;
|
||
padding: .2rem .4rem;
|
||
box-sizing: border-box;
|
||
height: 3rem;
|
||
display: flex;
|
||
border-bottom: .1rem solid #f4f4f4;
|
||
}
|
||
|
||
.txt {
|
||
display: flex;
|
||
flex: 1;
|
||
align-items: center;
|
||
padding: 0 .2rem;
|
||
font-size: .3rem;
|
||
}
|
||
|
||
#content {
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.item {
|
||
padding: .2rem .4rem;
|
||
border-bottom: .07rem solid #f4f4f4;
|
||
font-size: .4rem;
|
||
color: #333;
|
||
}
|
||
|
||
#open {
|
||
display: flex;
|
||
flex: 1;
|
||
z-index: 100;
|
||
font-size: .4rem;
|
||
color: #333;
|
||
align-items: flex-end;
|
||
justify-content: center;
|
||
|
||
}
|
||
|
||
#open span {
|
||
padding: .3rem .3rem;
|
||
border: .05rem solid #333;
|
||
border-radius: .2rem;
|
||
}
|
||
|
||
.read {
|
||
display: flex;
|
||
flex: 1 1 auto;
|
||
}
|
||
|
||
#prev {
|
||
flex: 0 0 2rem;
|
||
z-index: 100;
|
||
}
|
||
|
||
#viewer {
|
||
flex: 1;
|
||
}
|
||
|
||
#next {
|
||
flex: 0 0 2rem;
|
||
z-index: 100;
|
||
}
|
||
|
||
.save {
|
||
display: flex;
|
||
}
|
||
|
||
.box {
|
||
padding: .2rem .2rem;
|
||
justify-content: center;
|
||
border-bottom: .1rem solid #f4f4f4;
|
||
}
|
||
|
||
.jump {
|
||
display: flex;
|
||
height: 1rem;
|
||
border-bottom: .1rem solid #f4f4f4;
|
||
}
|
||
|
||
.jump input {
|
||
flex: 1;
|
||
padding: .1rem .1rem;
|
||
margin: .2rem .2rem .2rem .4rem;
|
||
outline: none;
|
||
font-size: .3rem;
|
||
}
|
||
|
||
.jump span {
|
||
flex: 0 0 1rem;
|
||
}
|
||
</style>
|
||
</head>
|
||
|
||
<body>
|
||
<div id="ebook">
|
||
<div class="mask">
|
||
<div id="open">
|
||
<span
|
||
onclick="document.getElementById('input').click();document.getElementById('open').style.display = 'none'">选择本地书籍</span>
|
||
<input type="file" id="input" style="display: none;">
|
||
</div>
|
||
<div class="read">
|
||
<div id="prev" onclick="rendition.prev()"></div>
|
||
<div id="viewer"></div>
|
||
<div id="next" onclick="rendition.next()"></div>
|
||
</div>
|
||
<div class="meun">
|
||
<div id="toc" onclick="showhide()"></div>
|
||
<div id="page"></div>
|
||
<div id="load"></div>
|
||
</div>
|
||
<div id="toc-mask" style="display: none;" onclick="showhide()"></div>
|
||
<div id="toc-content" style="display: none;">
|
||
<div class="intro">
|
||
<img id="cover">
|
||
<div style="display: flex;flex: 1;flex-direction: column;overflow-y: auto;">
|
||
<div id="title" class="txt"></div>
|
||
<div id="author" class="txt"></div>
|
||
<div id="publisher" class="txt"></div>
|
||
<div id="pubdate" class="txt"></div>
|
||
</div>
|
||
</div>
|
||
<div class="save">
|
||
<div class="txt box" onclick="save()">存档</div>
|
||
<div class="txt box" onclick="get()">读档</div>
|
||
<div class="txt box" onclick="del()">删档</div>
|
||
</div>
|
||
<div class="jump">
|
||
<input id="jump" type="number" placeholder="0-1之间的数字,如0.25"
|
||
oninput="if(value>1)value=1;if(value<0)value=0">
|
||
<span class="txt" onclick="jump()">跳转</span>
|
||
</div>
|
||
<div id="content"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<script>
|
||
let url = location.search.substring(3);
|
||
if (url !== "") {
|
||
var book = ePub(url);
|
||
document.getElementById("open").style.display = "none"
|
||
} else {
|
||
var book = ePub();
|
||
var inputElement = document.getElementById("input");
|
||
inputElement.addEventListener('change', function (e) {
|
||
var file = e.target.files[0];
|
||
if (window.FileReader) {
|
||
var reader = new FileReader();
|
||
reader.onload = openBook;
|
||
reader.readAsArrayBuffer(file);
|
||
}
|
||
});
|
||
function openBook(e) {
|
||
var bookData = e.target.result;
|
||
book.open(bookData, "binary");
|
||
}
|
||
}
|
||
//渲染
|
||
var rendition = book.renderTo("ebook", {
|
||
with: window.innerWidth,
|
||
height: window.innerHeight - 20
|
||
});
|
||
rendition.display();
|
||
|
||
book.ready
|
||
.then(() => {
|
||
var local = localStorage.getItem(book.key() + '-locations');
|
||
if (local) {
|
||
return book.locations.load(local);
|
||
} else {
|
||
return book.locations.generate();
|
||
}
|
||
})
|
||
.then(locations => {
|
||
localStorage.setItem(book.key() + '-locations', book.locations.save());
|
||
})
|
||
|
||
// 目录
|
||
book.loaded.navigation.then(toc => {
|
||
var read = localStorage.getItem(book.key() + '-read');
|
||
if (read) {
|
||
rendition.display(read);
|
||
}
|
||
var $content = document.getElementById("content");
|
||
toc.forEach(item => {
|
||
var div = document.createElement("div");
|
||
div.className = "item";
|
||
div.textContent = item.label;
|
||
div.addEventListener("click", () => {
|
||
rendition.display(item.href);
|
||
showhide()
|
||
});
|
||
$content.appendChild(div)
|
||
})
|
||
})
|
||
//简介
|
||
book.loaded.metadata.then(meta => {
|
||
var $title = document.getElementById("title");
|
||
var $author = document.getElementById("author");
|
||
var $cover = document.getElementById("cover");
|
||
var $publisher = document.getElementById("publisher");
|
||
var $pubdate = document.getElementById("pubdate");
|
||
$title.textContent = `书名:${meta.title}`;
|
||
$author.textContent = `作者:${meta.creator}`;
|
||
$publisher.textContent = `出版社:${meta.publisher}`;
|
||
$pubdate.textContent = `时间:${meta.pubdate}`;
|
||
if (book.archive) {
|
||
book.archive.createUrl(book.cover)
|
||
.then(url => {
|
||
$cover.src = url;
|
||
})
|
||
} else {
|
||
$cover.src = book.cover;
|
||
}
|
||
});
|
||
//进度显示
|
||
rendition.on('relocated', location => {
|
||
var percent = book.locations.percentageFromCfi(location.start.cfi);
|
||
var $page = document.getElementById("page");
|
||
var $load = document.getElementById("load");
|
||
$page.textContent = location.end.displayed.page + '/' + location.end.displayed.total;
|
||
$load.textContent = Math.fround(percent * 100).toFixed(1) + '%';
|
||
})
|
||
//章节名显示
|
||
rendition.on("rendered", section => {
|
||
var $toc = document.getElementById("toc");
|
||
$toc.textContent = "目录";
|
||
$toc.textContent = book.navigation.get(section.href).label;
|
||
})
|
||
function showhide() {
|
||
var $toc_content = document.getElementById("toc-content")
|
||
var $mask = document.getElementById("toc-mask")
|
||
if ($toc_content.style.display == "none") {
|
||
$toc_content.style.display = ""
|
||
$mask.style.display = ""
|
||
} else {
|
||
$toc_content.style.display = "none"
|
||
$mask.style.display = "none"
|
||
}
|
||
}
|
||
function jump() {
|
||
$jump = document.getElementById("jump").value;
|
||
rendition.display(book.locations.cfiFromPercentage($jump));
|
||
showhide();
|
||
document.getElementById("jump").value = "";
|
||
}
|
||
function save() {
|
||
localStorage.setItem(book.key() + '-read', rendition.currentLocation().start.cfi)
|
||
showhide()
|
||
}
|
||
function get() {
|
||
rendition.display(localStorage.getItem(book.key() + '-read'));
|
||
showhide()
|
||
}
|
||
function del() {
|
||
localStorage.removeItem(book.key() + '-read');
|
||
showhide()
|
||
}
|
||
</script>
|
||
</body>
|
||
|
||
</html>
|