2015-01-15 04:09:39 +03:00
|
|
|
/* globals $, App, d3 */
|
2015-01-09 00:22:23 +03:00
|
|
|
|
|
|
|
(function() {
|
|
|
|
// ----------
|
|
|
|
window.App = {
|
|
|
|
// ----------
|
|
|
|
init: function() {
|
|
|
|
var self = this;
|
|
|
|
|
2015-02-04 21:18:36 +03:00
|
|
|
this.maxImages = 500;
|
2015-01-09 00:22:23 +03:00
|
|
|
this.mode = 'none';
|
|
|
|
this.pageBuffer = 0.05;
|
2015-01-10 00:53:48 +03:00
|
|
|
this.bigBuffer = 0.2;
|
2015-02-14 01:32:17 +03:00
|
|
|
this.pageIndex = 0;
|
2015-01-09 00:22:23 +03:00
|
|
|
this.modeNames = [
|
|
|
|
'thumbs',
|
|
|
|
'scroll',
|
|
|
|
'book',
|
|
|
|
'page'
|
|
|
|
];
|
|
|
|
|
2015-02-11 01:02:41 +03:00
|
|
|
this.pages = this.createPages();
|
|
|
|
|
|
|
|
var tileSources = $.map(this.pages, function(v, i) {
|
2015-03-18 20:03:44 +03:00
|
|
|
return {
|
|
|
|
tileSource: v.starter.tileSource,
|
|
|
|
clip: v.starter.clip
|
|
|
|
};
|
2015-02-11 01:02:41 +03:00
|
|
|
});
|
|
|
|
|
2015-01-09 00:22:23 +03:00
|
|
|
this.viewer = OpenSeadragon({
|
|
|
|
id: "contentDiv",
|
|
|
|
prefixUrl: "../../../build/openseadragon/images/",
|
2015-01-09 22:45:53 +03:00
|
|
|
autoResize: false,
|
2015-01-14 02:33:03 +03:00
|
|
|
showHomeControl: false,
|
2015-02-11 01:02:41 +03:00
|
|
|
tileSources: tileSources
|
2015-01-09 00:22:23 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
this.viewer.addHandler('open', function() {
|
2015-01-09 22:45:53 +03:00
|
|
|
self.$el = $(self.viewer.element);
|
2015-02-11 01:02:41 +03:00
|
|
|
|
|
|
|
$.each(self.pages, function(i, v) {
|
2015-02-16 21:18:59 +03:00
|
|
|
v.setTiledImage(self.viewer.world.getItemAt(i));
|
2015-02-14 02:55:57 +03:00
|
|
|
v.addDetails();
|
2015-02-11 01:02:41 +03:00
|
|
|
});
|
|
|
|
|
2015-01-16 01:32:42 +03:00
|
|
|
self.setMode({
|
2015-01-24 03:00:58 +03:00
|
|
|
mode: 'thumbs',
|
|
|
|
immediately: true
|
2015-01-16 01:32:42 +03:00
|
|
|
});
|
2015-01-09 00:22:23 +03:00
|
|
|
});
|
|
|
|
|
2015-01-10 02:46:57 +03:00
|
|
|
this.viewer.addHandler('canvas-drag', function() {
|
2015-01-22 22:52:08 +03:00
|
|
|
if (self.mode === 'scroll') {
|
|
|
|
var result = self.hitTest(self.viewer.viewport.getCenter());
|
2015-01-14 02:33:03 +03:00
|
|
|
if (result) {
|
2015-02-14 01:32:17 +03:00
|
|
|
self.pageIndex = result.index;
|
2015-02-11 01:02:41 +03:00
|
|
|
self.update();
|
2015-01-14 02:33:03 +03:00
|
|
|
}
|
2015-01-09 01:04:31 +03:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2015-03-12 01:41:36 +03:00
|
|
|
this.viewer.addHandler('zoom', function(event) {
|
|
|
|
self.applyConstraints();
|
|
|
|
});
|
|
|
|
|
|
|
|
this.viewer.addHandler('pan', function(event) {
|
2015-01-20 22:23:56 +03:00
|
|
|
self.applyConstraints();
|
|
|
|
});
|
|
|
|
|
2015-01-09 00:22:23 +03:00
|
|
|
$.each(this.modeNames, function(i, v) {
|
|
|
|
$('.' + v).click(function() {
|
2015-01-16 01:32:42 +03:00
|
|
|
self.setMode({
|
|
|
|
mode: v
|
|
|
|
});
|
2015-01-09 00:22:23 +03:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
$('.next').click(function() {
|
2015-01-10 02:11:11 +03:00
|
|
|
self.next();
|
2015-01-09 00:22:23 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
$('.previous').click(function() {
|
2015-01-10 02:11:11 +03:00
|
|
|
self.previous();
|
|
|
|
});
|
|
|
|
|
2015-03-10 01:32:38 +03:00
|
|
|
this.$details = $('.details')
|
|
|
|
.prop('checked', true)
|
|
|
|
.change(function() {
|
|
|
|
if (self.$details.prop('checked')) {
|
|
|
|
self.showDetails();
|
|
|
|
} else {
|
|
|
|
self.hideDetails();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2015-01-10 02:11:11 +03:00
|
|
|
$(window).keyup(function(event) {
|
|
|
|
if (self.mode === 'thumbs') {
|
|
|
|
return;
|
2015-01-09 00:22:23 +03:00
|
|
|
}
|
|
|
|
|
2015-01-10 02:11:11 +03:00
|
|
|
if (event.which === 39) { // Right arrow
|
|
|
|
self.next();
|
|
|
|
} else if (event.which === 37) { // Left arrow
|
|
|
|
self.previous();
|
|
|
|
}
|
2015-01-09 00:22:23 +03:00
|
|
|
});
|
|
|
|
|
2015-01-21 03:10:24 +03:00
|
|
|
this.$scrollInner = $('.scroll-inner');
|
|
|
|
|
|
|
|
this.$scrollCover = $('.scroll-cover')
|
|
|
|
.scroll(function(event) {
|
|
|
|
var info = self.getScrollInfo();
|
|
|
|
if (!info || self.ignoreScroll) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var pos = new OpenSeadragon.Point(info.thumbBounds.getCenter().x,
|
|
|
|
info.thumbBounds.y + (info.viewportHeight / 2) +
|
|
|
|
(info.viewportMax * info.scrollFactor));
|
|
|
|
|
|
|
|
self.viewer.viewport.panTo(pos, true);
|
|
|
|
})
|
|
|
|
.mousemove(function(event) {
|
|
|
|
var pixel = new OpenSeadragon.Point(event.clientX, event.clientY);
|
2015-02-10 22:42:36 +03:00
|
|
|
pixel.y -= self.$scrollCover.position().top;
|
2015-01-21 03:10:24 +03:00
|
|
|
var result = self.hitTest(self.viewer.viewport.pointFromPixel(pixel));
|
|
|
|
self.updateHover(result ? result.index : -1);
|
|
|
|
})
|
|
|
|
.click(function(event) {
|
|
|
|
var pixel = new OpenSeadragon.Point(event.clientX, event.clientY);
|
2015-02-10 22:42:36 +03:00
|
|
|
pixel.y -= self.$scrollCover.position().top;
|
2015-01-21 03:10:24 +03:00
|
|
|
var result = self.hitTest(self.viewer.viewport.pointFromPixel(pixel));
|
|
|
|
if (result) {
|
|
|
|
self.setMode({
|
|
|
|
mode: 'page',
|
2015-02-14 01:32:17 +03:00
|
|
|
pageIndex: result.index
|
2015-01-21 03:10:24 +03:00
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2015-01-15 04:09:39 +03:00
|
|
|
var svgNode = this.viewer.svgOverlay();
|
|
|
|
|
|
|
|
this.highlight = d3.select(svgNode).append("rect")
|
|
|
|
.style('fill', 'none')
|
|
|
|
.style('stroke', '#08f')
|
|
|
|
.style('opacity', 0)
|
|
|
|
.style('stroke-width', 0.05)
|
|
|
|
.attr("pointer-events", "none");
|
|
|
|
|
|
|
|
this.hover = d3.select(svgNode).append("rect")
|
|
|
|
.style('fill', 'none')
|
|
|
|
.style('stroke', '#08f')
|
|
|
|
.style('opacity', 0)
|
|
|
|
.style('stroke-width', 0.05)
|
|
|
|
.attr("pointer-events", "none");
|
|
|
|
|
|
|
|
$(window).resize(function() {
|
2015-01-16 01:32:42 +03:00
|
|
|
var newSize = new OpenSeadragon.Point(self.$el.width(), self.$el.height());
|
|
|
|
self.viewer.viewport.resize(newSize, false);
|
|
|
|
self.setMode({
|
|
|
|
mode: self.mode,
|
|
|
|
immediately: true
|
|
|
|
});
|
|
|
|
|
2015-01-21 04:19:20 +03:00
|
|
|
self.viewer.forceRedraw();
|
|
|
|
|
2015-01-15 04:09:39 +03:00
|
|
|
self.viewer.svgOverlay('resize');
|
|
|
|
});
|
|
|
|
|
2015-01-09 00:22:23 +03:00
|
|
|
this.update();
|
|
|
|
},
|
|
|
|
|
2015-01-10 02:11:11 +03:00
|
|
|
// ----------
|
|
|
|
next: function() {
|
2015-02-14 01:32:17 +03:00
|
|
|
var pageIndex = this.pageIndex + (this.mode === 'book' ? 2 : 1);
|
|
|
|
if (this.mode === 'book' && pageIndex % 2 === 0 && pageIndex !== 0) {
|
|
|
|
pageIndex --;
|
2015-01-10 02:11:11 +03:00
|
|
|
}
|
|
|
|
|
2015-01-16 01:32:42 +03:00
|
|
|
this.goToPage({
|
2015-02-14 01:32:17 +03:00
|
|
|
pageIndex: pageIndex
|
2015-01-16 01:32:42 +03:00
|
|
|
});
|
2015-01-10 02:11:11 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
// ----------
|
|
|
|
previous: function() {
|
2015-02-14 01:32:17 +03:00
|
|
|
var pageIndex = this.pageIndex - (this.mode === 'book' ? 2 : 1);
|
|
|
|
if (this.mode === 'book' && pageIndex % 2 === 0 && pageIndex !== 0) {
|
|
|
|
pageIndex --;
|
2015-01-10 02:11:11 +03:00
|
|
|
}
|
|
|
|
|
2015-01-16 01:32:42 +03:00
|
|
|
this.goToPage({
|
2015-02-14 01:32:17 +03:00
|
|
|
pageIndex: pageIndex
|
2015-01-16 01:32:42 +03:00
|
|
|
});
|
2015-03-10 01:32:38 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
// ----------
|
|
|
|
hideDetails: function() {
|
|
|
|
$.each(this.pages, function(i, v) {
|
|
|
|
v.removeDetails();
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
// ----------
|
|
|
|
showDetails: function() {
|
|
|
|
$.each(this.pages, function(i, v) {
|
|
|
|
v.addDetails();
|
|
|
|
});
|
2015-01-10 02:11:11 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
// ----------
|
|
|
|
hitTest: function(pos) {
|
2015-02-14 01:32:17 +03:00
|
|
|
var count = this.pages.length;
|
2015-02-16 21:18:59 +03:00
|
|
|
var page, box;
|
2015-01-10 02:11:11 +03:00
|
|
|
|
|
|
|
for (var i = 0; i < count; i++) {
|
2015-02-16 21:18:59 +03:00
|
|
|
page = this.pages[i];
|
|
|
|
box = page.getBounds();
|
2015-01-10 02:11:11 +03:00
|
|
|
if (pos.x > box.x && pos.y > box.y && pos.x < box.x + box.width &&
|
|
|
|
pos.y < box.y + box.height) {
|
|
|
|
return {
|
|
|
|
index: i
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
},
|
|
|
|
|
2015-01-21 03:10:24 +03:00
|
|
|
// ----------
|
|
|
|
getScrollInfo: function() {
|
|
|
|
if (!this.thumbBounds) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
var output = {};
|
|
|
|
|
|
|
|
var viewerWidth = this.$el.width();
|
|
|
|
var viewerHeight = this.$el.height();
|
|
|
|
var scrollTop = this.$scrollCover.scrollTop();
|
|
|
|
output.scrollMax = this.$scrollInner.height() - this.$scrollCover.height();
|
|
|
|
output.scrollFactor = (output.scrollMax > 0 ? scrollTop / output.scrollMax : 0);
|
|
|
|
|
|
|
|
output.thumbBounds = this.thumbBounds;
|
|
|
|
output.viewportHeight = output.thumbBounds.width * (viewerHeight / viewerWidth);
|
|
|
|
output.viewportMax = Math.max(0, output.thumbBounds.height - output.viewportHeight);
|
|
|
|
return output;
|
|
|
|
},
|
|
|
|
|
2015-01-09 00:22:23 +03:00
|
|
|
// ----------
|
|
|
|
update: function() {
|
|
|
|
var self = this;
|
|
|
|
|
2015-01-10 02:11:11 +03:00
|
|
|
$('.nav').toggle(this.mode === 'scroll' || this.mode === 'book' || this.mode === 'page');
|
2015-02-14 01:32:17 +03:00
|
|
|
$('.previous').toggleClass('hidden', this.pageIndex <= 0);
|
|
|
|
$('.next').toggleClass('hidden', this.pageIndex >= this.pages.length - 1);
|
2015-01-09 00:22:23 +03:00
|
|
|
|
|
|
|
$.each(this.modeNames, function(i, v) {
|
|
|
|
$('.' + v).toggleClass('active', v === self.mode);
|
|
|
|
});
|
2015-02-11 01:02:41 +03:00
|
|
|
|
|
|
|
// alternates menu
|
|
|
|
if (this.$alternates) {
|
|
|
|
this.$alternates.remove();
|
|
|
|
this.$alternates = null;
|
|
|
|
}
|
|
|
|
|
2015-02-14 01:32:17 +03:00
|
|
|
var page = this.pages[this.pageIndex];
|
2015-02-11 01:02:41 +03:00
|
|
|
if (page && page.alternates && page.alternates.length) {
|
|
|
|
this.$alternates = $('<select>')
|
|
|
|
.change(function() {
|
|
|
|
page.selectAlternate(parseInt(self.$alternates.val(), 10));
|
|
|
|
})
|
|
|
|
.appendTo('.nav');
|
|
|
|
|
|
|
|
$('<option>')
|
|
|
|
.attr('value', -1)
|
|
|
|
.text(page.label || 'Default')
|
|
|
|
.appendTo(self.$alternates);
|
|
|
|
|
|
|
|
$.each(page.alternates, function(i, v) {
|
|
|
|
if (v.label) {
|
|
|
|
$('<option>')
|
|
|
|
.attr('value', i)
|
|
|
|
.text(v.label)
|
|
|
|
.appendTo(self.$alternates);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
this.$alternates.val(page.alternateIndex);
|
|
|
|
}
|
2015-01-09 00:22:23 +03:00
|
|
|
},
|
|
|
|
|
2015-01-20 22:23:56 +03:00
|
|
|
// ----------
|
|
|
|
applyConstraints: function() {
|
|
|
|
if (this.mode === 'thumbs') {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-03-12 01:41:36 +03:00
|
|
|
if (this.panBounds && !this.inZoomConstraints) {
|
|
|
|
var changed = false;
|
|
|
|
var viewBounds = this.viewer.viewport.getBounds();
|
|
|
|
var panBounds = this.panBounds.clone();
|
|
|
|
|
|
|
|
if (viewBounds.x < panBounds.x - 0.00001) {
|
|
|
|
viewBounds.x = panBounds.x;
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (viewBounds.y < panBounds.y - 0.00001) {
|
|
|
|
viewBounds.y = panBounds.y;
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (viewBounds.width > panBounds.width + 0.00001) {
|
|
|
|
viewBounds.width = panBounds.width;
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (viewBounds.height > panBounds.height + 0.00001) {
|
|
|
|
viewBounds.height = panBounds.height;
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (viewBounds.x + viewBounds.width > panBounds.x + panBounds.width + 0.00001) {
|
|
|
|
viewBounds.x = (panBounds.x + panBounds.width) - viewBounds.width;
|
|
|
|
changed = true;
|
2015-01-20 22:23:56 +03:00
|
|
|
}
|
|
|
|
|
2015-03-12 01:41:36 +03:00
|
|
|
if (viewBounds.y + viewBounds.height > panBounds.y + panBounds.height + 0.00001) {
|
|
|
|
viewBounds.y = (panBounds.y + panBounds.height) - viewBounds.height;
|
|
|
|
changed = true;
|
2015-01-20 22:23:56 +03:00
|
|
|
}
|
|
|
|
|
2015-03-12 01:41:36 +03:00
|
|
|
if (changed) {
|
|
|
|
this.inZoomConstraints = true;
|
|
|
|
this.viewer.viewport.fitBounds(viewBounds);
|
|
|
|
this.inZoomConstraints = false;
|
2015-01-20 22:23:56 +03:00
|
|
|
}
|
|
|
|
}
|
2015-03-12 01:41:36 +03:00
|
|
|
|
|
|
|
var zoom = this.viewer.viewport.getZoom();
|
|
|
|
var maxZoom = 2;
|
|
|
|
|
|
|
|
var zoomPoint = this.viewer.viewport.zoomPoint || this.viewer.viewport.getCenter();
|
|
|
|
var info = this.hitTest(zoomPoint);
|
|
|
|
if (info) {
|
|
|
|
var page = this.pages[info.index];
|
|
|
|
var tiledImage = page.hitTest(zoomPoint);
|
|
|
|
if (tiledImage) {
|
|
|
|
maxZoom = this.viewer.maxZoomLevel;
|
|
|
|
if (!maxZoom) {
|
|
|
|
var imageWidth = tiledImage.getContentSize().x;
|
|
|
|
var viewerWidth = this.$el.width();
|
|
|
|
maxZoom = imageWidth * this.viewer.maxZoomPixelRatio / viewerWidth;
|
|
|
|
maxZoom /= tiledImage.getBounds().width;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (zoom > maxZoom) {
|
|
|
|
this.viewer.viewport.zoomSpring.target.value = maxZoom;
|
|
|
|
}
|
2015-01-20 22:23:56 +03:00
|
|
|
},
|
|
|
|
|
2015-01-09 00:22:23 +03:00
|
|
|
// ----------
|
2015-01-16 01:32:42 +03:00
|
|
|
setMode: function(config) {
|
2015-01-09 22:45:53 +03:00
|
|
|
var self = this;
|
|
|
|
|
2015-01-16 01:32:42 +03:00
|
|
|
this.mode = config.mode;
|
2015-01-09 00:22:23 +03:00
|
|
|
|
2015-02-14 01:32:17 +03:00
|
|
|
if (config.pageIndex !== undefined) {
|
|
|
|
this.pageIndex = config.pageIndex; // Need to do this before layout
|
2015-01-09 01:04:31 +03:00
|
|
|
}
|
|
|
|
|
2015-01-21 03:10:24 +03:00
|
|
|
this.ignoreScroll = true;
|
|
|
|
this.thumbBounds = null;
|
2015-01-10 00:53:48 +03:00
|
|
|
|
2015-01-21 03:10:24 +03:00
|
|
|
var layout = this.createLayout();
|
2015-01-09 22:45:53 +03:00
|
|
|
|
|
|
|
if (this.mode === 'thumbs') {
|
|
|
|
this.viewer.gestureSettingsMouse.scrollToZoom = false;
|
|
|
|
this.viewer.zoomPerClick = 1;
|
2015-01-14 02:33:03 +03:00
|
|
|
this.viewer.panHorizontal = false;
|
|
|
|
this.viewer.panVertical = false;
|
2015-01-10 00:53:48 +03:00
|
|
|
var viewerWidth = this.$el.width();
|
|
|
|
var width = layout.bounds.width + (this.bigBuffer * 2);
|
|
|
|
var height = layout.bounds.height + (this.bigBuffer * 2);
|
|
|
|
var newHeight = viewerWidth * (height / width);
|
2015-01-21 03:10:24 +03:00
|
|
|
this.$scrollCover.show();
|
|
|
|
this.$scrollInner
|
2015-01-09 22:45:53 +03:00
|
|
|
.css({
|
2015-01-10 00:53:48 +03:00
|
|
|
height: newHeight
|
2015-01-09 22:45:53 +03:00
|
|
|
});
|
|
|
|
} else {
|
|
|
|
this.viewer.gestureSettingsMouse.scrollToZoom = true;
|
|
|
|
this.viewer.zoomPerClick = 2;
|
2015-01-14 02:33:03 +03:00
|
|
|
this.viewer.panHorizontal = true;
|
|
|
|
this.viewer.panVertical = true;
|
2015-01-21 03:10:24 +03:00
|
|
|
this.$scrollCover.hide();
|
2015-01-09 22:45:53 +03:00
|
|
|
}
|
|
|
|
|
2015-01-16 01:32:42 +03:00
|
|
|
this.setLayout({
|
|
|
|
layout: layout,
|
|
|
|
immediately: config.immediately
|
|
|
|
});
|
2015-01-09 00:22:23 +03:00
|
|
|
|
2015-01-21 03:10:24 +03:00
|
|
|
if (this.mode === 'thumbs') {
|
|
|
|
// Set up thumbBounds
|
|
|
|
this.thumbBounds = this.viewer.world.getHomeBounds();
|
|
|
|
this.thumbBounds.x -= this.bigBuffer;
|
|
|
|
this.thumbBounds.y -= this.bigBuffer;
|
|
|
|
this.thumbBounds.width += (this.bigBuffer * 2);
|
|
|
|
this.thumbBounds.height += (this.bigBuffer * 2);
|
|
|
|
|
|
|
|
// Scroll to the appropriate location
|
|
|
|
var info = this.getScrollInfo();
|
|
|
|
|
|
|
|
var viewportBounds = this.thumbBounds.clone();
|
|
|
|
viewportBounds.y += info.viewportMax * info.scrollFactor;
|
|
|
|
viewportBounds.height = info.viewportHeight;
|
|
|
|
|
2015-02-16 21:18:59 +03:00
|
|
|
var pageBounds = this.pages[this.pageIndex].getBounds();
|
|
|
|
var top = pageBounds.y - this.bigBuffer;
|
|
|
|
var bottom = top + pageBounds.height + (this.bigBuffer * 2);
|
2015-01-21 03:10:24 +03:00
|
|
|
|
|
|
|
var normalY;
|
|
|
|
if (top < viewportBounds.y) {
|
|
|
|
normalY = top - this.thumbBounds.y;
|
|
|
|
} else if (bottom > viewportBounds.y + viewportBounds.height) {
|
|
|
|
normalY = (bottom - info.viewportHeight) - this.thumbBounds.y;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (normalY !== undefined) {
|
|
|
|
var viewportFactor = normalY / info.viewportMax;
|
|
|
|
this.$scrollCover.scrollTop(info.scrollMax * viewportFactor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-16 01:32:42 +03:00
|
|
|
this.goHome({
|
|
|
|
immediately: config.immediately
|
|
|
|
});
|
2015-01-09 01:04:31 +03:00
|
|
|
|
2015-01-14 02:33:03 +03:00
|
|
|
this.viewer.viewport.minZoomLevel = this.viewer.viewport.getZoom();
|
|
|
|
|
2015-01-09 00:22:23 +03:00
|
|
|
this.update();
|
2015-01-15 04:09:39 +03:00
|
|
|
this.updateHighlight();
|
|
|
|
this.updateHover(-1);
|
2015-01-21 03:10:24 +03:00
|
|
|
|
2015-01-21 04:19:20 +03:00
|
|
|
clearTimeout(this.scrollTimeout);
|
|
|
|
this.scrollTimeout = setTimeout(function() {
|
2015-01-21 03:10:24 +03:00
|
|
|
self.ignoreScroll = false;
|
|
|
|
}, this.viewer.animationTime * 1000);
|
2015-01-15 04:09:39 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
// ----------
|
|
|
|
updateHighlight: function() {
|
|
|
|
if (this.mode !== 'thumbs') {
|
|
|
|
this.highlight.style('opacity', 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-02-16 21:18:59 +03:00
|
|
|
var page = this.pages[this.pageIndex];
|
|
|
|
var box = page.getBounds();
|
2015-01-15 04:09:39 +03:00
|
|
|
|
2015-08-11 18:24:05 +03:00
|
|
|
if (this.highlight) {
|
|
|
|
this.highlight
|
|
|
|
.style('opacity', 1)
|
|
|
|
.attr("x", box.x)
|
|
|
|
.attr("width", box.width)
|
|
|
|
.attr("y", box.y)
|
|
|
|
.attr("height", box.height);
|
|
|
|
}
|
2015-01-15 04:09:39 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
// ----------
|
2015-02-14 01:32:17 +03:00
|
|
|
updateHover: function(pageIndex) {
|
|
|
|
if (pageIndex === -1 || this.mode !== 'thumbs') {
|
2015-08-11 18:24:05 +03:00
|
|
|
if (this.hover) {
|
|
|
|
this.hover.style('opacity', 0);
|
|
|
|
}
|
2015-01-21 03:10:24 +03:00
|
|
|
this.$scrollCover.css({
|
2015-01-15 04:09:39 +03:00
|
|
|
'cursor': 'default'
|
|
|
|
});
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-01-21 03:10:24 +03:00
|
|
|
this.$scrollCover.css({
|
2015-01-15 04:09:39 +03:00
|
|
|
'cursor': 'pointer'
|
|
|
|
});
|
|
|
|
|
2015-02-16 21:18:59 +03:00
|
|
|
var page = this.pages[pageIndex];
|
|
|
|
var box = page.getBounds();
|
2015-01-15 04:09:39 +03:00
|
|
|
|
2015-08-11 18:24:05 +03:00
|
|
|
if (this.hover) {
|
|
|
|
this.hover
|
|
|
|
.style('opacity', 0.3)
|
|
|
|
.attr("x", box.x)
|
|
|
|
.attr("width", box.width)
|
|
|
|
.attr("y", box.y)
|
|
|
|
.attr("height", box.height);
|
|
|
|
}
|
2015-01-09 00:22:23 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
// ----------
|
2015-01-16 01:32:42 +03:00
|
|
|
goToPage: function(config) {
|
2015-01-20 22:23:56 +03:00
|
|
|
var self = this;
|
|
|
|
|
2015-02-16 21:18:59 +03:00
|
|
|
var pageCount = this.pages.length;
|
|
|
|
this.pageIndex = Math.max(0, Math.min(pageCount - 1, config.pageIndex));
|
2015-01-09 00:22:23 +03:00
|
|
|
|
2015-01-10 01:04:45 +03:00
|
|
|
var viewerWidth = this.$el.width();
|
|
|
|
var viewerHeight = this.$el.height();
|
2015-02-16 21:18:59 +03:00
|
|
|
var bounds = this.pages[this.pageIndex].getBounds();
|
2015-01-09 00:22:23 +03:00
|
|
|
var x = bounds.x;
|
|
|
|
var y = bounds.y;
|
|
|
|
var width = bounds.width;
|
|
|
|
var height = bounds.height;
|
2015-01-14 02:33:03 +03:00
|
|
|
var box;
|
2015-01-09 00:22:23 +03:00
|
|
|
|
|
|
|
if (this.mode === 'book') {
|
2015-02-16 21:18:59 +03:00
|
|
|
var page;
|
2015-02-14 01:32:17 +03:00
|
|
|
if (this.pageIndex % 2) { // First in a pair
|
|
|
|
if (this.pageIndex < this.pages.length - 1) {
|
2015-02-16 21:18:59 +03:00
|
|
|
page = this.pages[this.pageIndex + 1];
|
|
|
|
width += page.getBounds().width;
|
2015-01-09 00:22:23 +03:00
|
|
|
}
|
|
|
|
} else {
|
2015-02-14 01:32:17 +03:00
|
|
|
if (this.pageIndex > 0) {
|
2015-02-16 21:18:59 +03:00
|
|
|
page = this.pages[this.pageIndex - 1];
|
|
|
|
box = page.getBounds();
|
2015-02-10 22:53:56 +03:00
|
|
|
x -= box.width;
|
2015-01-09 00:22:23 +03:00
|
|
|
width += box.width;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
x -= this.pageBuffer;
|
|
|
|
y -= this.pageBuffer;
|
|
|
|
width += (this.pageBuffer * 2);
|
|
|
|
height += (this.pageBuffer * 2);
|
2015-01-10 01:04:45 +03:00
|
|
|
|
|
|
|
if (this.mode === 'scroll') {
|
2015-02-14 01:32:17 +03:00
|
|
|
if (this.pageIndex === 0) {
|
2015-01-10 02:11:11 +03:00
|
|
|
x = bounds.x - this.pageBuffer;
|
2015-01-10 01:04:45 +03:00
|
|
|
width = height * (viewerWidth / viewerHeight);
|
2015-02-14 01:32:17 +03:00
|
|
|
} else if (this.pageIndex === this.pages.length - 1) {
|
2015-01-10 01:04:45 +03:00
|
|
|
width = height * (viewerWidth / viewerHeight);
|
|
|
|
x = (bounds.x + bounds.width + this.pageBuffer) - width;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-18 20:03:44 +03:00
|
|
|
this.panBounds = null;
|
|
|
|
|
2015-01-14 02:33:03 +03:00
|
|
|
box = new OpenSeadragon.Rect(x, y, width, height);
|
2015-01-16 01:32:42 +03:00
|
|
|
this.viewer.viewport.fitBounds(box, config.immediately);
|
2015-01-14 02:33:03 +03:00
|
|
|
|
2015-01-20 22:23:56 +03:00
|
|
|
var setPanBounds = function() {
|
|
|
|
if (self.mode === 'page' || self.mode === 'book') {
|
|
|
|
self.panBounds = box;
|
|
|
|
} else if (self.mode === 'scroll') {
|
2015-02-16 21:18:59 +03:00
|
|
|
self.panBounds = self.pages[0].getBounds()
|
|
|
|
.union(self.pages[pageCount - 1].getBounds());
|
2015-01-20 22:23:56 +03:00
|
|
|
|
|
|
|
self.panBounds.x -= self.pageBuffer;
|
|
|
|
self.panBounds.y -= self.pageBuffer;
|
|
|
|
self.panBounds.width += (self.pageBuffer * 2);
|
|
|
|
self.panBounds.height += (self.pageBuffer * 2);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-01-24 03:00:58 +03:00
|
|
|
clearTimeout(this.panBoundsTimeout);
|
2015-01-20 22:23:56 +03:00
|
|
|
if (config.immediately) {
|
|
|
|
setPanBounds();
|
|
|
|
} else {
|
2015-01-24 03:00:58 +03:00
|
|
|
this.panBoundsTimeout = setTimeout(setPanBounds, this.viewer.animationTime * 1000);
|
2015-01-14 02:33:03 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
this.viewer.viewport.minZoomLevel = this.viewer.viewport.getZoom();
|
2015-01-09 00:22:23 +03:00
|
|
|
|
|
|
|
this.update();
|
|
|
|
},
|
|
|
|
|
|
|
|
// ----------
|
2015-01-10 00:53:48 +03:00
|
|
|
createLayout: function() {
|
|
|
|
var viewerWidth = this.$el.width();
|
|
|
|
var viewerHeight = this.$el.height();
|
|
|
|
var layoutConfig = {};
|
|
|
|
|
|
|
|
if (this.mode === 'thumbs') {
|
|
|
|
layoutConfig.columns = Math.floor(viewerWidth / 150);
|
|
|
|
layoutConfig.buffer = this.bigBuffer;
|
2015-01-14 03:15:40 +03:00
|
|
|
layoutConfig.sameWidth = true;
|
2015-01-10 00:53:48 +03:00
|
|
|
} else if (this.mode === 'scroll') {
|
|
|
|
layoutConfig.buffer = this.pageBuffer;
|
2015-01-15 02:09:48 +03:00
|
|
|
} else if (this.mode === 'book' || this.mode === 'page') {
|
|
|
|
layoutConfig.book = (this.mode === 'book');
|
|
|
|
var height = 1 + (this.pageBuffer * 2);
|
|
|
|
// Note that using window here is approximate, but that's close enough.
|
|
|
|
// We can't use viewer, because it may be stretched for the thumbs view.
|
|
|
|
layoutConfig.buffer = (height * ($(window).width() / $(window).height())) / 2;
|
2015-01-10 00:53:48 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
var layout = {
|
|
|
|
bounds: null,
|
|
|
|
specs: []
|
|
|
|
};
|
|
|
|
|
2015-02-14 01:32:17 +03:00
|
|
|
var count = this.pages.length;
|
2015-01-09 00:22:23 +03:00
|
|
|
var x = 0;
|
|
|
|
var y = 0;
|
2015-01-14 03:15:40 +03:00
|
|
|
var offset = new OpenSeadragon.Point();
|
|
|
|
var rowHeight = 0;
|
2015-02-16 21:18:59 +03:00
|
|
|
var box, page;
|
2015-01-09 00:22:23 +03:00
|
|
|
for (var i = 0; i < count; i++) {
|
2015-02-14 02:55:57 +03:00
|
|
|
page = this.pages[i];
|
2015-02-16 21:18:59 +03:00
|
|
|
box = page.getBounds();
|
2015-01-14 03:15:40 +03:00
|
|
|
|
2015-02-14 01:32:17 +03:00
|
|
|
if (i === this.pageIndex) {
|
2015-01-14 03:15:40 +03:00
|
|
|
offset = box.getTopLeft().minus(new OpenSeadragon.Point(x, y));
|
|
|
|
}
|
|
|
|
|
|
|
|
box.x = x;
|
|
|
|
box.y = y;
|
|
|
|
if (layoutConfig.sameWidth) {
|
|
|
|
box.height = box.height / box.width;
|
|
|
|
box.width = 1;
|
|
|
|
} else {
|
|
|
|
box.width = box.width / box.height;
|
|
|
|
box.height = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
rowHeight = Math.max(rowHeight, box.height);
|
|
|
|
|
|
|
|
layout.specs.push({
|
2015-02-14 02:55:57 +03:00
|
|
|
page: page,
|
2015-01-14 03:15:40 +03:00
|
|
|
bounds: box
|
|
|
|
});
|
|
|
|
|
2015-01-10 00:53:48 +03:00
|
|
|
if (layoutConfig.columns && i % layoutConfig.columns === layoutConfig.columns - 1) {
|
2015-01-09 00:22:23 +03:00
|
|
|
x = 0;
|
2015-01-14 03:15:40 +03:00
|
|
|
y += rowHeight + layoutConfig.buffer;
|
|
|
|
rowHeight = 0;
|
2015-01-09 00:22:23 +03:00
|
|
|
} else {
|
2015-01-10 00:53:48 +03:00
|
|
|
if (!layoutConfig.book || i % 2 === 0) {
|
|
|
|
x += layoutConfig.buffer;
|
2015-01-09 00:22:23 +03:00
|
|
|
}
|
|
|
|
|
2015-01-14 03:15:40 +03:00
|
|
|
x += box.width;
|
2015-01-09 00:22:23 +03:00
|
|
|
}
|
|
|
|
}
|
2015-01-09 01:04:31 +03:00
|
|
|
|
2015-01-14 03:15:40 +03:00
|
|
|
var pos, spec;
|
2015-01-09 01:04:31 +03:00
|
|
|
for (i = 0; i < count; i++) {
|
2015-01-14 03:15:40 +03:00
|
|
|
spec = layout.specs[i];
|
|
|
|
pos = spec.bounds.getTopLeft().plus(offset);
|
|
|
|
spec.bounds.x = pos.x;
|
|
|
|
spec.bounds.y = pos.y;
|
2015-01-10 00:53:48 +03:00
|
|
|
|
|
|
|
if (layout.bounds) {
|
2015-01-14 03:15:40 +03:00
|
|
|
layout.bounds = layout.bounds.union(spec.bounds);
|
2015-01-10 00:53:48 +03:00
|
|
|
} else {
|
2015-01-14 03:15:40 +03:00
|
|
|
layout.bounds = spec.bounds.clone();
|
2015-01-10 00:53:48 +03:00
|
|
|
}
|
2015-01-09 01:04:31 +03:00
|
|
|
}
|
2015-01-10 00:53:48 +03:00
|
|
|
|
|
|
|
return layout;
|
2015-01-09 00:22:23 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
// ----------
|
2015-01-16 01:32:42 +03:00
|
|
|
setLayout: function(config) {
|
2015-01-10 00:53:48 +03:00
|
|
|
var spec;
|
2015-01-09 00:22:23 +03:00
|
|
|
|
2015-01-16 01:32:42 +03:00
|
|
|
for (var i = 0; i < config.layout.specs.length; i++) {
|
|
|
|
spec = config.layout.specs[i];
|
2015-02-16 21:18:59 +03:00
|
|
|
spec.page.place(spec.bounds, config.immediately);
|
2015-01-10 00:53:48 +03:00
|
|
|
}
|
2015-01-09 00:22:23 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
// ----------
|
2015-01-16 01:32:42 +03:00
|
|
|
goHome: function(config) {
|
2015-01-10 00:53:48 +03:00
|
|
|
var viewerWidth = this.$el.width();
|
|
|
|
var viewerHeight = this.$el.height();
|
|
|
|
var layoutConfig = {};
|
2015-01-09 00:22:23 +03:00
|
|
|
|
2015-01-10 00:53:48 +03:00
|
|
|
if (this.mode === 'thumbs') {
|
2015-01-21 03:10:24 +03:00
|
|
|
var info = this.getScrollInfo();
|
|
|
|
var box = this.thumbBounds.clone();
|
2015-01-10 00:53:48 +03:00
|
|
|
box.height = box.width * (viewerHeight / viewerWidth);
|
2015-01-21 03:10:24 +03:00
|
|
|
box.y += info.viewportMax * info.scrollFactor;
|
2015-01-16 01:32:42 +03:00
|
|
|
this.viewer.viewport.fitBounds(box, config.immediately);
|
2015-01-14 02:33:03 +03:00
|
|
|
} else {
|
2015-01-16 01:32:42 +03:00
|
|
|
this.goToPage({
|
2015-02-14 01:32:17 +03:00
|
|
|
pageIndex: this.pageIndex,
|
2015-01-16 01:32:42 +03:00
|
|
|
immediately: config.immediately
|
|
|
|
});
|
2015-01-10 00:53:48 +03:00
|
|
|
}
|
2015-02-04 21:18:36 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
// ----------
|
2015-02-11 01:02:41 +03:00
|
|
|
createPages: function() {
|
|
|
|
var self = this;
|
|
|
|
|
2015-02-04 21:18:36 +03:00
|
|
|
if (this.tileSources) {
|
|
|
|
return $.map(this.tileSources.slice(0, this.maxImages), function(v, i) {
|
2015-02-11 01:02:41 +03:00
|
|
|
return new self.Page($.extend({
|
|
|
|
pageIndex: i
|
|
|
|
}, v));
|
2015-02-04 21:18:36 +03:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2015-02-16 21:45:46 +03:00
|
|
|
var highsmith = {
|
|
|
|
Image: {
|
|
|
|
xmlns: "http://schemas.microsoft.com/deepzoom/2008",
|
|
|
|
Url: "http://openseadragon.github.io/example-images/highsmith/highsmith_files/",
|
|
|
|
Format: "jpg",
|
|
|
|
Overlap: "2",
|
|
|
|
TileSize: "256",
|
|
|
|
Size: {
|
|
|
|
Width: "7026",
|
|
|
|
Height: "9221"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
var duomo = {
|
|
|
|
Image: {
|
|
|
|
xmlns: "http://schemas.microsoft.com/deepzoom/2008",
|
|
|
|
Url: "http://openseadragon.github.io/example-images/duomo/duomo_files/",
|
|
|
|
Format: "jpg",
|
|
|
|
Overlap: "2",
|
|
|
|
TileSize: "256",
|
|
|
|
Size: {
|
|
|
|
Width: "13920",
|
|
|
|
Height: "10200"
|
2015-02-04 21:18:36 +03:00
|
|
|
}
|
2015-02-16 21:45:46 +03:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
var tall = {
|
|
|
|
Image: {
|
|
|
|
xmlns: "http://schemas.microsoft.com/deepzoom/2008",
|
|
|
|
Url: "../../data/tall_files/",
|
|
|
|
Format: "jpg",
|
|
|
|
Overlap: "1",
|
|
|
|
TileSize: "254",
|
|
|
|
Size: {
|
|
|
|
Width: "500",
|
|
|
|
Height: "2000"
|
2015-02-04 21:18:36 +03:00
|
|
|
}
|
2015-02-16 21:45:46 +03:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
var wide = {
|
|
|
|
Image: {
|
|
|
|
xmlns: "http://schemas.microsoft.com/deepzoom/2008",
|
|
|
|
Url: "../../data/wide_files/",
|
|
|
|
Format: "jpg",
|
|
|
|
Overlap: "1",
|
|
|
|
TileSize: "254",
|
|
|
|
Size: {
|
|
|
|
Width: "2000",
|
|
|
|
Height: "500"
|
2015-02-04 21:18:36 +03:00
|
|
|
}
|
|
|
|
}
|
2015-02-16 21:45:46 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
var testpattern = {
|
|
|
|
Image: {
|
|
|
|
xmlns: "http://schemas.microsoft.com/deepzoom/2008",
|
|
|
|
Url: "../../data/testpattern_files/",
|
|
|
|
Format: "jpg",
|
|
|
|
Overlap: "1",
|
|
|
|
TileSize: "254",
|
|
|
|
Size: {
|
|
|
|
Width: "1000",
|
|
|
|
Height: "1000"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2015-02-04 21:18:36 +03:00
|
|
|
|
2015-02-11 01:02:41 +03:00
|
|
|
var pages = [];
|
2015-02-16 21:45:46 +03:00
|
|
|
|
|
|
|
pages.push(new this.Page({
|
|
|
|
masterWidth: 7026,
|
|
|
|
masterHeight: 9221,
|
|
|
|
x: 0,
|
|
|
|
y: 0,
|
|
|
|
width: 1,
|
|
|
|
label: 'highsmith',
|
|
|
|
tileSource: highsmith,
|
|
|
|
alternates: [
|
|
|
|
{
|
|
|
|
x: 0,
|
|
|
|
y: 0.55,
|
|
|
|
width: 1,
|
|
|
|
label: 'duomo',
|
|
|
|
tileSource: duomo
|
|
|
|
},
|
|
|
|
{
|
|
|
|
x: 0.7,
|
|
|
|
y: 0,
|
|
|
|
width: 0.3,
|
|
|
|
label: 'tall',
|
|
|
|
tileSource: tall
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}));
|
|
|
|
|
|
|
|
pages.push(new this.Page({
|
|
|
|
tileSource: highsmith,
|
|
|
|
details: [
|
|
|
|
{
|
|
|
|
x: 0.25,
|
|
|
|
y: 0.15,
|
|
|
|
width: 0.5,
|
|
|
|
tileSource: testpattern
|
|
|
|
},
|
|
|
|
{
|
|
|
|
x: 0.25,
|
|
|
|
y: 0.8,
|
|
|
|
width: 0.5,
|
|
|
|
tileSource: wide
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}));
|
|
|
|
|
2015-03-20 20:17:27 +03:00
|
|
|
pages.push(new this.Page({
|
|
|
|
tileSource: highsmith,
|
|
|
|
clip: {
|
|
|
|
x: 1000,
|
|
|
|
y: 1000,
|
|
|
|
width: 5026,
|
|
|
|
height: 7221
|
|
|
|
}
|
|
|
|
}));
|
|
|
|
|
2015-02-16 21:45:46 +03:00
|
|
|
var inputs = [
|
|
|
|
highsmith,
|
|
|
|
duomo,
|
|
|
|
testpattern
|
|
|
|
];
|
|
|
|
|
2015-02-04 21:18:36 +03:00
|
|
|
for (var i = 0; i < this.maxImages; i++) {
|
2015-02-11 01:02:41 +03:00
|
|
|
pages.push(new this.Page({
|
|
|
|
pageIndex: i,
|
|
|
|
tileSource: inputs[Math.floor(Math.random() * inputs.length)]
|
|
|
|
}));
|
2015-02-04 21:18:36 +03:00
|
|
|
}
|
|
|
|
|
2015-02-11 01:02:41 +03:00
|
|
|
return pages;
|
2015-01-09 00:22:23 +03:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// ----------
|
|
|
|
$(document).ready(function() {
|
|
|
|
App.init();
|
|
|
|
});
|
|
|
|
})();
|