I'm using EPUB.js and Vue to render an Epub. I want to display the cover images of several epub books so users can click one to then see the whole book.
There's no documentation on how to do this, but there are several methods that indicate that this should be possible.
First off, there's Book.coverUrl() method.
Note that I'm setting an img
src
property equal to bookCoverSrc
in the Vue template. Setting this.bookCoverSrc
will automatically update the src
of the img
tag and cause an image to display (if the src
is valid / resolves).
this.book = new Epub(this.epubUrl, {});
this.book.ready.then(() => {
this.book.coverUrl().then((url) => {
this.bookCoverSrc = url;
});
})
The above doesn't work. url
is undefined
.
Weirdly, there appears to be a cover
property directly on book
. So, I try:
this.book = new Epub(this.epubUrl, {});
this.book.ready.then(() => {
this.coverSrc = this.book.cover;
});
this.book.cover
resolves to OEBPS/@public@vhost@g@gutenberg@html@files@49010@49010-h@images@cover.jpg
, so at least locally when I set it to a src
results in a request to http://localhost:8080/OEBPS/@public@vhost@g@gutenberg@html@files@49010@49010-h@images@cover.jpg
, which 200s but returns no content. Probably a quirk of webpack-dev-server to 200 on that, but if I page through sources in Chrome dev tools I also don't see any indicate that such a URL should resolve.
So, docs not helping. I googled and found this github question from 2015. Their code is like
$("#cover").attr("src", Book.store.urlCache[Book.cover]);
Interesting, nothing in the docks about Book.store.urlCache. As expected, urlCache
is undefined
, though book.store
exists. I don't see anything on there that can help me display a cover image though.
Using epub.js, how can I display a cover image of an Epub file? Note that simply rendering the first "page" of the Epub file (which is usually the cover image) doesn't solve my problem, as I'd like to list a couple epub files' cover images.
Note also that I believe the epub files I'm using do have cover images. The files are Aesop's Fables and Irish Wonders.
EDIT: It's possible I need to use Book.load on the url provided by book.cover
first. I did so and tried to console.log it, but it's a massive blog of weirdly encoded text that looks something like:
����
So I think it's an image straight up, and I need to find a way to get that onto the Document somehow?
EDIT2: that big blobby blob is type: string, and I can't atob()
or btoa()
it.
EDIT3: Just fetch
ing the url provided by this.book.cover
returns my index.html, default behavior for webpack-dev-server when it doesn't know what else to do.
EDIT4: Below is the code for book.coverUrl
from epub.js
key: "coverUrl",
value: function coverUrl() {
var _this9 = this;
var retrieved = this.loaded.cover.then(function (url) {
if (_this9.archived) {
// return this.archive.createUrl(this.cover);
return _this9.resources.get(_this9.cover);
} else {
return _this9.cover;
}
});
return retrieved;
}
If I use this.archive.createUrl(this.cover)
instead of this.resources.get
, I actually get a functional URL, that looks like blob:http://localhost:8080/9a3447b7-5cc8-4cfd-8608-d963910cb5f5
. I'll try getting that out into src
and see what happens.
The reason this was happening to me was because the functioning line of code in the coverUrl
function was commented out in the source library epub.js, and a non-functioning line of code was written instead.
So, I had to copy down the entire library, uncomment the good code and delete the bad. Now the function works as it should.
To do so, clone down the entire epub.js project. Copy over the dependencies in that project's package.json
to your own. Then, take the src
, lib
, and libs
folders and copy them somewhere into your project. Find a way to disable eslint
for the location you put these folders into because the project uses TAB
characters for spacing which caused my terminal to hang due to ESLINT exploding.
npm install
so you have your and epub.js
dependencies in your node_modules
.
Open book.js
. Uncomment line 661 which looks like
return this.archive.createUrl(this.cover);
and comment out line 662 which looks like
// return this.resources.get(this.cover);
Now you can display an image by setting an img
tag's src
attribute to the URL returned by book.coverUrl()
.
this.book = new Epub(this.epubUrl, {});
this.book.ready.then(() => {
this.book.coverUrl().then((url) => {
this.bookCoverSrc = url;
});
})