adding draw page methods, preparing double page mode

This commit is contained in:
Bala Clark 2015-07-19 10:07:11 +02:00
parent 78e5fcd049
commit 8ab949583f
8 changed files with 262 additions and 34 deletions

View file

@ -5,9 +5,15 @@ let ProgressBar = require('./view/progress-bar')
class ComicBook extends EventEmitter { class ComicBook extends EventEmitter {
constructor (srcs = []) { constructor (srcs = [], options) {
super() super()
this.options = Object.assign({
// manga mode
rtl: false,
doublePage: false
}, options)
// requested image srcs // requested image srcs
this.srcs = srcs this.srcs = srcs
@ -72,17 +78,32 @@ class ComicBook extends EventEmitter {
this.progressBar.update(percentage) this.progressBar.update(percentage)
} }
drawPage () { drawPage (pageIndex) {
let page = this.pages.get(this.currentPageIndex) if (typeof pageIndex !== 'number') pageIndex = this.currentPageIndex
this.canvas.drawImage(page) let page = this.pages.get(pageIndex)
try {
this.canvas.drawImage(page)
this.currentPageIndex = pageIndex
} catch (e) {
if (e.message !== 'Invalid image') throw e
}
} }
drawNextPage () { drawNextPage () {
// TODO let increment = this.options.doublePage ? 2 : 1
let index = this.currentPageIndex + increment
if (index >= this.pages.size) {
index = this.pages.size - 1
}
this.drawPage(index)
} }
drawPrevioousPage () { drawPreviousPage () {
// TODO let increment = this.options.doublePage ? 2 : 1
let index = this.currentPageIndex - increment
if (index < 0) index = 0
this.drawPage(index)
} }
} }

View file

@ -1,5 +1,5 @@
let ComicBook = window.ComicBook = require('./comic-book') let ComicBook = window.ComicBook = require('./comic-book')
let comic = new ComicBook([ let comic = window.comic = new ComicBook([
'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_00.jpg', 'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_00.jpg',
'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_01.jpg', 'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_01.jpg',
'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_02.jpg', 'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_02.jpg',
@ -13,8 +13,10 @@ let comic = new ComicBook([
'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_10.jpg' 'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_10.jpg'
]) ])
comic.preload()
comic.render()
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
document.body.appendChild(comic.render().el) document.body.appendChild(comic.el)
comic.preload()
}, false) }, false)

View file

