diff --git a/examples/examples.css b/examples/examples.css index 233c922..e1969d1 100644 --- a/examples/examples.css +++ b/examples/examples.css @@ -61,11 +61,11 @@ body { } #prev { - left: 40px; + left: 0; } #next { - right: 40px; + right: 0; } #toc { @@ -87,6 +87,14 @@ body { box-shadow: -2px 0 15px rgba(0, 0, 0, 1); content: ""; } + + #prev { + left: 40px; + } + + #next { + right: 40px; + } } .arrow { diff --git a/examples/hypothesis-spreads.html b/examples/hypothesis-spreads.html index 66a63eb..c8730e7 100644 --- a/examples/hypothesis-spreads.html +++ b/examples/hypothesis-spreads.html @@ -8,15 +8,6 @@ - - - -
@@ -218,7 +36,7 @@ menu
- g + @@ -236,191 +54,5 @@
- - diff --git a/examples/hypothesis.css b/examples/hypothesis.css new file mode 100644 index 0000000..4a53bed --- /dev/null +++ b/examples/hypothesis.css @@ -0,0 +1,329 @@ +body { + margin: 0; + background: #fafafa; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + color: #333; +} + +svg { + display: block; +} + +.close-x { + stroke: #cccddd; + fill: transparent; + stroke-linecap: round; + stroke-width: 5; +} + +.close-x:hover { + stroke: #fff; +} + +#opener { + position: absolute; + top: 0; + left: 0; + padding: 10px; + stroke: #E2E2E2; + fill: #E2E2E2; + +} + +#opener:hover { + stroke: #777; + fill: #777; +} + +#navigation { + width: 400px; + position: fixed; + overflow: auto; + top: 0; + left: -425px; + + background: #ECECEC; + min-height: 100%; + height: 100%; + height: 100vh; + + overflow: scroll; + -webkit-overflow-scrolling: touch; + padding: 9px; + padding-top: 10px; + + transition: left .2s ease-out; + box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23); +} + +#navigation.open { + left: 0; +} + +#navigation.fixed { + position: fixed; +} + +#navigation h1 { + width: 200px; + font-size: 16px; + font-weight: normal; + color: #777; + margin-bottom: 10px; +} + +#navigation h2 { + font-size: 14px; + font-weight: normal; + color: #B0B0B0; + margin-bottom: 20px; +} + +#navigation ul { + padding-left: 28px; + margin-left: 0; +} + +#navigation ul li { + list-style: decimal; + margin-bottom: 10px; + color: #585858; + font-size: 12px; + padding-left: 0; + margin-left: 0; +} + +#navigation ul li a { + color: #585858; + text-decoration: none; +} + +#navigation ul li a:hover { + color: #585858; + text-decoration: underline; +} + +#navigation ul li a.active { + color: #000; + font-weight: 400; +} + +#navigation #author { + text-align: center; +} + +#cover { + display: inline; +} + +#main { + margin-top: 60px; +} + +#pagination { + text-align: center; + margin: 20px; + /*padding: 0 50px;*/ +} + +.arrow:hover { + color: #777; +} + +.arrow:active { + color: #000; +} + +.arrow .material-icons { + font-size: 64px; +} + +#prev { + float: left; +} + +#next { + float: right; +} + +#toc { + display: block; + margin: 10px auto; +} + +#hypothesis-custom { + overflow: hidden; + /*position: absolute;*/ + right: 0; + /*top: 0;*/ + height: 100%; + width: 200px; + /*z-index: -2;*/ +} + +#hypothesis-custom iframe { + position: absolute; + width: 100%; + height: 100%; +} + +#navigation #cover { + display: block; + margin: 24px auto; +} + +#closer { + position: absolute; + padding: 12px; + left: 0; + top: 0; + color: #333; + cursor: pointer; +} + +#closer .material-icons { + color: #333; +} + +#opener { + position: absolute; + left: 0; + top: 0; + cursor: pointer; +} + +#hiddenTitle { + display: none; +} + +#title { + width: 900px; + min-height: 18px; + margin: 10px auto; + text-align: center; + font-size: 16px; + color: #E2E2E2; + font-weight: 400; +} + +#title:hover { + color: #777; +} + +#prev { + left: 0; +} + +#next { + right: 0; +} + +#toc { + display: block; + margin: 10px auto; +} + +@media (min-width: 1000px) { + #viewer.spreads:after { + position: absolute; + width: 1px; + border-right: 1px #000 solid; + height: 90%; + z-index: 1; + left: 50%; + margin-left: -1px; + top: 5%; + opacity: .15; + box-shadow: -2px 0 15px rgba(0, 0, 0, 1); + content: ""; + } + + #prev { + left: 40px; + } + + #next { + right: 40px; + } +} + +#viewer.spreads { + width: 84vw; + height: 80vh; + box-shadow: 0 0 4px #ccc; + border-radius: 5px; + padding: 0; + position: relative; + margin: 10vh auto; + background: white; + top: 0; +} + +.arrow { + position: fixed; + top: 50%; + margin-top: -32px; + font-size: 64px; + color: #E2E2E2; + font-family: arial, sans-serif; + font-weight: bold; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + text-decoration: none; +} + +.navlink { + margin: 14px; + display: block; + text-align: center; + text-decoration: none; + color: #ccc; +} + +.arrow:hover, .navlink:hover { + color: #777; +} + +.arrow:active, .navlink:hover { + color: #000; +} + +#book-wrapper { + width: 480px; + height: 640px; + overflow: hidden; + border: 1px solid #ccc; + margin: 28px auto; + background: #fff; + border-radius: 0 5px 5px 0; + position: absolute; +} + +#book-viewer { + width: 480px; + height: 660px; + margin: -30px auto; + -moz-box-shadow: inset 10px 0 20px rgba(0,0,0,.1); + -webkit-box-shadow: inset 10px 0 20px rgba(0,0,0,.1); + box-shadow: inset 10px 0 20px rgba(0,0,0,.1); +} + +#book-viewer iframe { + padding: 40px 40px; +} + +#controls { + position: absolute; + bottom: 16px; + left: 50%; + width: 400px; + margin-left: -200px; + text-align: center; + display: none; +} + +#controls > input[type=range] { + width: 400px; +} diff --git a/examples/hypothesis.js b/examples/hypothesis.js new file mode 100644 index 0000000..d638ecb --- /dev/null +++ b/examples/hypothesis.js @@ -0,0 +1,191 @@ +(function() { + + function start() { + var params = URLSearchParams && new URLSearchParams(document.location.search.substring(1)); + var url = params && params.get("url") && decodeURIComponent(params.get("url")); + + // Load the opf + var book = ePub(url || window.location.protocol + "//s3.amazonaws.com/epubjs.org/books/moby-dick-hypothesis-demo.epub"); + var rendition = book.renderTo("viewer", { + ignoreClass: "annotator-hl", + width: "100%", + height: "100%" + }); + + // var hash = window.location.hash.slice(2); + var loc = window.location.href.indexOf("?loc="); + if (loc > -1) { + var href = window.location.href.slice(loc + 5); + var hash = decodeURIComponent(href); + } + + rendition.display(hash || undefined); + + + var next = document.getElementById("next"); + next.addEventListener("click", function(e){ + rendition.next(); + e.preventDefault(); + }, false); + + var prev = document.getElementById("prev"); + prev.addEventListener("click", function(e){ + rendition.prev(); + e.preventDefault(); + }, false); + + var nav = document.getElementById("navigation"); + var opener = document.getElementById("opener"); + opener.addEventListener("click", function(e){ + nav.classList.add("open"); + }, false); + + var closer = document.getElementById("closer"); + closer.addEventListener("click", function(e){ + nav.classList.remove("open"); + }, false); + + // Hidden + var hiddenTitle = document.getElementById("hiddenTitle"); + + rendition.on("rendered", function(section){ + var current = book.navigation && book.navigation.get(section.href); + + if (current) { + document.title = current.label; + } + + // TODO: this is needed to trigger the hypothesis client + // to inject into the iframe + requestAnimationFrame(function () { + hiddenTitle.textContent = section.href; + }) + + var old = document.querySelectorAll('.active'); + Array.prototype.slice.call(old, 0).forEach(function (link) { + link.classList.remove("active"); + }) + + var active = document.querySelector('a[href="'+section.href+'"]'); + if (active) { + active.classList.add("active"); + } + // Add CFI fragment to the history + history.pushState({}, '', "?loc=" + encodeURIComponent(section.href)); + // window.location.hash = "#/"+section.href + }); + + var keyListener = function(e){ + + // Left Key + if ((e.keyCode || e.which) == 37) { + rendition.prev(); + } + + // Right Key + if ((e.keyCode || e.which) == 39) { + rendition.next(); + } + + }; + + rendition.on("keyup", keyListener); + document.addEventListener("keyup", keyListener, false); + + book.loaded.navigation.then(function(toc){ + var $nav = document.getElementById("toc"), + docfrag = document.createDocumentFragment(); + + toc.forEach(function(chapter, index) { + var item = document.createElement("li"); + var link = document.createElement("a"); + link.id = "chap-" + chapter.id; + link.textContent = chapter.label; + link.href = chapter.href; + item.appendChild(link); + docfrag.appendChild(item); + + link.onclick = function(){ + var url = link.getAttribute("href"); + console.log(url) + rendition.display(url); + return false; + }; + + }); + + $nav.appendChild(docfrag); + + + }); + + book.loaded.metadata.then(function(meta){ + var $title = document.getElementById("title"); + var $author = document.getElementById("author"); + var $cover = document.getElementById("cover"); + var $nav = document.getElementById('navigation'); + + $title.textContent = meta.title; + $author.textContent = meta.creator; + if (book.archive) { + book.archive.createUrl(book.cover) + .then(function (url) { + $cover.src = url; + }) + } else { + $cover.src = book.cover; + } + + // if ($nav.offsetHeight + 60 < window.innerHeight) { + // $nav.classList.add("fixed"); + // } + + }); + + var tm; + function checkForAnnotator(cb, w) { + if (!w) { + w = window; + } + tm = setTimeout(function () { + if (w && w.annotator) { + clearTimeout(tm); + cb(); + } else { + checkForAnnotator(cb, w); + } + }, 100); + } + + book.rendition.hooks.content.register(function(contents, view) { + checkForAnnotator(function () { + + var annotator = contents.window.annotator; + + contents.window.addEventListener('scrolltorange', function (e) { + var range = e.detail; + var cfi = new ePub.CFI(range, contents.cfiBase).toString(); + if (cfi) { + book.rendition.display(cfi); + } + e.preventDefault(); + }); + + + annotator.on("highlightClick", function (annotation) { + console.log(annotation); + window.annotator.show(); + }) + + annotator.on("beforeAnnotationCreated", function (annotation) { + console.log(annotation); + window.annotator.show(); + }) + + }, contents.window); + + }); + } + + document.addEventListener('DOMContentLoaded', start, false); +})();