Twitter: raymondcamden


Address: Lafayette, LA, USA

Building an HTML5 Comic Book Reader

05-29-2012 11,034 views jQuery, JavaScript, HTML5 19 Comments

Edited on February 17, 2013: I was alerted by a reader that this code is broken now. To fix the bug I needed to make one code tweak (noted below) and update to the latest copy of zip.js.

Following up on my Sunday blog post on comics, I thought it would be fun to share a little experiment I built this weekend. Comic books are available in a compressed format typically called CBRs or CBZs. These aren't a special format, just simple compressed archives. CBRs are RAR files and CBZs are zips. While there doesn't appear to be good support for RAR files (I've only found a Java library to list the contents), the Zip format is much more widely used and easy to work with. In fact, you can find an excellent JavaScript implementation: zip.js I thought it might be fun to try using that to build my own web-based CBZ reader. Here's how I did it.

First, I added drag/drop support to my application so that users could simply drag in their local CBZ files. Instead of a div, I made the entire page a target for drop events:

Edit on February 17, 2013: Chrome recently changed something (or changed after I blogged) that now makes you listen for, and prevent, the dragover event. This is a very minor update:

The dropHandler needs to do a few things. First - it needs to figure out the type of drop. Don't forget that people can drag/drop blocks of text from other applications. What I want is to listen for files. Even better - I need to ensure that one file is dropped, not multiple. Here's the snippet for that logic.

Ok, now for the fun part. My application needs to try to decompress the zip file to the file system. In order to do that I am making use of the HTML5 File API. Earlier on I did a quick request for some temporary file storage - which is pretty simple:

Having the file system means I can extract the images out of the zip into the directory and refer to them later. We have access to the file from the drop event, so it is a simple matter of:

  • Pass the file data to zip.js
  • Extract the files
  • Save the files (again, this is a temporary file system)
  • Store a reference to them so I can display them to the user

Here is the function that handles all of that.

Once done - that leaves us with the simple job of providing basic interaction with the images. This is done via buttons that allow for navigation.

And that's it! Before I link to the demo, I'll warn you that this is not very tolerant of browsers that don't support everything required. Here are a few screen shots though to give you an idea of how it works.

First up - the application as it looks on loading.

Next - I drag a CBZ file over it...

And then it gets to work. Now - this part can be a bit slow. To be fair, I dragged a 35 megabyte file into the browser and it took about 40 seconds to parse. I think that's fairly decent for JavaScript.

I also provide UI feedback as the images are saved.

And then finally - the comic is readable. (Whether or not the story is any good is another question.)

Want to try it out? Hit the demo link below. Note that you may want to try with the latest Chrome and with a small comic. I've created a simple "comic" out of a zip of pictures that can be downloaded here.

19 Comments

  • Sergio Pedroza #
    Commented on 10-11-2012 at 1:30 PM
    Hey, this is really cool. I am a programmer at USC and was wondering if I can perhaps as you a couple questions in regards to the comic book reader. Is there anyway i can contact you via email. I would really like to add a similar feature to a project I am working on :)
  • Commented on 10-11-2012 at 1:33 PM
    You may absolutely email me. Use the Contact link on top.
  • Joe #
    Commented on 01-29-2013 at 2:15 PM
    When I drop the demo comic into the reader it just downloads it again... I'm using the most recent version of chrome in windows XP.
  • Commented on 01-29-2013 at 6:28 PM
    That sounds like the drag/drop handler isn't working. Can you try a simpler version of the code that just has that portion and see if it still works?
  • Commented on 03-24-2013 at 3:53 PM
    Raymond,

    I'm stuck on campus with my girlfriend, trying to read Amazing Spider-Man #232 on these locked down iMacs. I was surprised to find that the best web-based cbz reader I could find was your weekend project! However, since it was a weekend project, the code still lacks some features I would really love. Would you mind if I forked your code, and started adding some features? I would post all my code on GitHub and credit your blog post in the readme, or I could fork it from your GitHub account or even work on your branch if you would like to upload it. All up to you.

    Specifically, I was going to add fit-to-width, fit-to-height, two page spreads, and keyboard controls. Maybe I would work on adding a "library" feature later, for people to run their own private version.
  • Commented on 03-24-2013 at 7:16 PM
    That would be cool. Let me setup a GitHub repo tomorrow you can fork and contribute too.
  • Commented on 03-24-2013 at 11:47 PM
    Awesome!

    I've been working on it since my comment ( minus a long dinner ), and I already have fit to width / height working, key commands working, and I'm almost done with full spread!

    You can check it out at http://rkuykendall.com/uploads/ComicViewer/

    The key bindings are arrows ( or j/k ), v/h, and f.

    Looking forward to committing my code!
  • Commented on 03-27-2013 at 4:48 PM
    Hey Raymond, how is it going?
  • Commented on 03-27-2013 at 4:50 PM
    Doh! Been packed. :) Ok, time to get this into GitHub NOW!
  • Commented on 03-27-2013 at 4:56 PM
    Done. And thanks for reminding me: https://github.com/cfjedimaster/HTML5ComicBookRead...
  • Francisco Alonso #
    Commented on 09-09-2013 at 4:33 AM
    Hi!

    I really like your reader. I'm trying to build a comic reader for iOS using PhoneGap 2.9, just for learning purposes. do you think that's doable?. Maybe I could use some of this code??.

    Thanks!!
  • Commented on 09-09-2013 at 6:53 AM
    Afaik you can not use the FileSystem API in Mobile Safari. I just checked:

    http://caniuse.com/#feat=filesystem

    iOS7 is marked as unknown.
  • Commented on 09-09-2013 at 8:43 PM
    Just realized the link from my last comment is broken and I have long since finished my additions. Thanks again for adding a repo, Raymond.

    Comic reader:
    http://rkuykendall.com/webslinger/

    GitHub Respoitory:
    https://github.com/rkuykendall/HTML5ComicBookReade...

    Blog post:
    http://rkuykendall.com/articles/web-slinger-comic-...
  • Kevin #
    Commented on 09-09-2013 at 10:29 PM
    Just out of curiosity, is there any way to implement .cbr? The majority of my comics for some reason are in .cbr rather than .cbz. Or are there any converters out there?

    Otherwise loving the simplicity of it over all.
  • Commented on 09-10-2013 at 2:04 PM
    @Kevin: I did some research, and apparently RAR isn't a standard, so there aren't any good OS libraries out there. The best I found when I looked last time (admittedly a while ago) was a Java library that could read a list of entries from the RAR but not actually extract anything.
  • Francisco Alonso #
    Commented on 09-10-2013 at 2:14 PM
    Thanks for the answer! I'll try with xCode then.
  • Commented on 07-11-2014 at 5:13 PM
    My own comic book reader in the browser: https://code.google.com/p/kthoom/

    Binary tools for JS library you might find interesting: https://code.google.com/p/bitjs/
  • Commented on 07-12-2014 at 8:42 AM
    Oh nice, you got CBR support working? Mind if I borrow that? :)
  • Commented on 07-12-2014 at 10:24 AM
    It's an open source library, so of course not :)

Post Reply

Please refrain from posting large blocks of code as a comment. Use Pastebin or Gists instead. Text wrapped in asterisks (*) will be bold and text wrapped in underscores (_) will be italicized.

Leave this field empty