diff --git a/scripts.js b/scripts.js deleted file mode 100644 index bd3e58f..0000000 --- a/scripts.js +++ /dev/null @@ -1,326 +0,0 @@ -/*jslint on: true, eqeqeq: true */ -/* - TODOs: - - Fo sho: - - Show a progress bar when buffering - - use document.body.offsetWidth where present? (instead of window.innerWidth, the former excludes the width of scrollbars) - - scroll two pages at a time in double page mode - - page controls - - thumbnail browser - - chrome frame - - Nice 2 have: - - remember position (use localStorage) - - maybe use local storage for the pages array too? might be easier to implement manga mode with that - - offline mode - - page turn animation - -*/ - - - -/** - * 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) { - - var prop; - - if (typeof b === "undefined") { b = {}; } - - for (prop in a) { - if (a.hasOwnProperty(prop)) { - if (prop in b) { continue; } - b[prop] = a[prop]; - } - } - - return b; -} - -function ComicBook(id, srcs, opts) { - - this.id = id; // canvas element id - this.srcs = srcs; // array of image srcs for pages - - var defaults = { - displayMode: "double", // single / double - zoomMode: "fitWidth", // manual / fitWidth - manga: false - }; - - var options = merge(defaults, opts); // options array for internal use - - var pages = []; // array of preloaded Image objects - var canvas; // the HTML5 canvas object - var context; // the 2d drawing context - - var buffer = 4; // image preload buffer level - var pointer = 0; // the current page - var loaded = 0; // the amount of images that have been loaded so far - - var scale = 1; // page zoom scale, 1 = 100% - - /** - * Figure out the cursor position relative to the canvas. - * - * Thanks to: Mark Pilgrim & http://diveintohtml5.org/canvas.html - */ - function getCursorPosition(e) { - - var x; // horizontal cursor position - - // check if page relative positions exist, if not figure them out - if (e.pageX) { - x = e.pageX; - } 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'; - } - - /* - * @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 - */ - ComicBook.prototype.draw = function () { - - // setup canvas - canvas = document.getElementById(this.id); - context = canvas.getContext("2d"); - - // preload images if needed - if (pages.length !== this.srcs.length) { this.preload(this.srcs); } - else { this.drawPage(); } - - // add page controls - canvas.addEventListener("click", ComicBook.prototype.navigation, false); - }; - - /* - * Zoom the canvas - * - * @param new_scale {Number} Scale the canvas to this ratio - */ - ComicBook.prototype.zoom = function (new_scale) { - options.zoomMode = "manual"; - scale = new_scale; - if (typeof pages[pointer] === "object") { this.drawPage(); } - }; - - /** - * Preload all images, draw the page only after a given number have been loaded. - * - * @param srcs {Object} srcs - * @see #drawPage - */ - 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 - - var i = 0; // the current page counter for this method - - // I am using recursion instead of a forEach loop so that the next image is - // only loaded when the previous one has completely finished - function preload(i) { - - var page = new Image(); - - // console.log("starting to load: " + srcs[i]); - - page.src = srcs[i]; - - page.onload = function () { - - // console.info("loaded: " + srcs[i]); - - pages[i] = this; - loaded += 1; - - // there are still more pages to load, do it - if (loaded < srcs.length) { - i += 1; - preload(i); - } - - // start rendering the comic when the buffer level has been reached - if (loaded === buffer + 1) { ComicBook.prototype.drawPage(); } - if (loaded === srcs.length) { /* console.log("all loaded"); */ } - }; - } - - if (i === 0) { preload(i); } - }; - - /** - * Draw the current page in the canvas - * - * TODO: break this down into drawSinglePage() & drawDoublePage() - * TODO: if the current browser doesn't have canvas support, use img tags - */ - ComicBook.prototype.drawPage = function () { - - var zoom_scale; - var offsetW = 0, offsetH = 0; - - var page = pages[pointer]; - var page2 = pages[pointer + 1]; - - if (typeof page !== "object") { throw "invalid page type '"+ typeof page +"'"; } - - var width = page.width; - - // reset the canvas to stop duplicate pages showing - canvas.width = 0; - canvas.height = 0; - - if (options.displayMode === "double") { - - // 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(options.zoomMode) { - - case "manual": - document.body.style.overflowX = "auto" - zoom_scale = (options.displayMode === "double") ? scale * 2 : scale; - break; - - case "fitWidth": - document.body.style.overflowX = "hidden" - zoom_scale = (window.innerWidth > width) ? ((window.innerWidth - width) / window.innerWidth) + 1 // scale up if the window is wider than the page - : window.innerWidth / width; // scale down if the window is narrower than the page - break; - - default:throw "invalid zoomMode"; - } - - var canvas_width = page.width * zoom_scale; - var canvas_height = page.height * zoom_scale; - - var page_width = (options.zoomMode === "manual") ? page.width * scale : canvas_width; - var page_height = (options.zoomMode === "manual") ? page.height * scale : canvas_height; - - canvas_height = page_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; - - // disable scrollbars if not needed - document.body.style.overflowX = (canvas_width < window.innerWidth) ? "hidden" : "auto"; - document.body.style.overflowY = (canvas_height < window.innerHeight) ? "hidden" : "auto"; - - // work out a horizonal position that will keep the pages always centred - if (canvas_width < window.innerWidth && options.zoomMode === "manual") { - offsetW = (window.innerWidth - page_width) / 2; - if (options.displayMode === "double") { offsetW = offsetW - page_width / 2; } - } - - // work out a vertical position that will keep the pages always centred - if (canvas_height < window.innerHeight && options.zoomMode === "manual") { - offsetH = (window.innerHeight - page_height) / 2; - } - - // in manga double page mode reverse the pages - if (options.manga && options.displayMode === "double") { - var tmpPage = page; - var tmpPage2 = page2; // FIXME: check this exists before using - page = tmpPage2; - page2 = tmpPage; - } - - // draw the page(s) - context.drawImage(page, offsetW, offsetH, page_width, page_height); - if (options.displayMode === "double" && typeof page2 === "object") { context.drawImage(page2, page_width + offsetW, offsetH, page_width, page_height); } - }; - - /** - * Increment the counter and draw the page in the canvas - * - * @see #drawPage - */ - ComicBook.prototype.drawNextPage = function () { - if (pointer + 1 < pages.length) { - pointer++; - this.drawPage(); - } - }; - - /** - * Decrement the counter and draw the page in the canvas - * - * @see #drawPage - */ - ComicBook.prototype.drawPrevPage = function () { - if (pointer > 0) { - pointer--; - this.drawPage(); - } - }; - - ComicBook.prototype.navigation = function (e) { - - if (e.type === "click") { - - var side = getCursorPosition(e); - - window.scroll(0,0); - - // western style (left to right) - if (!options.manga) { - if (side === "left") { ComicBook.prototype.drawPrevPage(); } - if (side === "right") { ComicBook.prototype.drawNextPage(); } - } - // manga style (right to left) - else { - if (side === "left") { ComicBook.prototype.drawNextPage(); } - if (side === "right") { ComicBook.prototype.drawPrevPage(); } - } - } - }; -} - -var book; - -window.onload = function() { - - var pages = [ - "http://dev.justforcomics.com/get/image/?f=comics/extracted/oni_whiteout_melt_1/00.jpg", - "http://dev.justforcomics.com/get/image/?f=comics/extracted/oni_whiteout_melt_1/01.jpg", - "http://dev.justforcomics.com/get/image/?f=comics/extracted/oni_whiteout_melt_1/02.jpg", - "http://dev.justforcomics.com/get/image/?f=comics/extracted/oni_whiteout_melt_1/03.jpg", - "http://dev.justforcomics.com/get/image/?f=comics/extracted/oni_whiteout_melt_1/04.jpg", - "http://dev.justforcomics.com/get/image/?f=comics/extracted/oni_whiteout_melt_1/05.jpg", - "http://dev.justforcomics.com/get/image/?f=comics/extracted/oni_whiteout_melt_1/06.jpg" - ]; - - var options = { - displayMode: "double", - zoomMode: "fitWidth", - manga: false - }; - - book = new ComicBook("comic", pages, options); - book.draw(); -}; - -window.onresize = function() { - book.draw(); -};