Refactored how scrolling works (m2)

This commit is contained in:
Ian Gilman 2015-01-20 16:10:24 -08:00
parent 2b9a51036f
commit ec2e4a4e8f
3 changed files with 126 additions and 66 deletions

View File

@ -1,5 +1,4 @@
# To Do # To Do
* When going to thumbs, scroll to the proper part of the page
* Support 400+ page collections * Support 400+ page collections
* Show/hide pages? * Show/hide pages?

View File

@ -43,7 +43,7 @@
background: white; background: white;
} }
.openseadragon1.full { .viewer-position {
position: absolute; position: absolute;
left: 0; left: 0;
top: 30px; top: 30px;
@ -51,7 +51,10 @@
bottom: 0; bottom: 0;
} }
.openseadragon1.thumbs { .scroll-cover {
display: none;
overflow: scroll;
z-index: 100;
} }
</style> </style>
@ -67,6 +70,9 @@
<button class="next">Next</button> <button class="next">Next</button>
</div> </div>
</div> </div>
<div id="contentDiv" class="openseadragon1"></div> <div id="contentDiv" class="openseadragon1 viewer-position"></div>
<div class="scroll-cover viewer-position">
<div class="scroll-inner"></div>
</div>
</body> </body>
</html> </html>

View File

@ -20,6 +20,25 @@
'page' 'page'
]; ];
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: {
Height: "9221",
Width: "7026"
}
}
};
// this.tileSources = [];
// for (var i = 0; i < count; i++) {
// this.tileSources.push(highsmith);
// }
this.viewer = OpenSeadragon({ this.viewer = OpenSeadragon({
id: "contentDiv", id: "contentDiv",
prefixUrl: "../../../build/openseadragon/images/", prefixUrl: "../../../build/openseadragon/images/",
@ -37,21 +56,6 @@
}); });
}); });
this.viewer.addHandler('canvas-click', function(event) {
if (self.mode !== 'thumbs' || !event.quick) {
return;
}
var pos = self.viewer.viewport.pointFromPixel(event.position);
var result = self.hitTest(pos);
if (result) {
self.setMode({
mode: 'page',
page: result.index
});
}
});
this.viewer.addHandler('canvas-drag', function() { this.viewer.addHandler('canvas-drag', function() {
if (this.mode === 'scroll') { if (this.mode === 'scroll') {
var result = this.hitTest(this.viewer.viewport.getCenter()); var result = this.hitTest(this.viewer.viewport.getCenter());
@ -65,18 +69,6 @@
self.applyConstraints(); self.applyConstraints();
}); });
var tracker = new OpenSeadragon.MouseTracker({
element: this.viewer.container,
moveHandler: function(event) {
if (self.mode === 'thumbs') {
var result = self.hitTest(self.viewer.viewport.pointFromPixel(event.position));
self.updateHover(result ? result.index : -1);
}
}
});
tracker.setTracking(true);
$.each(this.modeNames, function(i, v) { $.each(this.modeNames, function(i, v) {
$('.' + v).click(function() { $('.' + v).click(function() {
self.setMode({ self.setMode({
@ -105,6 +97,37 @@
} }
}); });
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);
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);
var result = self.hitTest(self.viewer.viewport.pointFromPixel(pixel));
if (result) {
self.setMode({
mode: 'page',
page: result.index
});
}
});
var svgNode = this.viewer.svgOverlay(); var svgNode = this.viewer.svgOverlay();
this.highlight = d3.select(svgNode).append("rect") this.highlight = d3.select(svgNode).append("rect")
@ -179,6 +202,26 @@
return null; return null;
}, },
// ----------
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;
},
// ---------- // ----------
update: function() { update: function() {
var self = this; var self = this;
@ -237,13 +280,10 @@
this.page = config.page; // Need to do this before layout this.page = config.page; // Need to do this before layout
} }
var layout = this.createLayout(); this.ignoreScroll = true;
this.thumbBounds = null;
var oldSize = new OpenSeadragon.Point(this.$el.width(), this.$el.height()); var layout = this.createLayout();
var oldBounds = this.viewer.viewport.getBounds();
var scrollTop = $(window).scrollTop();
var scrollMax = $(document).height() - $(window).height();
var scrollFactor = (scrollMax > 0 ? scrollTop / scrollMax : 0);
if (this.mode === 'thumbs') { if (this.mode === 'thumbs') {
this.viewer.gestureSettingsMouse.scrollToZoom = false; this.viewer.gestureSettingsMouse.scrollToZoom = false;
@ -254,9 +294,8 @@
var width = layout.bounds.width + (this.bigBuffer * 2); var width = layout.bounds.width + (this.bigBuffer * 2);
var height = layout.bounds.height + (this.bigBuffer * 2); var height = layout.bounds.height + (this.bigBuffer * 2);
var newHeight = viewerWidth * (height / width); var newHeight = viewerWidth * (height / width);
this.$el this.$scrollCover.show();
.addClass('thumbs') this.$scrollInner
.removeClass('full')
.css({ .css({
height: newHeight height: newHeight
}); });
@ -265,25 +304,7 @@
this.viewer.zoomPerClick = 2; this.viewer.zoomPerClick = 2;
this.viewer.panHorizontal = true; this.viewer.panHorizontal = true;
this.viewer.panVertical = true; this.viewer.panVertical = true;
this.$el this.$scrollCover.hide();
.addClass('full')
.removeClass('thumbs')
.css({
height: 'auto'
});
}
var newSize = new OpenSeadragon.Point(this.$el.width(), this.$el.height());
if (oldSize.x !== newSize.x || oldSize.y !== newSize.y) {
this.viewer.viewport.resize(newSize, false);
var newBounds = this.viewer.viewport.getBounds();
var box = oldBounds.clone();
box.height = box.width * (newBounds.height / newBounds.width);
var boxMax = oldBounds.height - box.height;
box.y += boxMax * scrollFactor;
this.viewer.viewport.fitBounds(box, true);
this.viewer.viewport.update();
} }
this.setLayout({ this.setLayout({
@ -291,6 +312,38 @@
immediately: config.immediately immediately: config.immediately
}); });
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;
var itemBounds = this.viewer.world.getItemAt(this.page).getBounds();
var top = itemBounds.y - this.bigBuffer;
var bottom = top + itemBounds.height + (this.bigBuffer * 2);
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);
}
}
this.goHome({ this.goHome({
immediately: config.immediately immediately: config.immediately
}); });
@ -300,6 +353,10 @@
this.update(); this.update();
this.updateHighlight(); this.updateHighlight();
this.updateHover(-1); this.updateHover(-1);
setTimeout(function() {
self.ignoreScroll = false;
}, this.viewer.animationTime * 1000);
}, },
// ---------- // ----------
@ -324,14 +381,14 @@
updateHover: function(page) { updateHover: function(page) {
if (page === -1 || this.mode !== 'thumbs') { if (page === -1 || this.mode !== 'thumbs') {
this.hover.style('opacity', 0); this.hover.style('opacity', 0);
this.$el.css({ this.$scrollCover.css({
'cursor': 'default' 'cursor': 'default'
}); });
return; return;
} }
this.$el.css({ this.$scrollCover.css({
'cursor': 'pointer' 'cursor': 'pointer'
}); });
@ -527,13 +584,11 @@
var viewerHeight = this.$el.height(); var viewerHeight = this.$el.height();
var layoutConfig = {}; var layoutConfig = {};
var box;
if (this.mode === 'thumbs') { if (this.mode === 'thumbs') {
box = this.viewer.world.getHomeBounds(); var info = this.getScrollInfo();
box.x -= this.bigBuffer; var box = this.thumbBounds.clone();
box.y -= this.bigBuffer;
box.width += (this.bigBuffer * 2);
box.height = box.width * (viewerHeight / viewerWidth); box.height = box.width * (viewerHeight / viewerWidth);
box.y += info.viewportMax * info.scrollFactor;
this.viewer.viewport.fitBounds(box, config.immediately); this.viewer.viewport.fitBounds(box, config.immediately);
} else { } else {
this.goToPage({ this.goToPage({