diff --git a/scripts.js b/scripts.js index ff3739e..661185a 100644 --- a/scripts.js +++ b/scripts.js @@ -1,5 +1,5 @@ -var book; +var book 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" ]; - book = new ComicBook(); - book.draw("comic", pages); + var options = { + 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 canvas; var context; @@ -29,25 +46,24 @@ function ComicBook() { var loaded = 0; 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 {Object} srcs An array of all the comic page srcs, in order * @see #preload */ - this.draw = function(id, srcs) { + ComicBook.prototype.draw = function() { // setup canvas - canvas = document.getElementById(id); + canvas = document.getElementById(this.id); context = canvas.getContext("2d"); - // preload images - preload(srcs); - + // preload images if needed + if (pages.length != this.srcs.length) this.preload(this.srcs); + else this.drawPage(); + // 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 */ - this.zoom = function(new_scale) { - zoomMode = "manual"; + ComicBook.prototype.zoom = function(new_scale) { + options.zoomMode = "manual"; scale = new_scale; - drawPage(); + this.drawPage(); } /** @@ -67,7 +83,7 @@ function ComicBook() { * @param srcs {Object} srcs * @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 @@ -78,9 +94,8 @@ function ComicBook() { page.src = src; page.onload = function() { - - pages[i] = this; loaded++; - if (loaded == buffer) drawPage(); + pages[i] = this;loaded++; + if (loaded == buffer) ComicBook.prototype.drawPage(); } }); } @@ -91,34 +106,30 @@ function ComicBook() { * TODO: break this down into drawSinglePage() & drawDoublePage() * TODO: if the current browser doesn't have canvas support, use img tags */ - function drawPage() { - + ComicBook.prototype.drawPage = function() { + var zoom_scale; var page = pages[pointer]; var page2 = pages[pointer + 1]; - + if (typeof page != "object") throw "invalid page"; 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 - if (typeof page2 == "object") { - width += page2.width; - if (page2.height > page.height) height = page2.height; - } + // for double page spreads, factor in the width of both pages + if (typeof page2 == "object") width += page2.width; // if this is the last page and there is no page2, still keep the canvas wide else width += width; } - + // update the page scale if a non manual mode has been chosen - switch(zoomMode) { + switch(options.zoomMode) { case "manual": - zoom_scale = (displayMode == "double") ? scale * 2 : scale; + zoom_scale = (options.displayMode == "double") ? scale * 2 : scale; break; case "fitWidth": @@ -127,22 +138,22 @@ function ComicBook() { : window.innerWidth / width; // scale down if the window is narrower than the page break; - default: throw "invalid zoomMode"; + default:throw "invalid zoomMode"; } var canvas_width = page.width * zoom_scale; var canvas_height = page.height * zoom_scale; - var page_width = (zoomMode == "manual") ? page.width * scale : canvas_width; - var page_height = (zoomMode == "manual") ? page.height * scale : canvas_height; + var page_width = (options.zoomMode == "manual") ? page.width * scale : canvas_width; + 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 canvas.width = (canvas_width < window.innerWidth) ? window.innerWidth : canvas_width; canvas.height = (canvas_height < window.innerHeight) ? window.innerHeight : canvas_height; - + // draw the page(s) 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 */ - function drawNextPage() { + ComicBook.prototype.drawNextPage = function() { if (pointer + 1 < pages.length) { pointer++; - drawPage(); + this.drawPage(); } } @@ -163,21 +174,21 @@ function ComicBook() { * * @see #drawPage */ - function drawPrevPage() { + ComicBook.prototype.drawPrevPage = function() { if (pointer > 0) { pointer--; - drawPage(); + this.drawPage(); } } - - function navigation(e) { + + ComicBook.prototype.navigation = function(e) { switch (e.type) { case "click": switch (getCursorPosition(e)) { - case "left": drawPrevPage(); break; - case "right": drawNextPage(); break; + case "left": ComicBook.prototype.drawPrevPage(); break; + case "right": ComicBook.prototype.drawNextPage(); break; } break; @@ -191,19 +202,38 @@ function ComicBook() { * Thanks to: Mark Pilgrim & http://diveintohtml5.org/canvas.html */ function getCursorPosition(e) { - + var x; // check if page relative positions exist if (e.pageX) x = e.pageX; - + // if not figure them out else x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; - + // make the position relative to the canvas x -= canvas.offsetLeft; - + // check if the user clicked on the left or right side 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; + } +} \ No newline at end of file