loads of changes, methods are now mostly assigned to the prototype (for better or worse), the constructer accepts an array of options, in fitWidth mode the comic will scale on window resize

This commit is contained in:
Bala Clark 2010-07-07 16:57:47 +01:00
parent f3ec23e060
commit 2f1739743f

View file

@ -1,5 +1,5 @@
var book; var book
window.onload = function() { window.onload = function() {
@ -13,13 +13,30 @@ window.onload = function() {
"http://dev.justforcomics.com/get/image/?f=comics/extracted/oni_whiteout_melt_1/06.jpg" "http://dev.justforcomics.com/get/image/?f=comics/extracted/oni_whiteout_melt_1/06.jpg"
]; ];
book = new ComicBook(); var options = {
book.draw("comic", pages); displayMode: "double",
zoomMode: "fitWidth"
}
book = new ComicBook("comic", pages, options);
book.draw();
} }
function ComicBook() { window.onresize = function() {
book.draw();
}
function ComicBook(id, srcs, opts) {
this.id = id;
this.srcs = srcs;
var defaults = {
displayMode: "double", // single / double
zoomMode: "fitWidth" // manual / fitWidth
}
var options = merge(defaults, opts);
var srcs = [];
var pages = []; var pages = [];
var canvas; var canvas;
var context; var context;
@ -29,25 +46,24 @@ function ComicBook() {
var loaded = 0; var loaded = 0;
var scale = 1; var scale = 1;
var displayMode = "double" // single / double
var zoomMode = "fitWidth"; // manual / fitWidth
/* /*
* @param {String} id The canvas ID to draw the comic on. * @param {String} id The canvas ID to draw the comic on.
* @param {Object} srcs An array of all the comic page srcs, in order * @param {Object} srcs An array of all the comic page srcs, in order
* @see #preload * @see #preload
*/ */
this.draw = function(id, srcs) { ComicBook.prototype.draw = function() {
// setup canvas // setup canvas
canvas = document.getElementById(id); canvas = document.getElementById(this.id);
context = canvas.getContext("2d"); context = canvas.getContext("2d");
// preload images // preload images if needed
preload(srcs); if (pages.length != this.srcs.length) this.preload(this.srcs);
else this.drawPage();
// add page controls // add page controls
canvas.addEventListener("click", navigation, false); canvas.addEventListener("click", ComicBook.prototype.navigation, false);
} }
/* /*
@ -55,10 +71,10 @@ function ComicBook() {
* *
* @param new_scale {Number} Scale the canvas to this ratio * @param new_scale {Number} Scale the canvas to this ratio
*/ */
this.zoom = function(new_scale) { ComicBook.prototype.zoom = function(new_scale) {
zoomMode = "manual"; options.zoomMode = "manual";
scale = new_scale; scale = new_scale;
drawPage(); this.drawPage();
} }
/** /**
@ -67,7 +83,7 @@ function ComicBook() {
* @param srcs {Object} srcs * @param srcs {Object} srcs
* @see #drawPage * @see #drawPage
*/ */
function preload(srcs) { ComicBook.prototype.preload = function(srcs) {
if (srcs.length < buffer) buffer = srcs.length; // don't get stuck if the buffer level is higher than the number of pages if (srcs.length < buffer) buffer = srcs.length; // don't get stuck if the buffer level is higher than the number of pages
@ -78,9 +94,8 @@ function ComicBook() {
page.src = src; page.src = src;
page.onload = function() { page.onload = function() {
pages[i] = this;loaded++;
pages[i] = this; loaded++; if (loaded == buffer) ComicBook.prototype.drawPage();
if (loaded == buffer) drawPage();
} }
}); });
} }
@ -91,7 +106,7 @@ function ComicBook() {
* TODO: break this down into drawSinglePage() & drawDoublePage() * TODO: break this down into drawSinglePage() & drawDoublePage()
* TODO: if the current browser doesn't have canvas support, use img tags * TODO: if the current browser doesn't have canvas support, use img tags
*/ */
function drawPage() { ComicBook.prototype.drawPage = function() {
var zoom_scale; var zoom_scale;
var page = pages[pointer]; var page = pages[pointer];
@ -100,25 +115,21 @@ function ComicBook() {
if (typeof page != "object") throw "invalid page"; if (typeof page != "object") throw "invalid page";
var width = page.width; var width = page.width;
var height = page.height;
if (displayMode == "double") { if (options.displayMode == "double") {
// for double page spreads, factor in the width of both pages, set the height to the tallest page // for double page spreads, factor in the width of both pages
if (typeof page2 == "object") { if (typeof page2 == "object") width += page2.width;
width += page2.width;
if (page2.height > page.height) height = page2.height;
}
// if this is the last page and there is no page2, still keep the canvas wide // if this is the last page and there is no page2, still keep the canvas wide
else width += width; else width += width;
} }
// update the page scale if a non manual mode has been chosen // update the page scale if a non manual mode has been chosen
switch(zoomMode) { switch(options.zoomMode) {
case "manual": case "manual":
zoom_scale = (displayMode == "double") ? scale * 2 : scale; zoom_scale = (options.displayMode == "double") ? scale * 2 : scale;
break; break;
case "fitWidth": case "fitWidth":
@ -127,14 +138,14 @@ function ComicBook() {
: window.innerWidth / width; // scale down if the window is narrower than the page : window.innerWidth / width; // scale down if the window is narrower than the page
break; break;
default: throw "invalid zoomMode"; default:throw "invalid zoomMode";
} }
var canvas_width = page.width * zoom_scale; var canvas_width = page.width * zoom_scale;
var canvas_height = page.height * zoom_scale; var canvas_height = page.height * zoom_scale;
var page_width = (zoomMode == "manual") ? page.width * scale : canvas_width; var page_width = (options.zoomMode == "manual") ? page.width * scale : canvas_width;
var page_height = (zoomMode == "manual") ? page.height * scale : canvas_height; var page_height = (options.zoomMode == "manual") ? page.height * scale : canvas_height;
// make sure the canvas is always at least full screen, even if the page is more narrow than the screen // make sure the canvas is always at least full screen, even if the page is more narrow than the screen
canvas.width = (canvas_width < window.innerWidth) ? window.innerWidth : canvas_width; canvas.width = (canvas_width < window.innerWidth) ? window.innerWidth : canvas_width;
@ -142,7 +153,7 @@ function ComicBook() {
// draw the page(s) // draw the page(s)
context.drawImage(page, 0, 0, page_width, page_height); context.drawImage(page, 0, 0, page_width, page_height);
if (displayMode == "double" && typeof page2 == "object") context.drawImage(page2, page_width, 0, page_width, page_height); if (options.displayMode == "double" && typeof page2 == "object") context.drawImage(page2, page_width, 0, page_width, page_height);
} }
@ -151,10 +162,10 @@ function ComicBook() {
* *
* @see #drawPage * @see #drawPage
*/ */
function drawNextPage() { ComicBook.prototype.drawNextPage = function() {
if (pointer + 1 < pages.length) { if (pointer + 1 < pages.length) {
pointer++; pointer++;
drawPage(); this.drawPage();
} }
} }
@ -163,21 +174,21 @@ function ComicBook() {
* *
* @see #drawPage * @see #drawPage
*/ */
function drawPrevPage() { ComicBook.prototype.drawPrevPage = function() {
if (pointer > 0) { if (pointer > 0) {
pointer--; pointer--;
drawPage(); this.drawPage();
} }
} }
function navigation(e) { ComicBook.prototype.navigation = function(e) {
switch (e.type) { switch (e.type) {
case "click": case "click":
switch (getCursorPosition(e)) { switch (getCursorPosition(e)) {
case "left": drawPrevPage(); break; case "left": ComicBook.prototype.drawPrevPage(); break;
case "right": drawNextPage(); break; case "right": ComicBook.prototype.drawNextPage(); break;
} }
break; break;
@ -206,4 +217,23 @@ function ComicBook() {
// check if the user clicked on the left or right side // check if the user clicked on the left or right side
return (x <= canvas.width / 2) ? 'left' : 'right'; return (x <= canvas.width / 2) ? 'left' : 'right';
} }
/**
* Merge two arrays. Any properties in b will replace the same properties in
* a. New properties from b will be added to a.
*
* @param a {Object}
* @param b {Object}
*/
function merge(a, b) {
if (typeof b == "undefined") b = {};
for (prop in a) {
if (prop in b) continue;
b[prop] = a[prop];
}
return b;
}
} }