2013-05-01 08:46:16 +04:00
|
|
|
/*
|
2013-05-14 08:00:24 +04:00
|
|
|
* OpenSeadragon - Viewport
|
2013-05-01 08:46:16 +04:00
|
|
|
*
|
|
|
|
* Copyright (C) 2009 CodePlex Foundation
|
2013-05-14 07:32:09 +04:00
|
|
|
* Copyright (C) 2010-2013 OpenSeadragon contributors
|
2013-05-01 08:46:16 +04:00
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions are
|
|
|
|
* met:
|
|
|
|
*
|
|
|
|
* - Redistributions of source code must retain the above copyright notice,
|
|
|
|
* this list of conditions and the following disclaimer.
|
|
|
|
*
|
|
|
|
* - Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* - Neither the name of CodePlex Foundation nor the names of its
|
|
|
|
* contributors may be used to endorse or promote products derived from
|
|
|
|
* this software without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
|
|
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
|
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
2011-12-06 07:50:25 +04:00
|
|
|
(function( $ ){
|
2012-01-25 23:14:02 +04:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
2013-11-16 10:19:53 +04:00
|
|
|
* @class Viewport
|
|
|
|
* @memberof OpenSeadragon
|
2014-11-04 22:53:39 +03:00
|
|
|
* @classdesc Handles coordinate-related functionality (zoom, pan, rotation, etc.)
|
|
|
|
* for an {@link OpenSeadragon.Viewer}.
|
|
|
|
* @param {Object} options - Options for this Viewport.
|
2014-11-04 22:57:58 +03:00
|
|
|
* @param {Object} [options.margins] - See viewportMargins in {@link OpenSeadragon.Options}.
|
|
|
|
* @param {Number} [options.springStiffness] - See springStiffness in {@link OpenSeadragon.Options}.
|
|
|
|
* @param {Number} [options.animationTime] - See animationTime in {@link OpenSeadragon.Options}.
|
|
|
|
* @param {Number} [options.minZoomImageRatio] - See minZoomImageRatio in {@link OpenSeadragon.Options}.
|
|
|
|
* @param {Number} [options.maxZoomPixelRatio] - See maxZoomPixelRatio in {@link OpenSeadragon.Options}.
|
|
|
|
* @param {Number} [options.visibilityRatio] - See visibilityRatio in {@link OpenSeadragon.Options}.
|
|
|
|
* @param {Boolean} [options.wrapHorizontal] - See wrapHorizontal in {@link OpenSeadragon.Options}.
|
|
|
|
* @param {Boolean} [options.wrapVertical] - See wrapVertical in {@link OpenSeadragon.Options}.
|
|
|
|
* @param {Number} [options.defaultZoomLevel] - See defaultZoomLevel in {@link OpenSeadragon.Options}.
|
|
|
|
* @param {Number} [options.minZoomLevel] - See minZoomLevel in {@link OpenSeadragon.Options}.
|
|
|
|
* @param {Number} [options.maxZoomLevel] - See maxZoomLevel in {@link OpenSeadragon.Options}.
|
|
|
|
* @param {Number} [options.degrees] - See degrees in {@link OpenSeadragon.Options}.
|
|
|
|
* @param {Boolean} [options.homeFillsViewer] - See homeFillsViewer in {@link OpenSeadragon.Options}.
|
2012-01-25 23:14:02 +04:00
|
|
|
*/
|
2012-01-24 07:48:45 +04:00
|
|
|
$.Viewport = function( options ) {
|
|
|
|
|
2013-06-19 21:33:25 +04:00
|
|
|
//backward compatibility for positional args while prefering more
|
2012-03-01 17:38:15 +04:00
|
|
|
//idiomatic javascript options object as the only argument
|
|
|
|
var args = arguments;
|
|
|
|
if( args.length && args[ 0 ] instanceof $.Point ){
|
2012-01-24 07:48:45 +04:00
|
|
|
options = {
|
2012-03-01 17:38:15 +04:00
|
|
|
containerSize: args[ 0 ],
|
|
|
|
contentSize: args[ 1 ],
|
|
|
|
config: args[ 2 ]
|
2012-01-24 07:48:45 +04:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2012-03-01 17:38:15 +04:00
|
|
|
//options.config and the general config argument are deprecated
|
|
|
|
//in favor of the more direct specification of optional settings
|
2013-05-20 20:39:57 +04:00
|
|
|
//being passed directly on the options object
|
2012-03-01 17:38:15 +04:00
|
|
|
if ( options.config ){
|
|
|
|
$.extend( true, options, options.config );
|
|
|
|
delete options.config;
|
|
|
|
}
|
|
|
|
|
2014-10-22 04:11:09 +04:00
|
|
|
this._margins = $.extend({
|
|
|
|
left: 0,
|
|
|
|
top: 0,
|
|
|
|
right: 0,
|
|
|
|
bottom: 0
|
|
|
|
}, options.margins || {});
|
|
|
|
|
|
|
|
delete options.margins;
|
|
|
|
|
2012-03-01 17:38:15 +04:00
|
|
|
$.extend( true, this, {
|
2013-06-19 21:33:25 +04:00
|
|
|
|
2012-03-01 17:38:15 +04:00
|
|
|
//required settings
|
|
|
|
containerSize: null,
|
|
|
|
contentSize: null,
|
|
|
|
|
|
|
|
//internal state properties
|
|
|
|
zoomPoint: null,
|
2013-02-14 04:44:23 +04:00
|
|
|
viewer: null,
|
2012-03-01 17:38:15 +04:00
|
|
|
|
|
|
|
//configurable options
|
|
|
|
springStiffness: $.DEFAULT_SETTINGS.springStiffness,
|
|
|
|
animationTime: $.DEFAULT_SETTINGS.animationTime,
|
|
|
|
minZoomImageRatio: $.DEFAULT_SETTINGS.minZoomImageRatio,
|
|
|
|
maxZoomPixelRatio: $.DEFAULT_SETTINGS.maxZoomPixelRatio,
|
|
|
|
visibilityRatio: $.DEFAULT_SETTINGS.visibilityRatio,
|
|
|
|
wrapHorizontal: $.DEFAULT_SETTINGS.wrapHorizontal,
|
2013-02-06 06:26:40 +04:00
|
|
|
wrapVertical: $.DEFAULT_SETTINGS.wrapVertical,
|
|
|
|
defaultZoomLevel: $.DEFAULT_SETTINGS.defaultZoomLevel,
|
|
|
|
minZoomLevel: $.DEFAULT_SETTINGS.minZoomLevel,
|
2013-08-14 01:39:22 +04:00
|
|
|
maxZoomLevel: $.DEFAULT_SETTINGS.maxZoomLevel,
|
2014-08-29 22:53:29 +04:00
|
|
|
degrees: $.DEFAULT_SETTINGS.degrees,
|
|
|
|
homeFillsViewer: $.DEFAULT_SETTINGS.homeFillsViewer
|
2012-03-01 17:38:15 +04:00
|
|
|
|
|
|
|
}, options );
|
|
|
|
|
2015-10-30 00:29:59 +03:00
|
|
|
this._updateContainerInnerSize();
|
2014-10-17 01:00:07 +04:00
|
|
|
|
2012-01-05 03:14:20 +04:00
|
|
|
this.centerSpringX = new $.Spring({
|
2013-06-19 21:33:25 +04:00
|
|
|
initial: 0,
|
2012-03-01 17:38:15 +04:00
|
|
|
springStiffness: this.springStiffness,
|
|
|
|
animationTime: this.animationTime
|
2012-01-05 03:14:20 +04:00
|
|
|
});
|
|
|
|
this.centerSpringY = new $.Spring({
|
2013-06-19 21:33:25 +04:00
|
|
|
initial: 0,
|
2012-03-01 17:38:15 +04:00
|
|
|
springStiffness: this.springStiffness,
|
|
|
|
animationTime: this.animationTime
|
2012-01-05 03:14:20 +04:00
|
|
|
});
|
2012-02-28 03:29:00 +04:00
|
|
|
this.zoomSpring = new $.Spring({
|
2015-03-31 00:50:37 +03:00
|
|
|
exponential: true,
|
2013-06-19 21:33:25 +04:00
|
|
|
initial: 1,
|
2012-03-01 17:38:15 +04:00
|
|
|
springStiffness: this.springStiffness,
|
|
|
|
animationTime: this.animationTime
|
2012-01-05 03:14:20 +04:00
|
|
|
});
|
2012-02-28 03:29:00 +04:00
|
|
|
|
2015-01-21 03:09:54 +03:00
|
|
|
this._oldCenterX = this.centerSpringX.current.value;
|
|
|
|
this._oldCenterY = this.centerSpringY.current.value;
|
|
|
|
this._oldZoom = this.zoomSpring.current.value;
|
|
|
|
|
2014-08-19 03:04:49 +04:00
|
|
|
if (this.contentSize) {
|
|
|
|
this.resetContentSize( this.contentSize );
|
|
|
|
} else {
|
|
|
|
this.setHomeBounds(new $.Rect(0, 0, 1, 1), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.goHome( true );
|
2011-12-06 07:50:25 +04:00
|
|
|
this.update();
|
|
|
|
};
|
|
|
|
|
2016-01-25 00:09:18 +03:00
|
|
|
/** @lends OpenSeadragon.Viewport.prototype */
|
|
|
|
$.Viewport.prototype = {
|
2013-02-14 04:44:23 +04:00
|
|
|
/**
|
2014-08-19 03:04:49 +04:00
|
|
|
* Updates the viewport's home bounds and constraints for the given content size.
|
2013-02-14 04:44:23 +04:00
|
|
|
* @function
|
2014-08-19 03:04:49 +04:00
|
|
|
* @param {OpenSeadragon.Point} contentSize - size of the content in content units
|
2013-02-14 04:44:23 +04:00
|
|
|
* @return {OpenSeadragon.Viewport} Chainable.
|
2013-11-22 00:19:07 +04:00
|
|
|
* @fires OpenSeadragon.Viewer.event:reset-size
|
2013-02-14 04:44:23 +04:00
|
|
|
*/
|
2012-04-03 11:08:27 +04:00
|
|
|
resetContentSize: function( contentSize ){
|
2014-08-19 03:04:49 +04:00
|
|
|
$.console.assert(contentSize, "[Viewport.resetContentSize] contentSize is required");
|
|
|
|
$.console.assert(contentSize instanceof $.Point, "[Viewport.resetContentSize] contentSize must be an OpenSeadragon.Point");
|
|
|
|
$.console.assert(contentSize.x > 0, "[Viewport.resetContentSize] contentSize.x must be greater than 0");
|
|
|
|
$.console.assert(contentSize.y > 0, "[Viewport.resetContentSize] contentSize.y must be greater than 0");
|
|
|
|
|
|
|
|
this.setHomeBounds(new $.Rect(0, 0, 1, contentSize.y / contentSize.x), contentSize.x);
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Updates the viewport's home bounds and constraints.
|
|
|
|
* @function
|
2014-11-24 22:59:06 +03:00
|
|
|
* @param {OpenSeadragon.Rect} bounds - the new bounds in viewport coordinates
|
|
|
|
* @param {Number} contentFactor - how many content units per viewport unit
|
2014-08-19 03:04:49 +04:00
|
|
|
* @fires OpenSeadragon.Viewer.event:reset-size
|
|
|
|
*/
|
|
|
|
setHomeBounds: function(bounds, contentFactor) {
|
|
|
|
$.console.assert(bounds, "[Viewport.setHomeBounds] bounds is required");
|
|
|
|
$.console.assert(bounds instanceof $.Rect, "[Viewport.setHomeBounds] bounds must be an OpenSeadragon.Rect");
|
|
|
|
$.console.assert(bounds.width > 0, "[Viewport.setHomeBounds] bounds.width must be greater than 0");
|
|
|
|
$.console.assert(bounds.height > 0, "[Viewport.setHomeBounds] bounds.height must be greater than 0");
|
|
|
|
|
2015-12-06 03:18:56 +03:00
|
|
|
this.homeBounds = bounds.clone().rotate(this.degrees).getBoundingBox();
|
2014-08-19 03:04:49 +04:00
|
|
|
this.contentSize = this.homeBounds.getSize().times(contentFactor);
|
2012-04-03 11:08:27 +04:00
|
|
|
this.contentAspectX = this.contentSize.x / this.contentSize.y;
|
|
|
|
this.contentAspectY = this.contentSize.y / this.contentSize.x;
|
2012-08-29 22:46:34 +04:00
|
|
|
|
2015-12-06 03:18:56 +03:00
|
|
|
if (this.viewer) {
|
2013-11-16 10:19:53 +04:00
|
|
|
/**
|
2014-08-19 03:04:49 +04:00
|
|
|
* Raised when the viewer's content size or home bounds are reset
|
|
|
|
* (see {@link OpenSeadragon.Viewport#resetContentSize},
|
|
|
|
* {@link OpenSeadragon.Viewport#setHomeBounds}).
|
2013-11-22 00:19:07 +04:00
|
|
|
*
|
2013-11-16 10:19:53 +04:00
|
|
|
* @event reset-size
|
|
|
|
* @memberof OpenSeadragon.Viewer
|
|
|
|
* @type {object}
|
|
|
|
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.
|
|
|
|
* @property {OpenSeadragon.Point} contentSize
|
2014-08-19 03:04:49 +04:00
|
|
|
* @property {OpenSeadragon.Rect} homeBounds
|
|
|
|
* @property {Number} contentFactor
|
2013-11-18 18:56:32 +04:00
|
|
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
2013-11-16 10:19:53 +04:00
|
|
|
*/
|
2015-12-06 03:18:56 +03:00
|
|
|
this.viewer.raiseEvent('reset-size', {
|
2014-08-19 03:04:49 +04:00
|
|
|
contentSize: this.contentSize.clone(),
|
|
|
|
contentFactor: contentFactor,
|
|
|
|
homeBounds: this.homeBounds.clone()
|
2013-02-14 04:44:23 +04:00
|
|
|
});
|
|
|
|
}
|
2012-04-03 11:08:27 +04:00
|
|
|
},
|
|
|
|
|
2012-02-15 23:50:27 +04:00
|
|
|
/**
|
|
|
|
* @function
|
|
|
|
*/
|
2012-01-05 03:14:20 +04:00
|
|
|
getHomeZoom: function() {
|
2013-02-06 06:26:40 +04:00
|
|
|
if( this.defaultZoomLevel ){
|
|
|
|
return this.defaultZoomLevel;
|
|
|
|
} else {
|
2014-08-29 22:53:29 +04:00
|
|
|
var aspectFactor =
|
|
|
|
this.contentAspectX / this.getAspectRatio();
|
|
|
|
|
2014-09-18 03:05:23 +04:00
|
|
|
var output;
|
2014-08-29 22:53:29 +04:00
|
|
|
if( this.homeFillsViewer ){ // fill the viewer and clip the image
|
2014-09-18 03:05:23 +04:00
|
|
|
output = ( aspectFactor >= 1) ?
|
2014-08-29 22:53:29 +04:00
|
|
|
aspectFactor :
|
|
|
|
1;
|
|
|
|
} else {
|
2014-09-18 03:05:23 +04:00
|
|
|
output = ( aspectFactor >= 1 ) ?
|
2014-08-29 22:53:29 +04:00
|
|
|
1 :
|
|
|
|
aspectFactor;
|
|
|
|
}
|
2014-08-19 03:04:49 +04:00
|
|
|
|
|
|
|
return output / this.homeBounds.width;
|
2013-02-06 06:26:40 +04:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @function
|
|
|
|
*/
|
|
|
|
getHomeBounds: function() {
|
2015-01-02 22:44:35 +03:00
|
|
|
var center = this.homeBounds.getCenter( ),
|
|
|
|
width = 1.0 / this.getHomeZoom( ),
|
|
|
|
height = width / this.getAspectRatio();
|
|
|
|
|
|
|
|
return new $.Rect(
|
|
|
|
center.x - ( width / 2.0 ),
|
|
|
|
center.y - ( height / 2.0 ),
|
|
|
|
width,
|
|
|
|
height
|
|
|
|
);
|
2013-02-06 06:26:40 +04:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @function
|
2014-08-19 03:04:49 +04:00
|
|
|
* @param {Boolean} immediately
|
|
|
|
* @fires OpenSeadragon.Viewer.event:home
|
2013-02-06 06:26:40 +04:00
|
|
|
*/
|
|
|
|
goHome: function( immediately ) {
|
2013-02-14 04:44:23 +04:00
|
|
|
if( this.viewer ){
|
2014-08-19 03:04:49 +04:00
|
|
|
/**
|
|
|
|
* Raised when the "home" operation occurs (see {@link OpenSeadragon.Viewport#goHome}).
|
|
|
|
*
|
|
|
|
* @event home
|
|
|
|
* @memberof OpenSeadragon.Viewer
|
|
|
|
* @type {object}
|
|
|
|
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.
|
|
|
|
* @property {Boolean} immediately
|
|
|
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
|
|
|
*/
|
|
|
|
this.viewer.raiseEvent( 'home', {
|
|
|
|
immediately: immediately
|
|
|
|
});
|
2013-02-14 04:44:23 +04:00
|
|
|
}
|
2014-08-19 03:04:49 +04:00
|
|
|
return this.fitBounds( this.getHomeBounds(), immediately );
|
2011-12-06 07:50:25 +04:00
|
|
|
},
|
|
|
|
|
2012-02-15 23:50:27 +04:00
|
|
|
/**
|
|
|
|
* @function
|
|
|
|
*/
|
2012-01-05 03:14:20 +04:00
|
|
|
getMinZoom: function() {
|
2012-08-29 22:46:34 +04:00
|
|
|
var homeZoom = this.getHomeZoom(),
|
2013-06-19 21:33:25 +04:00
|
|
|
zoom = this.minZoomLevel ?
|
|
|
|
this.minZoomLevel :
|
2013-02-06 06:26:40 +04:00
|
|
|
this.minZoomImageRatio * homeZoom;
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2015-01-14 02:31:52 +03:00
|
|
|
return zoom;
|
2011-12-06 07:50:25 +04:00
|
|
|
},
|
|
|
|
|
2012-02-15 23:50:27 +04:00
|
|
|
/**
|
|
|
|
* @function
|
|
|
|
*/
|
2012-01-05 03:14:20 +04:00
|
|
|
getMaxZoom: function() {
|
2014-08-19 03:04:49 +04:00
|
|
|
var zoom = this.maxZoomLevel;
|
|
|
|
if (!zoom) {
|
2014-10-22 04:11:09 +04:00
|
|
|
zoom = this.contentSize.x * this.maxZoomPixelRatio / this._containerInnerSize.x;
|
2014-08-19 03:04:49 +04:00
|
|
|
zoom /= this.homeBounds.width;
|
|
|
|
}
|
2013-02-06 06:26:40 +04:00
|
|
|
|
2012-01-25 23:14:02 +04:00
|
|
|
return Math.max( zoom, this.getHomeZoom() );
|
2011-12-06 07:50:25 +04:00
|
|
|
},
|
2012-01-05 03:14:20 +04:00
|
|
|
|
2012-02-15 23:50:27 +04:00
|
|
|
/**
|
|
|
|
* @function
|
|
|
|
*/
|
2011-12-06 07:50:25 +04:00
|
|
|
getAspectRatio: function() {
|
2014-10-22 04:11:09 +04:00
|
|
|
return this._containerInnerSize.x / this._containerInnerSize.y;
|
2011-12-06 07:50:25 +04:00
|
|
|
},
|
2012-01-05 03:14:20 +04:00
|
|
|
|
2012-02-15 23:50:27 +04:00
|
|
|
/**
|
|
|
|
* @function
|
2014-10-17 02:19:05 +04:00
|
|
|
* @returns {OpenSeadragon.Point} The size of the container, in screen coordinates.
|
2012-02-15 23:50:27 +04:00
|
|
|
*/
|
2011-12-06 07:50:25 +04:00
|
|
|
getContainerSize: function() {
|
2012-01-25 23:14:02 +04:00
|
|
|
return new $.Point(
|
2013-06-19 21:33:25 +04:00
|
|
|
this.containerSize.x,
|
2012-01-25 23:14:02 +04:00
|
|
|
this.containerSize.y
|
|
|
|
);
|
2011-12-06 07:50:25 +04:00
|
|
|
},
|
|
|
|
|
2015-10-30 00:29:59 +03:00
|
|
|
/**
|
|
|
|
* @function
|
|
|
|
* The margins push the "home" region in from the sides by the specified amounts.
|
|
|
|
* @returns {Object} Properties (Numbers, in screen coordinates): left, top, right, bottom.
|
|
|
|
*/
|
|
|
|
getMargins: function() {
|
|
|
|
return $.extend({}, this._margins); // Make a copy so we are not returning our original
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @function
|
|
|
|
* The margins push the "home" region in from the sides by the specified amounts.
|
|
|
|
* @param {Object} margins - Properties (Numbers, in screen coordinates): left, top, right, bottom.
|
|
|
|
*/
|
|
|
|
setMargins: function(margins) {
|
|
|
|
$.console.assert($.type(margins) === 'object', '[Viewport.setMargins] margins must be an object');
|
|
|
|
|
|
|
|
this._margins = $.extend({
|
|
|
|
left: 0,
|
|
|
|
top: 0,
|
|
|
|
right: 0,
|
|
|
|
bottom: 0
|
|
|
|
}, margins);
|
|
|
|
|
|
|
|
this._updateContainerInnerSize();
|
|
|
|
this.viewer.forceRedraw();
|
|
|
|
},
|
|
|
|
|
2012-02-15 23:50:27 +04:00
|
|
|
/**
|
|
|
|
* @function
|
2013-08-19 21:14:04 +04:00
|
|
|
* @param {Boolean} current - Pass true for the current location; defaults to false (target location).
|
2014-11-24 22:59:06 +03:00
|
|
|
* @returns {OpenSeadragon.Rect} The location you are zoomed/panned to, in viewport coordinates.
|
2012-02-15 23:50:27 +04:00
|
|
|
*/
|
2012-01-05 04:45:47 +04:00
|
|
|
getBounds: function( current ) {
|
2012-01-25 23:14:02 +04:00
|
|
|
var center = this.getCenter( current ),
|
|
|
|
width = 1.0 / this.getZoom( current ),
|
2012-01-05 03:14:20 +04:00
|
|
|
height = width / this.getAspectRatio();
|
|
|
|
|
|
|
|
return new $.Rect(
|
2013-06-19 21:33:25 +04:00
|
|
|
center.x - ( width / 2.0 ),
|
2012-03-07 07:20:00 +04:00
|
|
|
center.y - ( height / 2.0 ),
|
2013-06-19 21:33:25 +04:00
|
|
|
width,
|
2012-01-05 03:14:20 +04:00
|
|
|
height
|
|
|
|
);
|
2011-12-06 07:50:25 +04:00
|
|
|
},
|
|
|
|
|
2014-10-17 01:00:07 +04:00
|
|
|
/**
|
|
|
|
* @function
|
|
|
|
* @param {Boolean} current - Pass true for the current location; defaults to false (target location).
|
2014-10-17 02:19:05 +04:00
|
|
|
* @returns {OpenSeadragon.Rect} The location you are zoomed/panned to,
|
2014-11-24 22:59:06 +03:00
|
|
|
* including the space taken by margins, in viewport coordinates.
|
2014-10-17 01:00:07 +04:00
|
|
|
*/
|
|
|
|
getBoundsWithMargins: function( current ) {
|
|
|
|
var bounds = this.getBounds(current);
|
2014-10-22 04:11:09 +04:00
|
|
|
var factor = this._containerInnerSize.x * this.getZoom(current);
|
|
|
|
bounds.x -= this._margins.left / factor;
|
|
|
|
bounds.y -= this._margins.top / factor;
|
|
|
|
bounds.width += (this._margins.left + this._margins.right) / factor;
|
|
|
|
bounds.height += (this._margins.top + this._margins.bottom) / factor;
|
2014-10-17 01:00:07 +04:00
|
|
|
return bounds;
|
|
|
|
},
|
|
|
|
|
2012-02-15 23:50:27 +04:00
|
|
|
/**
|
|
|
|
* @function
|
2013-08-19 21:14:04 +04:00
|
|
|
* @param {Boolean} current - Pass true for the current location; defaults to false (target location).
|
2012-02-15 23:50:27 +04:00
|
|
|
*/
|
2012-01-05 04:45:47 +04:00
|
|
|
getCenter: function( current ) {
|
2011-12-17 02:56:38 +04:00
|
|
|
var centerCurrent = new $.Point(
|
2014-10-18 01:27:24 +04:00
|
|
|
this.centerSpringX.current.value,
|
|
|
|
this.centerSpringY.current.value
|
2012-01-05 03:14:20 +04:00
|
|
|
),
|
|
|
|
centerTarget = new $.Point(
|
2014-10-18 01:27:24 +04:00
|
|
|
this.centerSpringX.target.value,
|
|
|
|
this.centerSpringY.target.value
|
2012-01-05 03:14:20 +04:00
|
|
|
),
|
|
|
|
oldZoomPixel,
|
|
|
|
zoom,
|
|
|
|
width,
|
|
|
|
height,
|
|
|
|
bounds,
|
|
|
|
newZoomPixel,
|
|
|
|
deltaZoomPixels,
|
|
|
|
deltaZoomPoints;
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2012-01-25 23:14:02 +04:00
|
|
|
if ( current ) {
|
2011-12-06 07:50:25 +04:00
|
|
|
return centerCurrent;
|
2012-01-25 23:14:02 +04:00
|
|
|
} else if ( !this.zoomPoint ) {
|
2011-12-06 07:50:25 +04:00
|
|
|
return centerTarget;
|
|
|
|
}
|
|
|
|
|
2012-01-05 03:14:20 +04:00
|
|
|
oldZoomPixel = this.pixelFromPoint(this.zoomPoint, true);
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2012-01-05 03:14:20 +04:00
|
|
|
zoom = this.getZoom();
|
|
|
|
width = 1.0 / zoom;
|
|
|
|
height = width / this.getAspectRatio();
|
|
|
|
bounds = new $.Rect(
|
|
|
|
centerCurrent.x - width / 2.0,
|
2013-06-19 21:33:25 +04:00
|
|
|
centerCurrent.y - height / 2.0,
|
|
|
|
width,
|
2012-01-05 03:14:20 +04:00
|
|
|
height
|
|
|
|
);
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2014-10-22 04:11:09 +04:00
|
|
|
newZoomPixel = this._pixelFromPoint(this.zoomPoint, bounds);
|
2012-01-05 03:14:20 +04:00
|
|
|
deltaZoomPixels = newZoomPixel.minus( oldZoomPixel );
|
2014-10-22 04:11:09 +04:00
|
|
|
deltaZoomPoints = deltaZoomPixels.divide( this._containerInnerSize.x * zoom );
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2012-01-05 03:14:20 +04:00
|
|
|
return centerTarget.plus( deltaZoomPoints );
|
2011-12-06 07:50:25 +04:00
|
|
|
},
|
|
|
|
|
2012-02-15 23:50:27 +04:00
|
|
|
/**
|
|
|
|
* @function
|
2013-08-19 21:14:04 +04:00
|
|
|
* @param {Boolean} current - Pass true for the current location; defaults to false (target location).
|
2012-02-15 23:50:27 +04:00
|
|
|
*/
|
2012-01-05 04:45:47 +04:00
|
|
|
getZoom: function( current ) {
|
|
|
|
if ( current ) {
|
2012-01-05 03:14:20 +04:00
|
|
|
return this.zoomSpring.current.value;
|
2011-12-06 07:50:25 +04:00
|
|
|
} else {
|
2012-01-05 03:14:20 +04:00
|
|
|
return this.zoomSpring.target.value;
|
2011-12-06 07:50:25 +04:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2012-02-15 23:50:27 +04:00
|
|
|
/**
|
|
|
|
* @function
|
2014-06-24 03:10:01 +04:00
|
|
|
* @private
|
2014-06-24 02:40:36 +04:00
|
|
|
* @param {OpenSeadragon.Rect} bounds
|
|
|
|
* @param {Boolean} immediately
|
|
|
|
* @return {OpenSeadragon.Rect} constrained bounds.
|
2012-02-15 23:50:27 +04:00
|
|
|
*/
|
2014-06-24 02:40:36 +04:00
|
|
|
_applyBoundaryConstraints: function( bounds, immediately ) {
|
2014-08-27 02:12:49 +04:00
|
|
|
var dx = 0,
|
2014-06-24 02:40:36 +04:00
|
|
|
dy = 0,
|
|
|
|
newBounds = new $.Rect(
|
|
|
|
bounds.x,
|
|
|
|
bounds.y,
|
|
|
|
bounds.width,
|
|
|
|
bounds.height
|
|
|
|
);
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2014-08-27 02:12:49 +04:00
|
|
|
var horizontalThreshold = this.visibilityRatio * newBounds.width;
|
|
|
|
var verticalThreshold = this.visibilityRatio * newBounds.height;
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2012-01-05 03:14:20 +04:00
|
|
|
if ( this.wrapHorizontal ) {
|
2012-01-05 04:45:47 +04:00
|
|
|
//do nothing
|
2013-02-06 06:26:40 +04:00
|
|
|
} else {
|
2014-08-27 02:12:49 +04:00
|
|
|
var thresholdLeft = newBounds.x + (newBounds.width - horizontalThreshold);
|
|
|
|
if (this.homeBounds.x > thresholdLeft) {
|
|
|
|
dx = this.homeBounds.x - thresholdLeft;
|
2013-06-19 21:33:25 +04:00
|
|
|
}
|
2014-08-27 02:12:49 +04:00
|
|
|
|
|
|
|
var homeRight = this.homeBounds.x + this.homeBounds.width;
|
|
|
|
var thresholdRight = newBounds.x + horizontalThreshold;
|
|
|
|
if (homeRight < thresholdRight) {
|
|
|
|
var newDx = homeRight - thresholdRight;
|
|
|
|
if (dx) {
|
|
|
|
dx = (dx + newDx) / 2;
|
|
|
|
} else {
|
|
|
|
dx = newDx;
|
|
|
|
}
|
2013-02-06 06:26:40 +04:00
|
|
|
}
|
2011-12-06 07:50:25 +04:00
|
|
|
}
|
|
|
|
|
2012-01-05 03:14:20 +04:00
|
|
|
if ( this.wrapVertical ) {
|
2012-01-05 04:45:47 +04:00
|
|
|
//do nothing
|
2013-02-06 06:26:40 +04:00
|
|
|
} else {
|
2014-08-27 02:12:49 +04:00
|
|
|
var thresholdTop = newBounds.y + (newBounds.height - verticalThreshold);
|
|
|
|
if (this.homeBounds.y > thresholdTop) {
|
|
|
|
dy = this.homeBounds.y - thresholdTop;
|
2013-06-19 21:33:25 +04:00
|
|
|
}
|
2014-08-27 02:12:49 +04:00
|
|
|
|
|
|
|
var homeBottom = this.homeBounds.y + this.homeBounds.height;
|
|
|
|
var thresholdBottom = newBounds.y + verticalThreshold;
|
|
|
|
if (homeBottom < thresholdBottom) {
|
|
|
|
var newDy = homeBottom - thresholdBottom;
|
|
|
|
if (dy) {
|
|
|
|
dy = (dy + newDy) / 2;
|
|
|
|
} else {
|
|
|
|
dy = newDy;
|
|
|
|
}
|
2013-02-06 06:26:40 +04:00
|
|
|
}
|
2011-12-06 07:50:25 +04:00
|
|
|
}
|
|
|
|
|
2014-08-27 02:12:49 +04:00
|
|
|
if ( dx || dy ) {
|
2014-06-24 02:40:36 +04:00
|
|
|
newBounds.x += dx;
|
|
|
|
newBounds.y += dy;
|
2011-12-06 07:50:25 +04:00
|
|
|
}
|
2013-02-14 04:44:23 +04:00
|
|
|
|
|
|
|
if( this.viewer ){
|
2013-11-16 10:19:53 +04:00
|
|
|
/**
|
2013-11-22 00:19:07 +04:00
|
|
|
* Raised when the viewport constraints are applied (see {@link OpenSeadragon.Viewport#applyConstraints}).
|
|
|
|
*
|
2013-11-16 10:19:53 +04:00
|
|
|
* @event constrain
|
|
|
|
* @memberof OpenSeadragon.Viewer
|
|
|
|
* @type {object}
|
|
|
|
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.
|
|
|
|
* @property {Boolean} immediately
|
2013-11-18 18:56:32 +04:00
|
|
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
2013-11-16 10:19:53 +04:00
|
|
|
*/
|
2013-06-19 21:33:25 +04:00
|
|
|
this.viewer.raiseEvent( 'constrain', {
|
2013-10-11 04:00:15 +04:00
|
|
|
immediately: immediately
|
2013-02-14 04:44:23 +04:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2014-07-24 20:40:43 +04:00
|
|
|
return newBounds;
|
2014-06-24 02:40:36 +04:00
|
|
|
},
|
2014-07-24 20:40:43 +04:00
|
|
|
|
2014-06-24 02:40:36 +04:00
|
|
|
/**
|
|
|
|
* @function
|
|
|
|
* @return {OpenSeadragon.Viewport} Chainable.
|
|
|
|
* @fires OpenSeadragon.Viewer.event:constrain
|
|
|
|
*/
|
|
|
|
applyConstraints: function( immediately ) {
|
|
|
|
var actualZoom = this.getZoom(),
|
|
|
|
constrainedZoom = Math.max(
|
|
|
|
Math.min( actualZoom, this.getMaxZoom() ),
|
|
|
|
this.getMinZoom()
|
|
|
|
),
|
|
|
|
bounds,
|
|
|
|
constrainedBounds;
|
2014-07-24 20:40:43 +04:00
|
|
|
|
2014-06-24 02:40:36 +04:00
|
|
|
if ( actualZoom != constrainedZoom ) {
|
|
|
|
this.zoomTo( constrainedZoom, this.zoomPoint, immediately );
|
|
|
|
}
|
|
|
|
|
|
|
|
bounds = this.getBounds();
|
|
|
|
|
|
|
|
constrainedBounds = this._applyBoundaryConstraints( bounds, immediately );
|
2014-07-24 20:40:43 +04:00
|
|
|
|
2014-06-24 02:40:36 +04:00
|
|
|
if ( bounds.x !== constrainedBounds.x || bounds.y !== constrainedBounds.y || immediately ){
|
|
|
|
this.fitBounds( constrainedBounds, immediately );
|
|
|
|
}
|
2014-07-24 20:40:43 +04:00
|
|
|
|
2013-01-31 01:51:37 +04:00
|
|
|
return this;
|
2011-12-06 07:50:25 +04:00
|
|
|
},
|
|
|
|
|
2012-02-15 23:50:27 +04:00
|
|
|
/**
|
|
|
|
* @function
|
|
|
|
* @param {Boolean} immediately
|
|
|
|
*/
|
2012-01-05 04:45:47 +04:00
|
|
|
ensureVisible: function( immediately ) {
|
2013-02-06 06:26:40 +04:00
|
|
|
return this.applyConstraints( immediately );
|
2011-12-06 07:50:25 +04:00
|
|
|
},
|
|
|
|
|
2012-01-25 23:14:02 +04:00
|
|
|
/**
|
2012-02-15 23:50:27 +04:00
|
|
|
* @function
|
2014-06-24 03:10:01 +04:00
|
|
|
* @private
|
2012-02-15 23:50:27 +04:00
|
|
|
* @param {OpenSeadragon.Rect} bounds
|
2014-06-24 03:10:01 +04:00
|
|
|
* @param {Object} options (immediately=false, constraints=false)
|
2013-02-14 04:44:23 +04:00
|
|
|
* @return {OpenSeadragon.Viewport} Chainable.
|
2012-01-25 23:14:02 +04:00
|
|
|
*/
|
2014-06-24 02:40:36 +04:00
|
|
|
_fitBounds: function( bounds, options ) {
|
2014-06-24 03:10:01 +04:00
|
|
|
options = options || {};
|
|
|
|
var immediately = options.immediately || false;
|
|
|
|
var constraints = options.constraints || false;
|
2014-07-24 20:40:43 +04:00
|
|
|
|
2012-01-05 03:14:20 +04:00
|
|
|
var aspect = this.getAspectRatio(),
|
|
|
|
center = bounds.getCenter(),
|
|
|
|
newBounds = new $.Rect(
|
2013-06-19 21:33:25 +04:00
|
|
|
bounds.x,
|
|
|
|
bounds.y,
|
|
|
|
bounds.width,
|
2012-01-05 03:14:20 +04:00
|
|
|
bounds.height
|
|
|
|
),
|
|
|
|
oldBounds,
|
|
|
|
oldZoom,
|
|
|
|
newZoom,
|
2014-06-24 02:40:36 +04:00
|
|
|
referencePoint,
|
|
|
|
newBoundsAspectRatio,
|
|
|
|
newConstrainedZoom;
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2012-01-25 23:14:02 +04:00
|
|
|
if ( newBounds.getAspectRatio() >= aspect ) {
|
2011-12-06 07:50:25 +04:00
|
|
|
newBounds.height = bounds.width / aspect;
|
2012-01-05 04:45:47 +04:00
|
|
|
newBounds.y = center.y - newBounds.height / 2;
|
2011-12-06 07:50:25 +04:00
|
|
|
} else {
|
|
|
|
newBounds.width = bounds.height * aspect;
|
2012-01-05 04:45:47 +04:00
|
|
|
newBounds.x = center.x - newBounds.width / 2;
|
2011-12-06 07:50:25 +04:00
|
|
|
}
|
|
|
|
|
2014-06-24 02:40:36 +04:00
|
|
|
if ( constraints ) {
|
|
|
|
newBoundsAspectRatio = newBounds.getAspectRatio();
|
|
|
|
}
|
2014-07-24 20:40:43 +04:00
|
|
|
|
2012-01-25 23:14:02 +04:00
|
|
|
this.panTo( this.getCenter( true ), true );
|
|
|
|
this.zoomTo( this.getZoom( true ), null, true );
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2012-01-05 03:14:20 +04:00
|
|
|
oldBounds = this.getBounds();
|
|
|
|
oldZoom = this.getZoom();
|
|
|
|
newZoom = 1.0 / newBounds.width;
|
2014-07-24 20:40:43 +04:00
|
|
|
|
2014-06-24 02:40:36 +04:00
|
|
|
if ( constraints ) {
|
|
|
|
newConstrainedZoom = Math.max(
|
|
|
|
Math.min(newZoom, this.getMaxZoom() ),
|
|
|
|
this.getMinZoom()
|
|
|
|
);
|
2014-07-24 20:40:43 +04:00
|
|
|
|
2014-06-24 02:40:36 +04:00
|
|
|
if (newZoom !== newConstrainedZoom) {
|
|
|
|
newZoom = newConstrainedZoom;
|
|
|
|
newBounds.width = 1.0 / newZoom;
|
|
|
|
newBounds.x = center.x - newBounds.width / 2;
|
|
|
|
newBounds.height = newBounds.width / newBoundsAspectRatio;
|
|
|
|
newBounds.y = center.y - newBounds.height / 2;
|
|
|
|
}
|
2014-07-24 20:40:43 +04:00
|
|
|
|
2014-06-24 02:40:36 +04:00
|
|
|
newBounds = this._applyBoundaryConstraints( newBounds, immediately );
|
2015-01-21 04:19:13 +03:00
|
|
|
center = newBounds.getCenter();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (immediately) {
|
|
|
|
this.panTo( center, true );
|
|
|
|
return this.zoomTo(newZoom, null, true);
|
2014-06-24 02:40:36 +04:00
|
|
|
}
|
2014-07-24 20:40:43 +04:00
|
|
|
|
2015-03-12 01:41:36 +03:00
|
|
|
if (Math.abs(newZoom - oldZoom) < 0.00000001 ||
|
|
|
|
Math.abs(newBounds.width - oldBounds.width) < 0.00000001) {
|
2015-01-21 04:19:13 +03:00
|
|
|
return this.panTo( center, immediately );
|
2011-12-06 07:50:25 +04:00
|
|
|
}
|
|
|
|
|
2013-06-19 21:33:25 +04:00
|
|
|
referencePoint = oldBounds.getTopLeft().times(
|
2014-10-22 04:11:09 +04:00
|
|
|
this._containerInnerSize.x / oldBounds.width
|
2012-01-05 03:14:20 +04:00
|
|
|
).minus(
|
2013-06-19 21:33:25 +04:00
|
|
|
newBounds.getTopLeft().times(
|
2014-10-22 04:11:09 +04:00
|
|
|
this._containerInnerSize.x / newBounds.width
|
2012-01-05 03:14:20 +04:00
|
|
|
)
|
|
|
|
).divide(
|
2014-10-22 04:11:09 +04:00
|
|
|
this._containerInnerSize.x / oldBounds.width -
|
|
|
|
this._containerInnerSize.x / newBounds.width
|
2012-01-05 03:14:20 +04:00
|
|
|
);
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2013-02-06 06:26:40 +04:00
|
|
|
return this.zoomTo( newZoom, referencePoint, immediately );
|
2011-12-06 07:50:25 +04:00
|
|
|
},
|
2013-06-19 21:33:25 +04:00
|
|
|
|
2014-06-24 02:40:36 +04:00
|
|
|
/**
|
|
|
|
* @function
|
|
|
|
* @param {OpenSeadragon.Rect} bounds
|
|
|
|
* @param {Boolean} immediately
|
|
|
|
* @return {OpenSeadragon.Viewport} Chainable.
|
|
|
|
*/
|
|
|
|
fitBounds: function( bounds, immediately ) {
|
|
|
|
return this._fitBounds( bounds, {
|
|
|
|
immediately: immediately,
|
|
|
|
constraints: false
|
|
|
|
} );
|
|
|
|
},
|
2014-07-24 20:40:43 +04:00
|
|
|
|
2014-06-24 02:40:36 +04:00
|
|
|
/**
|
|
|
|
* @function
|
|
|
|
* @param {OpenSeadragon.Rect} bounds
|
|
|
|
* @param {Boolean} immediately
|
|
|
|
* @return {OpenSeadragon.Viewport} Chainable.
|
|
|
|
*/
|
|
|
|
fitBoundsWithConstraints: function( bounds, immediately ) {
|
|
|
|
return this._fitBounds( bounds, {
|
|
|
|
immediately: immediately,
|
|
|
|
constraints: true
|
|
|
|
} );
|
|
|
|
},
|
2012-04-03 11:08:27 +04:00
|
|
|
|
|
|
|
/**
|
2014-11-06 02:57:44 +03:00
|
|
|
* Zooms so the image just fills the viewer vertically.
|
2012-04-03 11:08:27 +04:00
|
|
|
* @param {Boolean} immediately
|
2013-02-14 04:44:23 +04:00
|
|
|
* @return {OpenSeadragon.Viewport} Chainable.
|
2012-04-03 11:08:27 +04:00
|
|
|
*/
|
|
|
|
fitVertically: function( immediately ) {
|
2014-11-06 02:57:44 +03:00
|
|
|
var box = new $.Rect(this.homeBounds.x + (this.homeBounds.width / 2), this.homeBounds.y,
|
|
|
|
0, this.homeBounds.height);
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2014-11-06 02:57:44 +03:00
|
|
|
return this.fitBounds( box, immediately );
|
2011-12-06 07:50:25 +04:00
|
|
|
},
|
|
|
|
|
2012-04-03 11:08:27 +04:00
|
|
|
/**
|
2014-11-06 02:57:44 +03:00
|
|
|
* Zooms so the image just fills the viewer horizontally.
|
2012-04-03 11:08:27 +04:00
|
|
|
* @param {Boolean} immediately
|
2013-02-14 04:44:23 +04:00
|
|
|
* @return {OpenSeadragon.Viewport} Chainable.
|
2012-04-03 11:08:27 +04:00
|
|
|
*/
|
|
|
|
fitHorizontally: function( immediately ) {
|
2014-11-06 02:57:44 +03:00
|
|
|
var box = new $.Rect(this.homeBounds.x, this.homeBounds.y + (this.homeBounds.height / 2),
|
|
|
|
this.homeBounds.width, 0);
|
2012-04-03 11:08:27 +04:00
|
|
|
|
2014-11-06 02:57:44 +03:00
|
|
|
return this.fitBounds( box, immediately );
|
2012-04-03 11:08:27 +04:00
|
|
|
},
|
|
|
|
|
|
|
|
|
2012-02-15 23:50:27 +04:00
|
|
|
/**
|
|
|
|
* @function
|
|
|
|
* @param {OpenSeadragon.Point} delta
|
|
|
|
* @param {Boolean} immediately
|
2013-02-14 04:44:23 +04:00
|
|
|
* @return {OpenSeadragon.Viewport} Chainable.
|
2013-11-22 07:43:45 +04:00
|
|
|
* @fires OpenSeadragon.Viewer.event:pan
|
2012-02-15 23:50:27 +04:00
|
|
|
*/
|
2012-01-25 23:14:02 +04:00
|
|
|
panBy: function( delta, immediately ) {
|
2012-01-05 03:14:20 +04:00
|
|
|
var center = new $.Point(
|
|
|
|
this.centerSpringX.target.value,
|
|
|
|
this.centerSpringY.target.value
|
|
|
|
);
|
2013-02-06 06:26:40 +04:00
|
|
|
return this.panTo( center.plus( delta ), immediately );
|
2011-12-06 07:50:25 +04:00
|
|
|
},
|
|
|
|
|
2012-02-15 23:50:27 +04:00
|
|
|
/**
|
|
|
|
* @function
|
|
|
|
* @param {OpenSeadragon.Point} center
|
|
|
|
* @param {Boolean} immediately
|
2013-02-14 04:44:23 +04:00
|
|
|
* @return {OpenSeadragon.Viewport} Chainable.
|
2013-11-22 00:19:07 +04:00
|
|
|
* @fires OpenSeadragon.Viewer.event:pan
|
2012-02-15 23:50:27 +04:00
|
|
|
*/
|
2012-01-25 23:14:02 +04:00
|
|
|
panTo: function( center, immediately ) {
|
|
|
|
if ( immediately ) {
|
|
|
|
this.centerSpringX.resetTo( center.x );
|
|
|
|
this.centerSpringY.resetTo( center.y );
|
2011-12-06 07:50:25 +04:00
|
|
|
} else {
|
2012-01-25 23:14:02 +04:00
|
|
|
this.centerSpringX.springTo( center.x );
|
|
|
|
this.centerSpringY.springTo( center.y );
|
2011-12-06 07:50:25 +04:00
|
|
|
}
|
2013-01-31 01:51:37 +04:00
|
|
|
|
2013-02-14 04:44:23 +04:00
|
|
|
if( this.viewer ){
|
2013-11-16 10:19:53 +04:00
|
|
|
/**
|
2013-11-22 07:43:45 +04:00
|
|
|
* Raised when the viewport is panned (see {@link OpenSeadragon.Viewport#panBy} and {@link OpenSeadragon.Viewport#panTo}).
|
2013-11-22 00:19:07 +04:00
|
|
|
*
|
2013-11-16 10:19:53 +04:00
|
|
|
* @event pan
|
|
|
|
* @memberof OpenSeadragon.Viewer
|
|
|
|
* @type {object}
|
|
|
|
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.
|
|
|
|
* @property {OpenSeadragon.Point} center
|
|
|
|
* @property {Boolean} immediately
|
2013-11-18 18:56:32 +04:00
|
|
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
2013-11-16 10:19:53 +04:00
|
|
|
*/
|
2013-06-19 21:33:25 +04:00
|
|
|
this.viewer.raiseEvent( 'pan', {
|
2013-02-14 04:44:23 +04:00
|
|
|
center: center,
|
2013-10-11 04:00:15 +04:00
|
|
|
immediately: immediately
|
2013-02-14 04:44:23 +04:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2013-01-31 01:51:37 +04:00
|
|
|
return this;
|
2011-12-06 07:50:25 +04:00
|
|
|
},
|
|
|
|
|
2012-02-15 23:50:27 +04:00
|
|
|
/**
|
|
|
|
* @function
|
2013-02-14 04:44:23 +04:00
|
|
|
* @return {OpenSeadragon.Viewport} Chainable.
|
2013-11-22 00:19:07 +04:00
|
|
|
* @fires OpenSeadragon.Viewer.event:zoom
|
2012-02-15 23:50:27 +04:00
|
|
|
*/
|
2015-12-12 03:07:23 +03:00
|
|
|
zoomBy: function(factor, refPoint, immediately) {
|
|
|
|
return this.zoomTo(
|
|
|
|
this.zoomSpring.target.value * factor, refPoint, immediately);
|
2011-12-06 07:50:25 +04:00
|
|
|
},
|
|
|
|
|
2012-02-15 23:50:27 +04:00
|
|
|
/**
|
|
|
|
* @function
|
2013-02-14 04:44:23 +04:00
|
|
|
* @return {OpenSeadragon.Viewport} Chainable.
|
2013-11-22 00:19:07 +04:00
|
|
|
* @fires OpenSeadragon.Viewer.event:zoom
|
2012-02-15 23:50:27 +04:00
|
|
|
*/
|
2012-01-25 23:14:02 +04:00
|
|
|
zoomTo: function( zoom, refPoint, immediately ) {
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2013-10-04 20:12:47 +04:00
|
|
|
this.zoomPoint = refPoint instanceof $.Point &&
|
|
|
|
!isNaN(refPoint.x) &&
|
|
|
|
!isNaN(refPoint.y) ?
|
2013-06-19 21:33:25 +04:00
|
|
|
refPoint :
|
2013-01-31 01:51:37 +04:00
|
|
|
null;
|
2013-06-19 21:33:25 +04:00
|
|
|
|
2012-01-25 23:14:02 +04:00
|
|
|
if ( immediately ) {
|
|
|
|
this.zoomSpring.resetTo( zoom );
|
2013-06-19 21:33:25 +04:00
|
|
|
} else {
|
2012-01-25 23:14:02 +04:00
|
|
|
this.zoomSpring.springTo( zoom );
|
2011-12-06 07:50:25 +04:00
|
|
|
}
|
|
|
|
|
2013-02-14 04:44:23 +04:00
|
|
|
if( this.viewer ){
|
2013-11-16 10:19:53 +04:00
|
|
|
/**
|
2013-11-22 00:19:07 +04:00
|
|
|
* Raised when the viewport zoom level changes (see {@link OpenSeadragon.Viewport#zoomBy} and {@link OpenSeadragon.Viewport#zoomTo}).
|
|
|
|
*
|
2013-11-16 10:19:53 +04:00
|
|
|
* @event zoom
|
|
|
|
* @memberof OpenSeadragon.Viewer
|
|
|
|
* @type {object}
|
|
|
|
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.
|
|
|
|
* @property {Number} zoom
|
|
|
|
* @property {OpenSeadragon.Point} refPoint
|
|
|
|
* @property {Boolean} immediately
|
2013-11-18 18:56:32 +04:00
|
|
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
2013-11-16 10:19:53 +04:00
|
|
|
*/
|
2013-06-19 21:33:25 +04:00
|
|
|
this.viewer.raiseEvent( 'zoom', {
|
2013-02-14 04:44:23 +04:00
|
|
|
zoom: zoom,
|
|
|
|
refPoint: refPoint,
|
2013-10-11 04:00:15 +04:00
|
|
|
immediately: immediately
|
2013-02-14 04:44:23 +04:00
|
|
|
});
|
|
|
|
}
|
2013-01-31 01:51:37 +04:00
|
|
|
|
|
|
|
return this;
|
2011-12-06 07:50:25 +04:00
|
|
|
},
|
|
|
|
|
2013-08-16 02:15:20 +04:00
|
|
|
/**
|
2014-08-26 17:56:24 +04:00
|
|
|
* Rotates this viewport to the angle specified.
|
2013-08-16 02:15:20 +04:00
|
|
|
* @function
|
|
|
|
* @return {OpenSeadragon.Viewport} Chainable.
|
|
|
|
*/
|
2015-12-06 03:18:56 +03:00
|
|
|
setRotation: function(degrees) {
|
|
|
|
if (!this.viewer || !this.viewer.drawer.canRotate()) {
|
2013-08-16 21:32:21 +04:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2015-12-06 03:18:56 +03:00
|
|
|
degrees = degrees % 360;
|
|
|
|
if (degrees < 0) {
|
|
|
|
degrees += 360;
|
|
|
|
}
|
2013-08-16 02:15:20 +04:00
|
|
|
this.degrees = degrees;
|
2015-12-06 03:18:56 +03:00
|
|
|
this.setHomeBounds(
|
|
|
|
this.viewer.world.getHomeBounds(),
|
|
|
|
this.viewer.world.getContentFactor());
|
2013-12-09 18:26:36 +04:00
|
|
|
this.viewer.forceRedraw();
|
2014-07-18 03:24:28 +04:00
|
|
|
|
2014-08-13 13:53:52 +04:00
|
|
|
/**
|
|
|
|
* Raised when rotation has been changed.
|
|
|
|
*
|
2014-08-20 02:43:36 +04:00
|
|
|
* @event rotate
|
2014-08-13 13:53:52 +04:00
|
|
|
* @memberof OpenSeadragon.Viewer
|
|
|
|
* @type {object}
|
|
|
|
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.
|
|
|
|
* @property {Number} degrees - The number of degrees the rotation was set to.
|
|
|
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
|
|
|
*/
|
2015-12-06 03:18:56 +03:00
|
|
|
this.viewer.raiseEvent('rotate', {"degrees": degrees});
|
2013-08-16 02:15:20 +04:00
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2013-08-16 21:32:21 +04:00
|
|
|
/**
|
|
|
|
* Gets the current rotation in degrees.
|
|
|
|
* @function
|
|
|
|
* @return {Number} The current rotation in degrees.
|
|
|
|
*/
|
|
|
|
getRotation: function() {
|
|
|
|
return this.degrees;
|
|
|
|
},
|
|
|
|
|
2012-02-15 23:50:27 +04:00
|
|
|
/**
|
|
|
|
* @function
|
2013-02-14 04:44:23 +04:00
|
|
|
* @return {OpenSeadragon.Viewport} Chainable.
|
2013-11-22 00:19:07 +04:00
|
|
|
* @fires OpenSeadragon.Viewer.event:resize
|
2012-02-15 23:50:27 +04:00
|
|
|
*/
|
2012-01-25 23:14:02 +04:00
|
|
|
resize: function( newContainerSize, maintain ) {
|
2012-01-05 03:14:20 +04:00
|
|
|
var oldBounds = this.getBounds(),
|
|
|
|
newBounds = oldBounds,
|
2013-11-23 05:07:44 +04:00
|
|
|
widthDeltaFactor;
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2014-10-18 01:27:24 +04:00
|
|
|
this.containerSize.x = newContainerSize.x;
|
|
|
|
this.containerSize.y = newContainerSize.y;
|
|
|
|
|
2015-10-30 00:29:59 +03:00
|
|
|
this._updateContainerInnerSize();
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2013-11-23 05:07:44 +04:00
|
|
|
if ( maintain ) {
|
2014-10-17 02:19:05 +04:00
|
|
|
// TODO: widthDeltaFactor will always be 1; probably not what's intended
|
2013-11-23 05:07:44 +04:00
|
|
|
widthDeltaFactor = newContainerSize.x / this.containerSize.x;
|
2012-01-18 03:30:41 +04:00
|
|
|
newBounds.width = oldBounds.width * widthDeltaFactor;
|
2011-12-06 07:50:25 +04:00
|
|
|
newBounds.height = newBounds.width / this.getAspectRatio();
|
|
|
|
}
|
|
|
|
|
2013-02-14 04:44:23 +04:00
|
|
|
if( this.viewer ){
|
2013-11-16 10:19:53 +04:00
|
|
|
/**
|
2013-11-22 00:19:07 +04:00
|
|
|
* Raised when the viewer is resized (see {@link OpenSeadragon.Viewport#resize}).
|
|
|
|
*
|
2013-11-16 10:19:53 +04:00
|
|
|
* @event resize
|
|
|
|
* @memberof OpenSeadragon.Viewer
|
|
|
|
* @type {object}
|
|
|
|
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.
|
|
|
|
* @property {OpenSeadragon.Point} newContainerSize
|
|
|
|
* @property {Boolean} maintain
|
2013-11-18 18:56:32 +04:00
|
|
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
2013-11-16 10:19:53 +04:00
|
|
|
*/
|
2013-06-19 21:33:25 +04:00
|
|
|
this.viewer.raiseEvent( 'resize', {
|
2013-02-14 04:44:23 +04:00
|
|
|
newContainerSize: newContainerSize,
|
2013-10-11 04:00:15 +04:00
|
|
|
maintain: maintain
|
2013-02-14 04:44:23 +04:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2013-02-06 06:26:40 +04:00
|
|
|
return this.fitBounds( newBounds, true );
|
2011-12-06 07:50:25 +04:00
|
|
|
},
|
|
|
|
|
2015-10-30 00:29:59 +03:00
|
|
|
// private
|
|
|
|
_updateContainerInnerSize: function() {
|
|
|
|
this._containerInnerSize = new $.Point(
|
|
|
|
Math.max(1, this.containerSize.x - (this._margins.left + this._margins.right)),
|
|
|
|
Math.max(1, this.containerSize.y - (this._margins.top + this._margins.bottom))
|
|
|
|
);
|
|
|
|
},
|
|
|
|
|
2012-02-15 23:50:27 +04:00
|
|
|
/**
|
|
|
|
* @function
|
|
|
|
*/
|
2011-12-06 07:50:25 +04:00
|
|
|
update: function() {
|
2015-01-21 03:09:54 +03:00
|
|
|
var oldZoomPixel,
|
2012-01-05 03:14:20 +04:00
|
|
|
newZoomPixel,
|
|
|
|
deltaZoomPixels,
|
|
|
|
deltaZoomPoints;
|
2011-12-06 07:50:25 +04:00
|
|
|
|
|
|
|
if (this.zoomPoint) {
|
2012-01-25 23:14:02 +04:00
|
|
|
oldZoomPixel = this.pixelFromPoint( this.zoomPoint, true );
|
2011-12-06 07:50:25 +04:00
|
|
|
}
|
|
|
|
|
2012-01-05 03:14:20 +04:00
|
|
|
this.zoomSpring.update();
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2015-01-21 03:09:54 +03:00
|
|
|
if (this.zoomPoint && this.zoomSpring.current.value != this._oldZoom) {
|
2012-01-05 03:14:20 +04:00
|
|
|
newZoomPixel = this.pixelFromPoint( this.zoomPoint, true );
|
2012-01-25 23:14:02 +04:00
|
|
|
deltaZoomPixels = newZoomPixel.minus( oldZoomPixel );
|
2012-01-05 03:14:20 +04:00
|
|
|
deltaZoomPoints = this.deltaPointsFromPixels( deltaZoomPixels, true );
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2012-01-05 03:14:20 +04:00
|
|
|
this.centerSpringX.shiftBy( deltaZoomPoints.x );
|
|
|
|
this.centerSpringY.shiftBy( deltaZoomPoints.y );
|
2011-12-06 07:50:25 +04:00
|
|
|
} else {
|
|
|
|
this.zoomPoint = null;
|
|
|
|
}
|
|
|
|
|
2012-01-05 03:14:20 +04:00
|
|
|
this.centerSpringX.update();
|
|
|
|
this.centerSpringY.update();
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2015-01-21 03:09:54 +03:00
|
|
|
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;
|
2011-12-06 07:50:25 +04:00
|
|
|
},
|
|
|
|
|
2012-02-15 23:50:27 +04:00
|
|
|
/**
|
2015-12-23 02:19:22 +03:00
|
|
|
* Convert a delta (translation vector) from viewport coordinates to pixels
|
2015-12-12 03:07:23 +03:00
|
|
|
* coordinates. This method does not take rotation into account.
|
|
|
|
* Consider using deltaPixelsFromPoints if you need to account for rotation.
|
|
|
|
* @param {OpenSeadragon.Point} deltaPoints - The translation vector to convert.
|
|
|
|
* @param {Boolean} [current=false] - Pass true for the current location;
|
|
|
|
* defaults to false (target location).
|
|
|
|
* @returns {OpenSeadragon.Point}
|
2012-02-15 23:50:27 +04:00
|
|
|
*/
|
2015-12-23 02:19:22 +03:00
|
|
|
deltaPixelsFromPointsNoRotate: function(deltaPoints, current) {
|
2012-01-05 03:14:20 +04:00
|
|
|
return deltaPoints.times(
|
2015-12-12 03:07:23 +03:00
|
|
|
this._containerInnerSize.x * this.getZoom(current)
|
2012-01-05 03:14:20 +04:00
|
|
|
);
|
2011-12-06 07:50:25 +04:00
|
|
|
},
|
|
|
|
|
2012-02-15 23:50:27 +04:00
|
|
|
/**
|
2015-12-15 02:36:18 +03:00
|
|
|
* Convert a delta (translation vector) from viewport coordinates to pixels
|
2015-12-12 03:07:23 +03:00
|
|
|
* coordinates.
|
|
|
|
* @param {OpenSeadragon.Point} deltaPoints - The translation vector to convert.
|
|
|
|
* @param {Boolean} [current=false] - Pass true for the current location;
|
|
|
|
* defaults to false (target location).
|
|
|
|
* @returns {OpenSeadragon.Point}
|
2012-02-15 23:50:27 +04:00
|
|
|
*/
|
2015-12-12 03:07:23 +03:00
|
|
|
deltaPixelsFromPoints: function(deltaPoints, current) {
|
2015-12-23 02:19:22 +03:00
|
|
|
return this.deltaPixelsFromPointsNoRotate(
|
2015-12-12 03:07:23 +03:00
|
|
|
deltaPoints.rotate(this.getRotation()),
|
|
|
|
current);
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2015-12-23 02:19:22 +03:00
|
|
|
* Convert a delta (translation vector) from pixels coordinates to viewport
|
2015-12-12 03:07:23 +03:00
|
|
|
* coordinates. This method does not take rotation into account.
|
|
|
|
* Consider using deltaPointsFromPixels if you need to account for rotation.
|
|
|
|
* @param {OpenSeadragon.Point} deltaPixels - The translation vector to convert.
|
|
|
|
* @param {Boolean} [current=false] - Pass true for the current location;
|
|
|
|
* defaults to false (target location).
|
|
|
|
* @returns {OpenSeadragon.Point}
|
|
|
|
*/
|
2015-12-23 02:19:22 +03:00
|
|
|
deltaPointsFromPixelsNoRotate: function(deltaPixels, current) {
|
2012-01-05 03:14:20 +04:00
|
|
|
return deltaPixels.divide(
|
2015-12-12 03:07:23 +03:00
|
|
|
this._containerInnerSize.x * this.getZoom(current)
|
2012-01-05 03:14:20 +04:00
|
|
|
);
|
2011-12-06 07:50:25 +04:00
|
|
|
},
|
|
|
|
|
2015-12-12 03:07:23 +03:00
|
|
|
/**
|
2015-12-15 02:36:18 +03:00
|
|
|
* Convert a delta (translation vector) from pixels coordinates to viewport
|
|
|
|
* coordinates.
|
2015-12-12 03:07:23 +03:00
|
|
|
* @param {OpenSeadragon.Point} deltaPixels - The translation vector to convert.
|
|
|
|
* @param {Boolean} [current=false] - Pass true for the current location;
|
|
|
|
* defaults to false (target location).
|
|
|
|
* @returns {OpenSeadragon.Point}
|
|
|
|
*/
|
|
|
|
deltaPointsFromPixels: function(deltaPixels, current) {
|
2015-12-23 02:19:22 +03:00
|
|
|
return this.deltaPointsFromPixelsNoRotate(deltaPixels, current)
|
2015-12-12 03:07:23 +03:00
|
|
|
.rotate(-this.getRotation());
|
|
|
|
},
|
|
|
|
|
2015-12-15 02:36:18 +03:00
|
|
|
/**
|
2015-12-23 02:19:22 +03:00
|
|
|
* Convert viewport coordinates to pixels coordinates.
|
2015-12-15 02:36:18 +03:00
|
|
|
* This method does not take rotation into account.
|
|
|
|
* Consider using pixelFromPoint if you need to account for rotation.
|
|
|
|
* @param {OpenSeadragon.Point} point the viewport coordinates
|
|
|
|
* @param {Boolean} [current=false] - Pass true for the current location;
|
|
|
|
* defaults to false (target location).
|
|
|
|
* @returns {OpenSeadragon.Point}
|
|
|
|
*/
|
2015-12-23 02:19:22 +03:00
|
|
|
pixelFromPointNoRotate: function(point, current) {
|
|
|
|
return this._pixelFromPointNoRotate(point, this.getBounds(current));
|
2015-12-12 03:07:23 +03:00
|
|
|
},
|
|
|
|
|
2012-02-15 23:50:27 +04:00
|
|
|
/**
|
2015-12-15 02:36:18 +03:00
|
|
|
* Convert viewport coordinates to pixel coordinates.
|
|
|
|
* @param {OpenSeadragon.Point} point the viewport coordinates
|
2015-12-12 03:07:23 +03:00
|
|
|
* @param {Boolean} [current=false] - Pass true for the current location;
|
|
|
|
* defaults to false (target location).
|
2015-12-15 02:36:18 +03:00
|
|
|
* @returns {OpenSeadragon.Point}
|
2012-02-15 23:50:27 +04:00
|
|
|
*/
|
2015-12-12 03:07:23 +03:00
|
|
|
pixelFromPoint: function(point, current) {
|
|
|
|
return this._pixelFromPoint(point, this.getBounds(current));
|
2014-10-22 04:11:09 +04:00
|
|
|
},
|
|
|
|
|
2014-11-04 22:53:39 +03:00
|
|
|
// private
|
2015-12-23 02:19:22 +03:00
|
|
|
_pixelFromPointNoRotate: function(point, bounds) {
|
2012-01-05 03:14:20 +04:00
|
|
|
return point.minus(
|
|
|
|
bounds.getTopLeft()
|
|
|
|
).times(
|
2014-10-22 04:11:09 +04:00
|
|
|
this._containerInnerSize.x / bounds.width
|
2014-10-18 01:27:24 +04:00
|
|
|
).plus(
|
2014-10-22 04:11:09 +04:00
|
|
|
new $.Point(this._margins.left, this._margins.top)
|
2012-01-05 03:14:20 +04:00
|
|
|
);
|
2011-12-06 07:50:25 +04:00
|
|
|
},
|
|
|
|
|
2015-12-12 03:07:23 +03:00
|
|
|
// private
|
|
|
|
_pixelFromPoint: function(point, bounds) {
|
2015-12-23 02:19:22 +03:00
|
|
|
return this._pixelFromPointNoRotate(
|
2015-12-12 03:07:23 +03:00
|
|
|
point.rotate(this.getRotation(), this.getCenter(true)),
|
|
|
|
bounds);
|
|
|
|
},
|
|
|
|
|
2015-12-15 02:36:18 +03:00
|
|
|
/**
|
2015-12-23 02:19:22 +03:00
|
|
|
* Convert pixel coordinates to viewport coordinates.
|
2015-12-15 02:36:18 +03:00
|
|
|
* This method does not take rotation into account.
|
|
|
|
* Consider using pointFromPixel if you need to account for rotation.
|
|
|
|
* @param {OpenSeadragon.Point} pixel Pixel coordinates
|
|
|
|
* @param {Boolean} [current=false] - Pass true for the current location;
|
|
|
|
* defaults to false (target location).
|
|
|
|
* @returns {OpenSeadragon.Point}
|
|
|
|
*/
|
2015-12-23 02:19:22 +03:00
|
|
|
pointFromPixelNoRotate: function(pixel, current) {
|
2012-01-05 03:14:20 +04:00
|
|
|
var bounds = this.getBounds( current );
|
2014-10-18 01:27:24 +04:00
|
|
|
return pixel.minus(
|
2014-10-22 04:11:09 +04:00
|
|
|
new $.Point(this._margins.left, this._margins.top)
|
2014-10-18 01:27:24 +04:00
|
|
|
).divide(
|
2014-10-22 04:11:09 +04:00
|
|
|
this._containerInnerSize.x / bounds.width
|
2012-01-05 03:14:20 +04:00
|
|
|
).plus(
|
|
|
|
bounds.getTopLeft()
|
|
|
|
);
|
2013-02-11 07:53:51 +04:00
|
|
|
},
|
|
|
|
|
2015-12-12 03:07:23 +03:00
|
|
|
/**
|
2015-12-15 02:36:18 +03:00
|
|
|
* Convert pixel coordinates to viewport coordinates.
|
|
|
|
* @param {OpenSeadragon.Point} pixel Pixel coordinates
|
|
|
|
* @param {Boolean} [current=false] - Pass true for the current location;
|
|
|
|
* defaults to false (target location).
|
|
|
|
* @returns {OpenSeadragon.Point}
|
2015-12-12 03:07:23 +03:00
|
|
|
*/
|
|
|
|
pointFromPixel: function(pixel, current) {
|
2015-12-23 02:19:22 +03:00
|
|
|
return this.pointFromPixelNoRotate(pixel, current).rotate(
|
2015-12-12 03:07:23 +03:00
|
|
|
-this.getRotation(),
|
|
|
|
this.getCenter(true)
|
|
|
|
);
|
|
|
|
},
|
|
|
|
|
2014-11-24 22:46:33 +03:00
|
|
|
// private
|
|
|
|
_viewportToImageDelta: function( viewerX, viewerY ) {
|
|
|
|
var scale = this.homeBounds.width;
|
|
|
|
return new $.Point(viewerX * (this.contentSize.x / scale),
|
|
|
|
viewerY * ((this.contentSize.y * this.contentAspectX) / scale));
|
|
|
|
},
|
|
|
|
|
2013-02-11 07:53:51 +04:00
|
|
|
/**
|
2013-09-06 03:26:00 +04:00
|
|
|
* Translates from OpenSeadragon viewer coordinate system to image coordinate system.
|
2013-09-04 22:13:25 +04:00
|
|
|
* This method can be called either by passing X,Y coordinates or an
|
|
|
|
* OpenSeadragon.Point
|
2014-11-22 03:32:04 +03:00
|
|
|
* Note: not accurate with multi-image; use TiledImage.viewportToImageCoordinates instead.
|
2013-09-04 22:13:25 +04:00
|
|
|
* @function
|
2016-01-25 00:09:18 +03:00
|
|
|
* @param {(OpenSeadragon.Point|Number)} viewerX either a point or the X
|
|
|
|
* coordinate in viewport coordinate system.
|
|
|
|
* @param {Number} [viewerY] Y coordinate in viewport coordinate system.
|
2013-09-04 22:13:25 +04:00
|
|
|
* @return {OpenSeadragon.Point} a point representing the coordinates in the image.
|
2013-02-11 07:53:51 +04:00
|
|
|
*/
|
2016-01-25 00:09:18 +03:00
|
|
|
viewportToImageCoordinates: function(viewerX, viewerY) {
|
|
|
|
if (viewerX instanceof $.Point) {
|
2013-08-30 21:59:48 +04:00
|
|
|
//they passed a point instead of individual components
|
2016-01-25 00:09:18 +03:00
|
|
|
return this.viewportToImageCoordinates(viewerX.x, viewerX.y);
|
2013-08-30 21:59:48 +04:00
|
|
|
}
|
2014-11-22 02:18:25 +03:00
|
|
|
|
2014-11-22 03:32:04 +03:00
|
|
|
if (this.viewer && this.viewer.world.getItemCount() > 1) {
|
|
|
|
$.console.error('[Viewport.viewportToImageCoordinates] is not accurate with multi-image; use TiledImage.viewportToImageCoordinates instead.');
|
|
|
|
}
|
|
|
|
|
2014-11-24 22:46:33 +03:00
|
|
|
return this._viewportToImageDelta(viewerX - this.homeBounds.x, viewerY - this.homeBounds.y);
|
|
|
|
},
|
|
|
|
|
|
|
|
// private
|
|
|
|
_imageToViewportDelta: function( imageX, imageY ) {
|
2014-11-22 02:18:25 +03:00
|
|
|
var scale = this.homeBounds.width;
|
2014-11-24 22:46:33 +03:00
|
|
|
return new $.Point((imageX / this.contentSize.x) * scale,
|
|
|
|
(imageY / this.contentSize.y / this.contentAspectX) * scale);
|
2013-02-11 07:53:51 +04:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2013-09-06 03:26:00 +04:00
|
|
|
* Translates from image coordinate system to OpenSeadragon viewer coordinate system
|
2013-09-04 22:13:25 +04:00
|
|
|
* This method can be called either by passing X,Y coordinates or an
|
|
|
|
* OpenSeadragon.Point
|
2014-11-22 03:32:04 +03:00
|
|
|
* Note: not accurate with multi-image; use TiledImage.imageToViewportCoordinates instead.
|
2013-09-04 22:13:25 +04:00
|
|
|
* @function
|
2016-01-25 00:09:18 +03:00
|
|
|
* @param {(OpenSeadragon.Point | Number)} imageX the point or the
|
|
|
|
* X coordinate in image coordinate system.
|
|
|
|
* @param {Number} [imageY] Y coordinate in image coordinate system.
|
2013-09-04 22:13:25 +04:00
|
|
|
* @return {OpenSeadragon.Point} a point representing the coordinates in the viewport.
|
2013-02-11 07:53:51 +04:00
|
|
|
*/
|
2016-01-25 00:09:18 +03:00
|
|
|
imageToViewportCoordinates: function(imageX, imageY) {
|
|
|
|
if (imageX instanceof $.Point) {
|
2013-08-30 21:59:48 +04:00
|
|
|
//they passed a point instead of individual components
|
2016-01-25 00:09:18 +03:00
|
|
|
return this.imageToViewportCoordinates(imageX.x, imageX.y);
|
2013-08-30 21:59:48 +04:00
|
|
|
}
|
2014-11-22 02:18:25 +03:00
|
|
|
|
2014-11-22 03:32:04 +03:00
|
|
|
if (this.viewer && this.viewer.world.getItemCount() > 1) {
|
|
|
|
$.console.error('[Viewport.imageToViewportCoordinates] is not accurate with multi-image; use TiledImage.imageToViewportCoordinates instead.');
|
|
|
|
}
|
|
|
|
|
2014-11-24 22:46:33 +03:00
|
|
|
var point = this._imageToViewportDelta(imageX, imageY);
|
|
|
|
point.x += this.homeBounds.x;
|
|
|
|
point.y += this.homeBounds.y;
|
|
|
|
return point;
|
2013-02-11 07:53:51 +04:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2013-09-04 22:13:25 +04:00
|
|
|
* Translates from a rectangle which describes a portion of the image in
|
|
|
|
* pixel coordinates to OpenSeadragon viewport rectangle coordinates.
|
|
|
|
* This method can be called either by passing X,Y,width,height or an
|
|
|
|
* OpenSeadragon.Rect
|
2014-11-22 03:32:04 +03:00
|
|
|
* Note: not accurate with multi-image; use TiledImage.imageToViewportRectangle instead.
|
2013-09-04 22:13:25 +04:00
|
|
|
* @function
|
2016-01-25 00:09:18 +03:00
|
|
|
* @param {(OpenSeadragon.Rect | Number)} imageX the rectangle or the X
|
|
|
|
* coordinate of the top left corner of the rectangle in image coordinate system.
|
|
|
|
* @param {Number} [imageY] the Y coordinate of the top left corner of the rectangle
|
2013-09-04 22:13:25 +04:00
|
|
|
* in image coordinate system.
|
2016-01-25 00:09:18 +03:00
|
|
|
* @param {Number} [pixelWidth] the width in pixel of the rectangle.
|
|
|
|
* @param {Number} [pixelHeight] the height in pixel of the rectangle.
|
2013-02-11 07:53:51 +04:00
|
|
|
*/
|
2015-12-12 03:07:23 +03:00
|
|
|
imageToViewportRectangle: function(imageX, imageY, pixelWidth, pixelHeight) {
|
|
|
|
var rect = imageX;
|
|
|
|
if (!(rect instanceof $.Rect)) {
|
|
|
|
//they passed individual components instead of a rectangle
|
|
|
|
rect = new $.Rect(imageX, imageY, pixelWidth, pixelHeight);
|
2013-02-11 07:53:51 +04:00
|
|
|
}
|
2014-11-22 03:32:04 +03:00
|
|
|
|
2015-12-12 03:07:23 +03:00
|
|
|
var coordA = this.imageToViewportCoordinates(rect.x, rect.y);
|
|
|
|
var coordB = this._imageToViewportDelta(rect.width, rect.height);
|
2013-06-19 21:33:25 +04:00
|
|
|
return new $.Rect(
|
2013-02-11 07:53:51 +04:00
|
|
|
coordA.x,
|
|
|
|
coordA.y,
|
2014-11-24 22:46:33 +03:00
|
|
|
coordB.x,
|
2015-12-12 03:07:23 +03:00
|
|
|
coordB.y,
|
|
|
|
rect.degrees
|
2013-02-11 07:53:51 +04:00
|
|
|
);
|
2013-08-30 21:59:48 +04:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Translates from a rectangle which describes a portion of
|
|
|
|
* the viewport in point coordinates to image rectangle coordinates.
|
2013-09-04 22:13:25 +04:00
|
|
|
* This method can be called either by passing X,Y,width,height or an
|
|
|
|
* OpenSeadragon.Rect
|
2014-11-22 03:32:04 +03:00
|
|
|
* Note: not accurate with multi-image; use TiledImage.viewportToImageRectangle instead.
|
2013-09-04 22:13:25 +04:00
|
|
|
* @function
|
2016-01-25 00:09:18 +03:00
|
|
|
* @param {(OpenSeadragon.Rect | Number)} viewerX either a rectangle or
|
|
|
|
* the X coordinate of the top left corner of the rectangle in viewport
|
|
|
|
* coordinate system.
|
|
|
|
* @param {Number} [viewerY] the Y coordinate of the top left corner of the rectangle
|
2013-09-04 22:13:25 +04:00
|
|
|
* in viewport coordinate system.
|
2016-01-25 00:09:18 +03:00
|
|
|
* @param {Number} [pointWidth] the width of the rectangle in viewport coordinate system.
|
|
|
|
* @param {Number} [pointHeight] the height of the rectangle in viewport coordinate system.
|
2013-08-30 21:59:48 +04:00
|
|
|
*/
|
2015-12-12 03:07:23 +03:00
|
|
|
viewportToImageRectangle: function(viewerX, viewerY, pointWidth, pointHeight) {
|
|
|
|
var rect = viewerX;
|
|
|
|
if (!(rect instanceof $.Rect)) {
|
|
|
|
//they passed individual components instead of a rectangle
|
|
|
|
rect = new $.Rect(viewerX, viewerY, pointWidth, pointHeight);
|
2013-08-30 21:59:48 +04:00
|
|
|
}
|
2014-11-22 03:32:04 +03:00
|
|
|
|
2015-12-12 03:07:23 +03:00
|
|
|
var coordA = this.viewportToImageCoordinates(rect.x, rect.y);
|
|
|
|
var coordB = this._viewportToImageDelta(rect.width, rect.height);
|
2013-08-30 21:59:48 +04:00
|
|
|
return new $.Rect(
|
|
|
|
coordA.x,
|
|
|
|
coordA.y,
|
2014-11-24 22:46:33 +03:00
|
|
|
coordB.x,
|
2015-12-12 03:07:23 +03:00
|
|
|
coordB.y,
|
|
|
|
rect.degrees
|
2013-08-30 21:59:48 +04:00
|
|
|
);
|
2013-10-04 01:26:44 +04:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2013-10-05 18:21:12 +04:00
|
|
|
* Convert pixel coordinates relative to the viewer element to image
|
2013-10-04 01:26:44 +04:00
|
|
|
* coordinates.
|
2014-11-22 03:32:04 +03:00
|
|
|
* Note: not accurate with multi-image.
|
2013-10-04 01:26:44 +04:00
|
|
|
* @param {OpenSeadragon.Point} pixel
|
|
|
|
* @returns {OpenSeadragon.Point}
|
|
|
|
*/
|
|
|
|
viewerElementToImageCoordinates: function( pixel ) {
|
|
|
|
var point = this.pointFromPixel( pixel, true );
|
|
|
|
return this.viewportToImageCoordinates( point );
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2013-10-05 18:21:12 +04:00
|
|
|
* Convert pixel coordinates relative to the image to
|
2013-10-04 01:26:44 +04:00
|
|
|
* viewer element coordinates.
|
2014-11-22 03:32:04 +03:00
|
|
|
* Note: not accurate with multi-image.
|
2014-02-05 02:02:11 +04:00
|
|
|
* @param {OpenSeadragon.Point} pixel
|
2013-10-04 01:26:44 +04:00
|
|
|
* @returns {OpenSeadragon.Point}
|
|
|
|
*/
|
2014-02-05 02:02:11 +04:00
|
|
|
imageToViewerElementCoordinates: function( pixel ) {
|
|
|
|
var point = this.imageToViewportCoordinates( pixel );
|
|
|
|
return this.pixelFromPoint( point, true );
|
2013-10-04 01:26:44 +04:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2013-10-05 18:21:12 +04:00
|
|
|
* Convert pixel coordinates relative to the window to image coordinates.
|
2014-11-22 03:32:04 +03:00
|
|
|
* Note: not accurate with multi-image.
|
2013-10-04 01:26:44 +04:00
|
|
|
* @param {OpenSeadragon.Point} pixel
|
|
|
|
* @returns {OpenSeadragon.Point}
|
|
|
|
*/
|
|
|
|
windowToImageCoordinates: function( pixel ) {
|
|
|
|
var viewerCoordinates = pixel.minus(
|
|
|
|
OpenSeadragon.getElementPosition( this.viewer.element ));
|
|
|
|
return this.viewerElementToImageCoordinates( viewerCoordinates );
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2013-10-05 18:21:12 +04:00
|
|
|
* Convert image coordinates to pixel coordinates relative to the window.
|
2014-11-22 03:32:04 +03:00
|
|
|
* Note: not accurate with multi-image.
|
2013-10-04 01:26:44 +04:00
|
|
|
* @param {OpenSeadragon.Point} pixel
|
|
|
|
* @returns {OpenSeadragon.Point}
|
|
|
|
*/
|
|
|
|
imageToWindowCoordinates: function( pixel ) {
|
|
|
|
var viewerCoordinates = this.imageToViewerElementCoordinates( pixel );
|
|
|
|
return viewerCoordinates.plus(
|
|
|
|
OpenSeadragon.getElementPosition( this.viewer.element ));
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2013-10-05 18:21:12 +04:00
|
|
|
* Convert pixel coordinates relative to the viewer element to viewport
|
2013-10-04 01:26:44 +04:00
|
|
|
* coordinates.
|
|
|
|
* @param {OpenSeadragon.Point} pixel
|
|
|
|
* @returns {OpenSeadragon.Point}
|
|
|
|
*/
|
|
|
|
viewerElementToViewportCoordinates: function( pixel ) {
|
|
|
|
return this.pointFromPixel( pixel, true );
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2013-10-05 18:21:12 +04:00
|
|
|
* Convert viewport coordinates to pixel coordinates relative to the
|
2013-10-04 01:26:44 +04:00
|
|
|
* viewer element.
|
|
|
|
* @param {OpenSeadragon.Point} point
|
|
|
|
* @returns {OpenSeadragon.Point}
|
|
|
|
*/
|
|
|
|
viewportToViewerElementCoordinates: function( point ) {
|
|
|
|
return this.pixelFromPoint( point, true );
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2013-10-05 18:21:12 +04:00
|
|
|
* Convert pixel coordinates relative to the window to viewport coordinates.
|
2013-10-04 01:26:44 +04:00
|
|
|
* @param {OpenSeadragon.Point} pixel
|
|
|
|
* @returns {OpenSeadragon.Point}
|
|
|
|
*/
|
|
|
|
windowToViewportCoordinates: function( pixel ) {
|
|
|
|
var viewerCoordinates = pixel.minus(
|
|
|
|
OpenSeadragon.getElementPosition( this.viewer.element ));
|
|
|
|
return this.viewerElementToViewportCoordinates( viewerCoordinates );
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2013-10-05 18:21:12 +04:00
|
|
|
* Convert viewport coordinates to pixel coordinates relative to the window.
|
2013-10-04 01:26:44 +04:00
|
|
|
* @param {OpenSeadragon.Point} point
|
|
|
|
* @returns {OpenSeadragon.Point}
|
|
|
|
*/
|
|
|
|
viewportToWindowCoordinates: function( point ) {
|
|
|
|
var viewerCoordinates = this.viewportToViewerElementCoordinates( point );
|
|
|
|
return viewerCoordinates.plus(
|
|
|
|
OpenSeadragon.getElementPosition( this.viewer.element ));
|
|
|
|
},
|
2014-07-18 03:24:28 +04:00
|
|
|
|
2013-10-18 23:16:49 +04:00
|
|
|
/**
|
|
|
|
* Convert a viewport zoom to an image zoom.
|
|
|
|
* Image zoom: ratio of the original image size to displayed image size.
|
|
|
|
* 1 means original image size, 0.5 half size...
|
|
|
|
* Viewport zoom: ratio of the displayed image's width to viewport's width.
|
|
|
|
* 1 means identical width, 2 means image's width is twice the viewport's width...
|
2014-11-22 03:32:04 +03:00
|
|
|
* Note: not accurate with multi-image.
|
2013-10-18 23:16:49 +04:00
|
|
|
* @function
|
|
|
|
* @param {Number} viewportZoom The viewport zoom
|
|
|
|
* target zoom.
|
|
|
|
* @returns {Number} imageZoom The image zoom
|
|
|
|
*/
|
|
|
|
viewportToImageZoom: function( viewportZoom ) {
|
2014-11-22 03:32:04 +03:00
|
|
|
if (this.viewer && this.viewer.world.getItemCount() > 1) {
|
|
|
|
$.console.error('[Viewport.viewportToImageZoom] is not accurate with multi-image.');
|
|
|
|
}
|
|
|
|
|
|
|
|
var imageWidth = this.contentSize.x;
|
2014-10-22 04:11:09 +04:00
|
|
|
var containerWidth = this._containerInnerSize.x;
|
2014-11-22 02:18:25 +03:00
|
|
|
var scale = this.homeBounds.width;
|
|
|
|
var viewportToImageZoomRatio = (containerWidth / imageWidth) * scale;
|
2013-10-18 23:16:49 +04:00
|
|
|
return viewportZoom * viewportToImageZoomRatio;
|
|
|
|
},
|
2014-07-18 03:24:28 +04:00
|
|
|
|
2013-10-04 01:26:44 +04:00
|
|
|
/**
|
2013-10-18 23:16:49 +04:00
|
|
|
* Convert an image zoom to a viewport zoom.
|
|
|
|
* Image zoom: ratio of the original image size to displayed image size.
|
|
|
|
* 1 means original image size, 0.5 half size...
|
|
|
|
* Viewport zoom: ratio of the displayed image's width to viewport's width.
|
|
|
|
* 1 means identical width, 2 means image's width is twice the viewport's width...
|
2014-11-22 03:32:04 +03:00
|
|
|
* Note: not accurate with multi-image.
|
2013-10-04 01:26:44 +04:00
|
|
|
* @function
|
2013-10-18 23:16:49 +04:00
|
|
|
* @param {Number} imageZoom The image zoom
|
2013-10-04 01:26:44 +04:00
|
|
|
* target zoom.
|
2013-10-18 23:16:49 +04:00
|
|
|
* @returns {Number} viewportZoom The viewport zoom
|
2013-10-04 01:26:44 +04:00
|
|
|
*/
|
2013-10-18 23:16:49 +04:00
|
|
|
imageToViewportZoom: function( imageZoom ) {
|
2014-11-22 03:32:04 +03:00
|
|
|
if (this.viewer && this.viewer.world.getItemCount() > 1) {
|
|
|
|
$.console.error('[Viewport.imageToViewportZoom] is not accurate with multi-image.');
|
|
|
|
}
|
|
|
|
|
|
|
|
var imageWidth = this.contentSize.x;
|
2014-10-22 04:11:09 +04:00
|
|
|
var containerWidth = this._containerInnerSize.x;
|
2014-11-22 02:18:25 +03:00
|
|
|
var scale = this.homeBounds.width;
|
|
|
|
var viewportToImageZoomRatio = (imageWidth / containerWidth) / scale;
|
2013-10-18 23:16:49 +04:00
|
|
|
return imageZoom * viewportToImageZoomRatio;
|
2011-12-06 07:50:25 +04:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
}( OpenSeadragon ));
|