mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-21 20:56:09 +03:00
commit
425d78ddb4
@ -39,7 +39,14 @@ OPENSEADRAGON CHANGELOG
|
||||
* Rect and Point toString() functions are now consistent: rounding values to nearest hundredth
|
||||
* Overlays appear in the DOM immediately on open or addOverlay (#507)
|
||||
* imageLoaderLimit now works (#544)
|
||||
* Turning off scrollToZoom in gestureSettings now allows scroll events to propagate
|
||||
* You can now set a minZoomLevel that's greater than the home zoom level
|
||||
* Added union() to OpenSeadragon.Rect
|
||||
* Fixed an error in fitBounds if the new and old bounds were extremely close in size
|
||||
* Added ajaxWithCredentials option (#543)
|
||||
* Added viewport-change event for after the viewport changes but before it's drawn
|
||||
* A spring's current value is now updated immediately on reset (#524)
|
||||
* Fixed an error in fitBounds that occurred sometimes with immediately = true
|
||||
* Added support for HDPI (retina) displays (#583)
|
||||
|
||||
1.2.2: (in progress)
|
||||
|
@ -201,6 +201,21 @@ $.Rect.prototype = /** @lends OpenSeadragon.Rect.prototype */{
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the smallest rectangle that will contain this and the given rectangle.
|
||||
* @param {OpenSeadragon.Rect} rect
|
||||
* @return {OpenSeadragon.Rect} The new rectangle.
|
||||
*/
|
||||
// ----------
|
||||
union: function(rect) {
|
||||
var left = Math.min(this.x, rect.x);
|
||||
var top = Math.min(this.y, rect.y);
|
||||
var right = Math.max(this.x + this.width, rect.x + rect.width);
|
||||
var bottom = Math.max(this.y + this.height, rect.y + rect.height);
|
||||
|
||||
return new OpenSeadragon.Rect(left, top, right - left, bottom - top);
|
||||
},
|
||||
|
||||
/**
|
||||
* Rotates a rectangle around a point. Currently only 90, 180, and 270
|
||||
* degrees are supported.
|
||||
|
@ -117,10 +117,8 @@ $.Spring.prototype = /** @lends OpenSeadragon.Spring.prototype */{
|
||||
* @param {Number} target
|
||||
*/
|
||||
resetTo: function( target ) {
|
||||
this.target.value = target;
|
||||
this.target.time = this.current.time;
|
||||
this.start.value = this.target.value;
|
||||
this.start.time = this.target.time;
|
||||
this.start.value = this.target.value = this.current.value = target;
|
||||
this.start.time = this.target.time = this.current.time = $.now();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -409,8 +409,6 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
||||
|
||||
this._xSpring.resetTo(position.x);
|
||||
this._ySpring.resetTo(position.y);
|
||||
this._xSpring.update();
|
||||
this._ySpring.update();
|
||||
} else {
|
||||
if (sameTarget) {
|
||||
return;
|
||||
@ -454,7 +452,6 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
||||
}
|
||||
|
||||
this._scaleSpring.resetTo(scale);
|
||||
this._scaleSpring.update();
|
||||
this._updateForScale();
|
||||
} else {
|
||||
if (sameTarget) {
|
||||
|
@ -2703,8 +2703,11 @@ function onCanvasScroll( event ) {
|
||||
shift: event.shift,
|
||||
originalEvent: event.originalEvent
|
||||
});
|
||||
//cancels event
|
||||
return false;
|
||||
|
||||
if (gestureSettings && gestureSettings.scrollToZoom) {
|
||||
//cancels event
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function onContainerEnter( event ) {
|
||||
@ -2789,13 +2792,10 @@ function updateMulti( viewer ) {
|
||||
|
||||
function updateOnce( viewer ) {
|
||||
|
||||
var containerSize,
|
||||
animated;
|
||||
|
||||
//viewer.profiler.beginUpdate();
|
||||
|
||||
if ( viewer.autoResize ) {
|
||||
containerSize = _getSafeElemSize( viewer.container );
|
||||
var containerSize = _getSafeElemSize( viewer.container );
|
||||
if ( !containerSize.equals( THIS[ viewer.hash ].prevContainerSize ) ) {
|
||||
// maintain image position
|
||||
var oldBounds = viewer.viewport.getBounds();
|
||||
@ -2806,8 +2806,22 @@ function updateOnce( viewer ) {
|
||||
}
|
||||
}
|
||||
|
||||
animated = viewer.viewport.update();
|
||||
animated = viewer.world.update() || animated;
|
||||
var viewportChange = viewer.viewport.update();
|
||||
var animated = viewer.world.update() || viewportChange;
|
||||
|
||||
if (viewportChange) {
|
||||
/**
|
||||
* Raised when any spring animation update occurs (zoom, pan, etc.),
|
||||
* before the viewer has drawn the new location.
|
||||
*
|
||||
* @event viewport-change
|
||||
* @memberof OpenSeadragon.Viewer
|
||||
* @type {object}
|
||||
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.
|
||||
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||
*/
|
||||
viewer.raiseEvent('viewport-change');
|
||||
}
|
||||
|
||||
if( viewer.referenceStrip ){
|
||||
animated = viewer.referenceStrip.update( viewer.viewport ) || animated;
|
||||
@ -2838,7 +2852,8 @@ function updateOnce( viewer ) {
|
||||
|
||||
if (animated) {
|
||||
/**
|
||||
* Raised when any spring animation update occurs (zoom, pan, etc.).
|
||||
* Raised when any spring animation update occurs (zoom, pan, etc.),
|
||||
* after the viewer has drawn the new location.
|
||||
*
|
||||
* @event animation
|
||||
* @memberof OpenSeadragon.Viewer
|
||||
|
@ -132,6 +132,10 @@ $.Viewport = function( options ) {
|
||||
animationTime: this.animationTime
|
||||
});
|
||||
|
||||
this._oldCenterX = this.centerSpringX.current.value;
|
||||
this._oldCenterY = this.centerSpringY.current.value;
|
||||
this._oldZoom = this.zoomSpring.current.value;
|
||||
|
||||
if (this.contentSize) {
|
||||
this.resetContentSize( this.contentSize );
|
||||
} else {
|
||||
@ -275,7 +279,7 @@ $.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{
|
||||
this.minZoomLevel :
|
||||
this.minZoomImageRatio * homeZoom;
|
||||
|
||||
return Math.min( zoom, homeZoom );
|
||||
return zoom;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -584,10 +588,17 @@ $.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{
|
||||
}
|
||||
|
||||
newBounds = this._applyBoundaryConstraints( newBounds, immediately );
|
||||
center = newBounds.getCenter();
|
||||
}
|
||||
|
||||
if ( newZoom == oldZoom || newBounds.width == oldBounds.width ) {
|
||||
return this.panTo( constraints ? newBounds.getCenter() : center, immediately );
|
||||
if (immediately) {
|
||||
this.panTo( center, true );
|
||||
return this.zoomTo(newZoom, null, true);
|
||||
}
|
||||
|
||||
if (Math.abs(newZoom - oldZoom) < 0.00000000001 ||
|
||||
Math.abs(newBounds.width - oldBounds.width) < 0.00000000001) {
|
||||
return this.panTo( center, immediately );
|
||||
}
|
||||
|
||||
referencePoint = oldBounds.getTopLeft().times(
|
||||
@ -855,10 +866,7 @@ $.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{
|
||||
* @function
|
||||
*/
|
||||
update: function() {
|
||||
var oldCenterX = this.centerSpringX.current.value,
|
||||
oldCenterY = this.centerSpringY.current.value,
|
||||
oldZoom = this.zoomSpring.current.value,
|
||||
oldZoomPixel,
|
||||
var oldZoomPixel,
|
||||
newZoomPixel,
|
||||
deltaZoomPixels,
|
||||
deltaZoomPoints;
|
||||
@ -869,7 +877,7 @@ $.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{
|
||||
|
||||
this.zoomSpring.update();
|
||||
|
||||
if (this.zoomPoint && this.zoomSpring.current.value != oldZoom) {
|
||||
if (this.zoomPoint && this.zoomSpring.current.value != this._oldZoom) {
|
||||
newZoomPixel = this.pixelFromPoint( this.zoomPoint, true );
|
||||
deltaZoomPixels = newZoomPixel.minus( oldZoomPixel );
|
||||
deltaZoomPoints = this.deltaPointsFromPixels( deltaZoomPixels, true );
|
||||
@ -883,9 +891,15 @@ $.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{
|
||||
this.centerSpringX.update();
|
||||
this.centerSpringY.update();
|
||||
|
||||
return this.centerSpringX.current.value != oldCenterX ||
|
||||
this.centerSpringY.current.value != oldCenterY ||
|
||||
this.zoomSpring.current.value != oldZoom;
|
||||
var changed = this.centerSpringX.current.value != this._oldCenterX ||
|
||||
this.centerSpringY.current.value != this._oldCenterY ||
|
||||
this.zoomSpring.current.value != this._oldZoom;
|
||||
|
||||
this._oldCenterX = this.centerSpringX.current.value;
|
||||
this._oldCenterY = this.centerSpringY.current.value;
|
||||
this._oldZoom = this.zoomSpring.current.value;
|
||||
|
||||
return changed;
|
||||
},
|
||||
|
||||
|
||||
|
20
test/demo/m2/README.md
Normal file
20
test/demo/m2/README.md
Normal file
@ -0,0 +1,20 @@
|
||||
# M2 Demo
|
||||
|
||||
This is an advanced demo/testbed, for proposed improvements to the new version of the Mirador project:
|
||||
|
||||
https://github.com/IIIF/m2/
|
||||
|
||||
You can see a previous version of Mirador here:
|
||||
|
||||
http://showcase.iiif.io/viewer/mirador/
|
||||
|
||||
## To Do
|
||||
|
||||
* Choosing between multiple versions of a page
|
||||
* Detail images overlaid on the page
|
||||
* Cropped images
|
||||
|
||||
### Maybe
|
||||
|
||||
* Show/hide pages?
|
||||
* Lazyloading tilesources?
|
78
test/demo/m2/index.html
Normal file
78
test/demo/m2/index.html
Normal file
@ -0,0 +1,78 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Mirador POC</title>
|
||||
<script type="text/javascript" src='../../../build/openseadragon/openseadragon.js'></script>
|
||||
<script type="text/javascript" src='../../lib/jquery-1.9.1.min.js'></script>
|
||||
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
|
||||
<script src="js/main.js"></script>
|
||||
<!-- <script src="js/harvard-tilesources.js"></script> -->
|
||||
<script src="js/openseadragon-svg-overlay.js"></script>
|
||||
<style type="text/css">
|
||||
|
||||
html,
|
||||
body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #eee;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.header {
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.nav {
|
||||
display: inline-block;
|
||||
margin-left: 50px;
|
||||
}
|
||||
|
||||
.active {
|
||||
background: #ddf;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.openseadragon1 {
|
||||
background: white;
|
||||
}
|
||||
|
||||
.viewer-position {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 30px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.scroll-cover {
|
||||
display: none;
|
||||
overflow: scroll;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<button class="thumbs">Thumbnails</button>
|
||||
<button class="scroll">Scroll</button>
|
||||
<button class="book">Book</button>
|
||||
<button class="page">Page</button>
|
||||
<div class="nav">
|
||||
<button class="previous">Previous</button>
|
||||
<button class="next">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="contentDiv" class="openseadragon1 viewer-position"></div>
|
||||
<div class="scroll-cover viewer-position">
|
||||
<div class="scroll-inner"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
1
test/demo/m2/js/.gitignore
vendored
Normal file
1
test/demo/m2/js/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
harvard-tilesources.js
|
670
test/demo/m2/js/main.js
Normal file
670
test/demo/m2/js/main.js
Normal file
@ -0,0 +1,670 @@
|
||||
/* globals $, App, d3 */
|
||||
|
||||
(function() {
|
||||
// ----------
|
||||
window.App = {
|
||||
// ----------
|
||||
init: function() {
|
||||
var self = this;
|
||||
|
||||
this.maxImages = 500;
|
||||
this.mode = 'none';
|
||||
this.pageBuffer = 0.05;
|
||||
this.bigBuffer = 0.2;
|
||||
this.page = 0;
|
||||
this.modeNames = [
|
||||
'thumbs',
|
||||
'scroll',
|
||||
'book',
|
||||
'page'
|
||||
];
|
||||
|
||||
this.viewer = OpenSeadragon({
|
||||
id: "contentDiv",
|
||||
prefixUrl: "../../../build/openseadragon/images/",
|
||||
autoResize: false,
|
||||
showHomeControl: false,
|
||||
tileSources: this.getTileSources()
|
||||
});
|
||||
|
||||
this.viewer.addHandler('open', function() {
|
||||
self.$el = $(self.viewer.element);
|
||||
self.setMode({
|
||||
mode: 'thumbs',
|
||||
immediately: true
|
||||
});
|
||||
});
|
||||
|
||||
this.viewer.addHandler('canvas-drag', function() {
|
||||
if (self.mode === 'scroll') {
|
||||
var result = self.hitTest(self.viewer.viewport.getCenter());
|
||||
if (result) {
|
||||
self.page = result.index;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.viewer.addHandler('viewport-change', function(event) {
|
||||
self.applyConstraints();
|
||||
});
|
||||
|
||||
$.each(this.modeNames, function(i, v) {
|
||||
$('.' + v).click(function() {
|
||||
self.setMode({
|
||||
mode: v
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
$('.next').click(function() {
|
||||
self.next();
|
||||
});
|
||||
|
||||
$('.previous').click(function() {
|
||||
self.previous();
|
||||
});
|
||||
|
||||
$(window).keyup(function(event) {
|
||||
if (self.mode === 'thumbs') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.which === 39) { // Right arrow
|
||||
self.next();
|
||||
} else if (event.which === 37) { // Left arrow
|
||||
self.previous();
|
||||
}
|
||||
});
|
||||
|
||||
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();
|
||||
|
||||
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() {
|
||||
var newSize = new OpenSeadragon.Point(self.$el.width(), self.$el.height());
|
||||
self.viewer.viewport.resize(newSize, false);
|
||||
self.setMode({
|
||||
mode: self.mode,
|
||||
immediately: true
|
||||
});
|
||||
|
||||
self.viewer.forceRedraw();
|
||||
|
||||
self.viewer.svgOverlay('resize');
|
||||
});
|
||||
|
||||
this.update();
|
||||
},
|
||||
|
||||
// ----------
|
||||
next: function() {
|
||||
var page = this.page + (this.mode === 'book' ? 2 : 1);
|
||||
if (this.mode === 'book' && page % 2 === 0 && page !== 0) {
|
||||
page --;
|
||||
}
|
||||
|
||||
this.goToPage({
|
||||
page: page
|
||||
});
|
||||
},
|
||||
|
||||
// ----------
|
||||
previous: function() {
|
||||
var page = this.page - (this.mode === 'book' ? 2 : 1);
|
||||
if (this.mode === 'book' && page % 2 === 0 && page !== 0) {
|
||||
page --;
|
||||
}
|
||||
|
||||
this.goToPage({
|
||||
page: page
|
||||
});
|
||||
},
|
||||
|
||||
// ----------
|
||||
hitTest: function(pos) {
|
||||
var count = this.viewer.world.getItemCount();
|
||||
var item, box;
|
||||
|
||||
for (var i = 0; i < count; i++) {
|
||||
item = this.viewer.world.getItemAt(i);
|
||||
box = item.getBounds();
|
||||
if (pos.x > box.x && pos.y > box.y && pos.x < box.x + box.width &&
|
||||
pos.y < box.y + box.height) {
|
||||
return {
|
||||
item: item,
|
||||
index: i
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
var self = this;
|
||||
|
||||
$('.nav').toggle(this.mode === 'scroll' || this.mode === 'book' || this.mode === 'page');
|
||||
$('.previous').toggleClass('hidden', this.page <= 0);
|
||||
$('.next').toggleClass('hidden', this.page >= this.viewer.world.getItemCount() - 1);
|
||||
|
||||
$.each(this.modeNames, function(i, v) {
|
||||
$('.' + v).toggleClass('active', v === self.mode);
|
||||
});
|
||||
},
|
||||
|
||||
// ----------
|
||||
applyConstraints: function() {
|
||||
if (this.mode === 'thumbs') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.panBounds) {
|
||||
var center = this.viewer.viewport.getCenter(true);
|
||||
var viewBounds = this.viewer.viewport.getBounds(true);
|
||||
var bounds = this.panBounds.clone();
|
||||
var left = bounds.x + (viewBounds.width / 2);
|
||||
var top = bounds.y + (viewBounds.height / 2);
|
||||
var right = (bounds.x + bounds.width) - (viewBounds.width / 2);
|
||||
var bottom = (bounds.y + bounds.height) - (viewBounds.height / 2);
|
||||
|
||||
var x;
|
||||
if (left <= right) {
|
||||
x = Math.max(left, Math.min(right, center.x));
|
||||
} else {
|
||||
x = bounds.x + (bounds.width / 2);
|
||||
}
|
||||
|
||||
var y;
|
||||
if (top <= bottom) {
|
||||
y = Math.max(top, Math.min(bottom, center.y));
|
||||
} else {
|
||||
y = bounds.y + (bounds.height / 2);
|
||||
}
|
||||
|
||||
if (x !== center.x || y !== center.y) {
|
||||
this.viewer.viewport.centerSpringX.current.value = x;
|
||||
this.viewer.viewport.centerSpringY.current.value = y;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// ----------
|
||||
setMode: function(config) {
|
||||
var self = this;
|
||||
|
||||
this.mode = config.mode;
|
||||
|
||||
if (config.page !== undefined) {
|
||||
this.page = config.page; // Need to do this before layout
|
||||
}
|
||||
|
||||
this.ignoreScroll = true;
|
||||
this.thumbBounds = null;
|
||||
|
||||
var layout = this.createLayout();
|
||||
|
||||
if (this.mode === 'thumbs') {
|
||||
this.viewer.gestureSettingsMouse.scrollToZoom = false;
|
||||
this.viewer.zoomPerClick = 1;
|
||||
this.viewer.panHorizontal = false;
|
||||
this.viewer.panVertical = false;
|
||||
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);
|
||||
this.$scrollCover.show();
|
||||
this.$scrollInner
|
||||
.css({
|
||||
height: newHeight
|
||||
});
|
||||
} else {
|
||||
this.viewer.gestureSettingsMouse.scrollToZoom = true;
|
||||
this.viewer.zoomPerClick = 2;
|
||||
this.viewer.panHorizontal = true;
|
||||
this.viewer.panVertical = true;
|
||||
this.$scrollCover.hide();
|
||||
}
|
||||
|
||||
this.setLayout({
|
||||
layout: layout,
|
||||
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({
|
||||
immediately: config.immediately
|
||||
});
|
||||
|
||||
this.viewer.viewport.minZoomLevel = this.viewer.viewport.getZoom();
|
||||
|
||||
this.update();
|
||||
this.updateHighlight();
|
||||
this.updateHover(-1);
|
||||
|
||||
clearTimeout(this.scrollTimeout);
|
||||
this.scrollTimeout = setTimeout(function() {
|
||||
self.ignoreScroll = false;
|
||||
}, this.viewer.animationTime * 1000);
|
||||
},
|
||||
|
||||
// ----------
|
||||
updateHighlight: function() {
|
||||
if (this.mode !== 'thumbs') {
|
||||
this.highlight.style('opacity', 0);
|
||||
return;
|
||||
}
|
||||
|
||||
var item = this.viewer.world.getItemAt(this.page);
|
||||
var box = item.getBounds();
|
||||
|
||||
this.highlight
|
||||
.style('opacity', 1)
|
||||
.attr("x", box.x)
|
||||
.attr("width", box.width)
|
||||
.attr("y", box.y)
|
||||
.attr("height", box.height);
|
||||
},
|
||||
|
||||
// ----------
|
||||
updateHover: function(page) {
|
||||
if (page === -1 || this.mode !== 'thumbs') {
|
||||
this.hover.style('opacity', 0);
|
||||
this.$scrollCover.css({
|
||||
'cursor': 'default'
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.$scrollCover.css({
|
||||
'cursor': 'pointer'
|
||||
});
|
||||
|
||||
var item = this.viewer.world.getItemAt(page);
|
||||
var box = item.getBounds();
|
||||
|
||||
this.hover
|
||||
.style('opacity', 0.3)
|
||||
.attr("x", box.x)
|
||||
.attr("width", box.width)
|
||||
.attr("y", box.y)
|
||||
.attr("height", box.height);
|
||||
},
|
||||
|
||||
// ----------
|
||||
goToPage: function(config) {
|
||||
var self = this;
|
||||
|
||||
var itemCount = this.viewer.world.getItemCount();
|
||||
this.page = Math.max(0, Math.min(itemCount - 1, config.page));
|
||||
|
||||
var viewerWidth = this.$el.width();
|
||||
var viewerHeight = this.$el.height();
|
||||
var bounds = this.viewer.world.getItemAt(this.page).getBounds();
|
||||
var x = bounds.x;
|
||||
var y = bounds.y;
|
||||
var width = bounds.width;
|
||||
var height = bounds.height;
|
||||
var box;
|
||||
|
||||
if (this.mode === 'book') {
|
||||
var item;
|
||||
if (this.page % 2) { // First in a pair
|
||||
item = this.viewer.world.getItemAt(this.page + 1);
|
||||
if (item) {
|
||||
width += item.getBounds().width;
|
||||
}
|
||||
} else {
|
||||
item = this.viewer.world.getItemAt(this.page - 1);
|
||||
if (item) {
|
||||
box = item.getBounds();
|
||||
x -= width;
|
||||
width += box.width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x -= this.pageBuffer;
|
||||
y -= this.pageBuffer;
|
||||
width += (this.pageBuffer * 2);
|
||||
height += (this.pageBuffer * 2);
|
||||
|
||||
if (this.mode === 'scroll') {
|
||||
if (this.page === 0) {
|
||||
x = bounds.x - this.pageBuffer;
|
||||
width = height * (viewerWidth / viewerHeight);
|
||||
} else if (this.page === this.viewer.world.getItemCount() - 1) {
|
||||
width = height * (viewerWidth / viewerHeight);
|
||||
x = (bounds.x + bounds.width + this.pageBuffer) - width;
|
||||
}
|
||||
}
|
||||
|
||||
box = new OpenSeadragon.Rect(x, y, width, height);
|
||||
this.viewer.viewport.fitBounds(box, config.immediately);
|
||||
|
||||
this.panBounds = null;
|
||||
|
||||
var setPanBounds = function() {
|
||||
if (self.mode === 'page' || self.mode === 'book') {
|
||||
self.panBounds = box;
|
||||
} else if (self.mode === 'scroll') {
|
||||
self.panBounds = self.viewer.world.getItemAt(0).getBounds()
|
||||
.union(self.viewer.world.getItemAt(itemCount - 1).getBounds());
|
||||
|
||||
self.panBounds.x -= self.pageBuffer;
|
||||
self.panBounds.y -= self.pageBuffer;
|
||||
self.panBounds.width += (self.pageBuffer * 2);
|
||||
self.panBounds.height += (self.pageBuffer * 2);
|
||||
}
|
||||
};
|
||||
|
||||
clearTimeout(this.panBoundsTimeout);
|
||||
if (config.immediately) {
|
||||
setPanBounds();
|
||||
} else {
|
||||
this.panBoundsTimeout = setTimeout(setPanBounds, this.viewer.animationTime * 1000);
|
||||
}
|
||||
|
||||
this.viewer.viewport.minZoomLevel = this.viewer.viewport.getZoom();
|
||||
|
||||
this.update();
|
||||
},
|
||||
|
||||
// ----------
|
||||
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;
|
||||
layoutConfig.sameWidth = true;
|
||||
} else if (this.mode === 'scroll') {
|
||||
layoutConfig.buffer = this.pageBuffer;
|
||||
} 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;
|
||||
}
|
||||
|
||||
var layout = {
|
||||
bounds: null,
|
||||
specs: []
|
||||
};
|
||||
|
||||
var count = this.viewer.world.getItemCount();
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
var offset = new OpenSeadragon.Point();
|
||||
var rowHeight = 0;
|
||||
var item, box;
|
||||
for (var i = 0; i < count; i++) {
|
||||
item = this.viewer.world.getItemAt(i);
|
||||
box = item.getBounds();
|
||||
|
||||
if (i === this.page) {
|
||||
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({
|
||||
item: item,
|
||||
bounds: box
|
||||
});
|
||||
|
||||
if (layoutConfig.columns && i % layoutConfig.columns === layoutConfig.columns - 1) {
|
||||
x = 0;
|
||||
y += rowHeight + layoutConfig.buffer;
|
||||
rowHeight = 0;
|
||||
} else {
|
||||
if (!layoutConfig.book || i % 2 === 0) {
|
||||
x += layoutConfig.buffer;
|
||||
}
|
||||
|
||||
x += box.width;
|
||||
}
|
||||
}
|
||||
|
||||
var pos, spec;
|
||||
for (i = 0; i < count; i++) {
|
||||
spec = layout.specs[i];
|
||||
pos = spec.bounds.getTopLeft().plus(offset);
|
||||
spec.bounds.x = pos.x;
|
||||
spec.bounds.y = pos.y;
|
||||
|
||||
if (layout.bounds) {
|
||||
layout.bounds = layout.bounds.union(spec.bounds);
|
||||
} else {
|
||||
layout.bounds = spec.bounds.clone();
|
||||
}
|
||||
}
|
||||
|
||||
return layout;
|
||||
},
|
||||
|
||||
// ----------
|
||||
setLayout: function(config) {
|
||||
var spec;
|
||||
|
||||
for (var i = 0; i < config.layout.specs.length; i++) {
|
||||
spec = config.layout.specs[i];
|
||||
spec.item.setPosition(spec.bounds.getTopLeft(), config.immediately);
|
||||
spec.item.setWidth(spec.bounds.width, config.immediately);
|
||||
}
|
||||
},
|
||||
|
||||
// ----------
|
||||
goHome: function(config) {
|
||||
var viewerWidth = this.$el.width();
|
||||
var viewerHeight = this.$el.height();
|
||||
var layoutConfig = {};
|
||||
|
||||
if (this.mode === 'thumbs') {
|
||||
var info = this.getScrollInfo();
|
||||
var box = this.thumbBounds.clone();
|
||||
box.height = box.width * (viewerHeight / viewerWidth);
|
||||
box.y += info.viewportMax * info.scrollFactor;
|
||||
this.viewer.viewport.fitBounds(box, config.immediately);
|
||||
} else {
|
||||
this.goToPage({
|
||||
page: this.page,
|
||||
immediately: config.immediately
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// ----------
|
||||
getTileSources: function() {
|
||||
if (this.tileSources) {
|
||||
return $.map(this.tileSources.slice(0, this.maxImages), function(v, i) {
|
||||
return new OpenSeadragon.IIIFTileSource(v);
|
||||
});
|
||||
}
|
||||
|
||||
var inputs = [
|
||||
{
|
||||
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"
|
||||
}
|
||||
}
|
||||
}, {
|
||||
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"
|
||||
}
|
||||
}
|
||||
}, {
|
||||
// Image: {
|
||||
// xmlns: "http://schemas.microsoft.com/deepzoom/2008",
|
||||
// Url: "../../data/tall_files/",
|
||||
// Format: "jpg",
|
||||
// Overlap: "1",
|
||||
// TileSize: "254",
|
||||
// Size: {
|
||||
// Width: "500",
|
||||
// Height: "2000"
|
||||
// }
|
||||
// }
|
||||
// }, {
|
||||
// Image: {
|
||||
// xmlns: "http://schemas.microsoft.com/deepzoom/2008",
|
||||
// Url: "../../data/wide_files/",
|
||||
// Format: "jpg",
|
||||
// Overlap: "1",
|
||||
// TileSize: "254",
|
||||
// Size: {
|
||||
// Width: "2000",
|
||||
// Height: "500"
|
||||
// }
|
||||
// }
|
||||
// }, {
|
||||
Image: {
|
||||
xmlns: "http://schemas.microsoft.com/deepzoom/2008",
|
||||
Url: "../../data/testpattern_files/",
|
||||
Format: "jpg",
|
||||
Overlap: "1",
|
||||
TileSize: "254",
|
||||
Size: {
|
||||
Width: "1000",
|
||||
Height: "1000"
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
var outputs = [];
|
||||
for (var i = 0; i < this.maxImages; i++) {
|
||||
outputs.push(inputs[Math.floor(Math.random() * inputs.length)]);
|
||||
}
|
||||
|
||||
return outputs;
|
||||
}
|
||||
};
|
||||
|
||||
// ----------
|
||||
$(document).ready(function() {
|
||||
App.init();
|
||||
});
|
||||
})();
|
73
test/demo/m2/js/openseadragon-svg-overlay.js
Normal file
73
test/demo/m2/js/openseadragon-svg-overlay.js
Normal file
@ -0,0 +1,73 @@
|
||||
(function() {
|
||||
|
||||
if (!window.OpenSeadragon) {
|
||||
console.error('[openseadragon-svg-overlay] requires OpenSeadragon');
|
||||
return;
|
||||
}
|
||||
|
||||
var svgNS = 'http://www.w3.org/2000/svg';
|
||||
|
||||
var update = function(viewer) {
|
||||
var info = viewer._svgOverlayInfo;
|
||||
|
||||
if (info.containerWidth !== viewer.container.clientWidth) {
|
||||
info.containerWidth = viewer.container.clientWidth;
|
||||
info.svg.setAttribute('width', info.containerWidth);
|
||||
}
|
||||
|
||||
if (info.containerHeight !== viewer.container.clientHeight) {
|
||||
info.containerHeight = viewer.container.clientHeight;
|
||||
info.svg.setAttribute('height', info.containerHeight);
|
||||
}
|
||||
|
||||
var p = viewer.viewport.pixelFromPoint(new OpenSeadragon.Point(0, 0), true);
|
||||
var zoom = viewer.viewport.getZoom(true);
|
||||
var scale = viewer.container.clientWidth * zoom;
|
||||
info.node.setAttribute('transform',
|
||||
'translate(' + p.x + ',' + p.y + ') scale(' + scale + ')');
|
||||
};
|
||||
|
||||
OpenSeadragon.Viewer.prototype.svgOverlay = function(command) {
|
||||
var self = this;
|
||||
|
||||
if (command === undefined) {
|
||||
if (this._svgOverlayInfo) {
|
||||
console.error('[openseadragon-svg-overlay] already initialized on this viewer');
|
||||
return;
|
||||
}
|
||||
|
||||
var info = this._svgOverlayInfo = {
|
||||
containerWidth: 0,
|
||||
containerHeight: 0
|
||||
};
|
||||
|
||||
info.svg = document.createElementNS(svgNS, 'svg');
|
||||
info.svg.setAttribute('pointer-events', 'none');
|
||||
info.svg.style.position = 'absolute';
|
||||
info.svg.style.left = 0;
|
||||
info.svg.style.top = 0;
|
||||
info.svg.style.width = '100%';
|
||||
info.svg.style.height = '100%';
|
||||
this.container.insertBefore(info.svg, this.canvas.nextSibling);
|
||||
|
||||
info.node = document.createElementNS(svgNS, 'g');
|
||||
info.svg.appendChild(info.node);
|
||||
|
||||
this.addHandler('animation', function() {
|
||||
update(self);
|
||||
});
|
||||
|
||||
this.addHandler('open', function() {
|
||||
update(self);
|
||||
});
|
||||
|
||||
update(this);
|
||||
return info.node;
|
||||
} else if (command === 'resize') {
|
||||
update(this);
|
||||
} else {
|
||||
console.error('[openseadragon-svg-overlay] unknown command: ' + command);
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
Loading…
Reference in New Issue
Block a user