@ -13,8 +13,8 @@ class Canvas extends EventEmitter {
this.options = Object.assign({ this.options = Object.assign({
// fitWidth, fitWindow, manua // fitWidth, fitWindow, manua
zoomMode: 'fitWidth', zoomMode: 'fitWidth',
// ltr, rtl // manga mode
readDirection: 'ltr', rtl: false,
// should two pages be rendered at a time? // should two pages be rendered at a time?
doublePage: false doublePage: false
}, options) }, options)
@ -126,7 +126,7 @@ class Canvas extends EventEmitter {
} }
// in manga double page mode reverse the page(s) // in manga double page mode reverse the page(s)
if (this.options.manga && this.options.doublePage && typeof page2 === 'object') { if (this.options.rtl && this.options.doublePage && typeof page2 === 'object') {
let tmpPage = page let tmpPage = page
let tmpPage2 = page2 let tmpPage2 = page2
page = tmpPage2 page = tmpPage2

63
dist/comicbook.js vendored
View file

@ -9,6 +9,8 @@ var _createClass = require('babel-runtime/helpers/create-class')['default'];
var _classCallCheck = require('babel-runtime/helpers/class-call-check')['default']; var _classCallCheck = require('babel-runtime/helpers/class-call-check')['default'];
var _Object$assign = require('babel-runtime/core-js/object/assign')['default'];
var _Map = require('babel-runtime/core-js/map')['default']; var _Map = require('babel-runtime/core-js/map')['default'];
var EventEmitter = require('events').EventEmitter; var EventEmitter = require('events').EventEmitter;
@ -19,22 +21,30 @@ var ProgressBar = require('./view/progress-bar');
var ComicBook = (function (_EventEmitter) { var ComicBook = (function (_EventEmitter) {
_inherits(ComicBook, _EventEmitter); _inherits(ComicBook, _EventEmitter);
function ComicBook() { function ComicBook(srcs, options) {
var srcs = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0]; if (srcs === undefined) srcs = [];
_classCallCheck(this, ComicBook); _classCallCheck(this, ComicBook);
_get(Object.getPrototypeOf(ComicBook.prototype), 'constructor', this).call(this); _get(Object.getPrototypeOf(ComicBook.prototype), 'constructor', this).call(this);
this.options = _Object$assign({
// manga mode
rtl: false,
doublePage: false
}, options);
// requested image srcs // requested image srcs
this.srcs = srcs; this.srcs = srcs;
// loaded image objects // loaded image objects
this.pages = new _Map(); this.pages = new _Map();
this.currentPageIndex = 0;
this.preloadBuffer = 4; this.preloadBuffer = 4;
// TODO move this logic into the router
this.currentPageIndex = 0;
this.canvas = new Canvas(); this.canvas = new Canvas();
this.loadIndicator = new LoadIndicator(); this.loadIndicator = new LoadIndicator();
this.progressBar = new ProgressBar(); this.progressBar = new ProgressBar();
@ -96,9 +106,34 @@ var ComicBook = (function (_EventEmitter) {
} }
}, { }, {
key: 'drawPage', key: 'drawPage',
value: function drawPage() { value: function drawPage(pageIndex) {
var page = this.pages.get(this.currentPageIndex); if (typeof pageIndex !== 'number') pageIndex = this.currentPageIndex;
this.canvas.drawImage(page); var page = this.pages.get(pageIndex);
try {
this.canvas.drawImage(page);
this.currentPageIndex = pageIndex;
} catch (e) {
if (e.message !== 'Invalid image') throw e;
}
}
}, {
key: 'drawNextPage',
value: function drawNextPage() {
var increment = this.options.doublePage ? 2 : 1;
var index = this.currentPageIndex + increment;
if (index >= this.pages.size) {
index = this.pages.size - 1;
}
this.drawPage(index);
}
}, {
key: 'drawPreviousPage',
value: function drawPreviousPage() {
var increment = this.options.doublePage ? 2 : 1;
var index = this.currentPageIndex - increment;
if (index < 0) index = 0;
this.drawPage(index);
} }
}]); }]);
@ -107,15 +142,17 @@ var ComicBook = (function (_EventEmitter) {
module.exports = ComicBook; module.exports = ComicBook;
},{"./view/canvas":3,"./view/load-indicator":4,"./view/progress-bar":5,"babel-runtime/core-js/map":7,"babel-runtime/helpers/class-call-check":12,"babel-runtime/helpers/create-class":13,"babel-runtime/helpers/get":14,"babel-runtime/helpers/inherits":15,"events":53}],2:[function(require,module,exports){ },{"./view/canvas":3,"./view/load-indicator":4,"./view/progress-bar":5,"babel-runtime/core-js/map":7,"babel-runtime/core-js/object/assign":8,"babel-runtime/helpers/class-call-check":12,"babel-runtime/helpers/create-class":13,"babel-runtime/helpers/get":14,"babel-runtime/helpers/inherits":15,"events":53}],2:[function(require,module,exports){
'use strict'; 'use strict';
var ComicBook = window.ComicBook = require('./comic-book'); var ComicBook = window.ComicBook = require('./comic-book');
var comic = new ComicBook(['https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_00.jpg', 'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_01.jpg', 'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_02.jpg', 'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_03.jpg', 'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_04.jpg', 'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_05.jpg', 'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_06.jpg', 'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_07.jpg', 'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_08.jpg', 'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_09.jpg', 'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_10.jpg']); var comic = window.comic = new ComicBook(['https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_00.jpg', 'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_01.jpg', 'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_02.jpg', 'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_03.jpg', 'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_04.jpg', 'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_05.jpg', 'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_06.jpg', 'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_07.jpg', 'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_08.jpg', 'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_09.jpg', 'https://raw.githubusercontent.com/balaclark/HTML5-Comic-Book-Reader/master/examples/goldenboy/goldenboy_10.jpg']);
comic.preload();
comic.render();
document.addEventListener('DOMContentLoaded', function () { document.addEventListener('DOMContentLoaded', function () {
document.body.appendChild(comic.render().el); document.body.appendChild(comic.el);
comic.preload();
}, false); }, false);
},{"./comic-book":1}],3:[function(require,module,exports){ },{"./comic-book":1}],3:[function(require,module,exports){
@ -149,8 +186,8 @@ var Canvas = (function (_EventEmitter) {
this.options = _Object$assign({ this.options = _Object$assign({
// fitWidth, fitWindow, manua // fitWidth, fitWindow, manua
zoomMode: 'fitWidth', zoomMode: 'fitWidth',
// ltr, rtl // manga mode
readDirection: 'ltr', rtl: false,
// should two pages be rendered at a time? // should two pages be rendered at a time?
doublePage: false doublePage: false
}, options); }, options);
@ -261,7 +298,7 @@ var Canvas = (function (_EventEmitter) {
} }
// in manga double page mode reverse the page(s) // in manga double page mode reverse the page(s)
if (this.options.manga && this.options.doublePage && typeof page2 === 'object') { if (this.options.rtl && this.options.doublePage && typeof page2 === 'object') {
var tmpPage = page; var tmpPage = page;
var tmpPage2 = page2; var tmpPage2 = page2;
page = tmpPage2; page = tmpPage2;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -95,8 +95,176 @@ describe('ComicBook', () => {
done() done()
}) })
}) })
it('should restart the preload from whatever page is requested')
}) })
it('should scroll to the top of the page on page turn') describe('draw', () => {
describe('drawPage()', () => {
it('should draw a given page', () => {
let comic = new ComicBook(srcs)
comic.canvas.drawImage = spy()
comic.drawPage(1)
assert.equal(comic.canvas.drawImage.callCount, 1)
assert(comic.canvas.drawImage.calls[0].calledWith(comic.pages.get(1)))
})
it('should default to drawing the current page', () => {
let comic = new ComicBook(srcs)
comic.canvas.drawImage = spy()
comic.currentPageIndex = 2
comic.drawPage()
assert.equal(comic.canvas.drawImage.callCount, 1)
assert(comic.canvas.drawImage.calls[0].calledWith(comic.pages.get(2)))
})
it('should update the current page index after drawing', () => {
let comic = new ComicBook(srcs)
comic.canvas.drawImage = () => {}
comic.currentPageIndex = 1
comic.drawPage(2)
assert.equal(comic.currentPageIndex, 2)
})
it('should ignore "Invalid image" exceptions and not draw the page when they occur', () => {
let comic = new ComicBook(srcs)
comic.currentPageIndex = 1
assert.doesNotThrow(comic.drawPage.bind(comic, 666))
assert.equal(comic.currentPageIndex, 1)
})
it('should throw all other exceptions and not draw the page when they occur', () => {
let comic = new ComicBook(srcs)
comic.canvas.drawImage = () => { throw new Error('Some other exception') }
assert.throws(comic.drawPage.bind(comic))
})
it('should draw two pages in double page mode')
})
describe('drawNextPage()', () => {
it('should draw the next page', done => {
let comic = new ComicBook(srcs)
comic.drawPage = spy()
comic.currentPageIndex = 1
comic.on('preload:finish', () => {
comic.drawNextPage()
assert(comic.drawPage.calls[0].calledWith(2))
done()
})
comic.preload()
})
it('should draw the next page in double page mode', done => {
let comic = new ComicBook(srcs)
comic.drawPage = spy()
comic.currentPageIndex = 1
comic.options.doublePage = true
comic.on('preload:finish', () => {
comic.drawNextPage()
assert(comic.drawPage.calls[0].calledWith(3))
done()
})
comic.preload()
})
it('should handle the final page of double page mode being a single page', done => {
let comic = new ComicBook(srcs)
comic.drawPage = spy()
comic.currentPageIndex = 3
comic.options.doublePage = true
comic.on('preload:finish', () => {
comic.drawNextPage()
assert(comic.drawPage.calls[0].calledWith(4))
done()
})
comic.preload()
})
})
describe('drawPreviousPage()', () => {
it('should draw the previous page', done => {
let comic = new ComicBook(srcs)
comic.drawPage = spy()
comic.currentPageIndex = 2
comic.on('preload:finish', () => {
comic.drawPreviousPage()
assert(comic.drawPage.calls[0].calledWith(1))
done()
})
comic.preload()
})
it('should draw the previous page in double page mode', done => {
let comic = new ComicBook(srcs)
comic.drawPage = spy()
comic.currentPageIndex = 3
comic.options.doublePage = true
comic.on('preload:finish', () => {
comic.drawPreviousPage()
assert(comic.drawPage.calls[0].calledWith(1))
done()
})
comic.preload()
})
it('should handle navigating back to an uneven first page in double page mode', done => {
let comic = new ComicBook(srcs)
comic.drawPage = spy()
comic.currentPageIndex = 1
comic.options.doublePage = true
comic.on('preload:finish', () => {
comic.drawPreviousPage()
assert(comic.drawPage.calls[0].calledWith(0))
done()
})
comic.preload()
})
it('should reverse image order in double page manga mode')
})
})
describe('routing', () => {
it('should scroll to the top of the page on page turn')
it('should render a page when the route changes')
})
}) })