mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-22 05:06:09 +03:00
Merge pull request #1441 from nelsonn3c/feature/flip
Adds flip/mirror slides feature.
This commit is contained in:
commit
e01e36794d
BIN
images/flip_grouphover.png
Normal file
BIN
images/flip_grouphover.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.8 KiB |
BIN
images/flip_hover.png
Normal file
BIN
images/flip_hover.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.8 KiB |
BIN
images/flip_pressed.png
Normal file
BIN
images/flip_pressed.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.8 KiB |
BIN
images/flip_rest.png
Normal file
BIN
images/flip_rest.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.8 KiB |
@ -500,6 +500,10 @@ $.Drawer.prototype = {
|
|||||||
|
|
||||||
if ( this.viewport.degrees !== 0 ) {
|
if ( this.viewport.degrees !== 0 ) {
|
||||||
this._offsetForRotation({degrees: this.viewport.degrees});
|
this._offsetForRotation({degrees: this.viewport.degrees});
|
||||||
|
} else{
|
||||||
|
if(this.viewer.viewport.flipped) {
|
||||||
|
this._flip();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (tiledImage.getRotation(true) % 360 !== 0) {
|
if (tiledImage.getRotation(true) % 360 !== 0) {
|
||||||
this._offsetForRotation({
|
this._offsetForRotation({
|
||||||
@ -620,10 +624,28 @@ $.Drawer.prototype = {
|
|||||||
context.save();
|
context.save();
|
||||||
|
|
||||||
context.translate(point.x, point.y);
|
context.translate(point.x, point.y);
|
||||||
|
if(this.viewer.viewport.flipped){
|
||||||
|
context.rotate(Math.PI / 180 * -options.degrees);
|
||||||
|
context.scale(-1, 1);
|
||||||
|
} else{
|
||||||
context.rotate(Math.PI / 180 * options.degrees);
|
context.rotate(Math.PI / 180 * options.degrees);
|
||||||
|
}
|
||||||
context.translate(-point.x, -point.y);
|
context.translate(-point.x, -point.y);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// private
|
||||||
|
_flip: function(options) {
|
||||||
|
options = options || {};
|
||||||
|
var point = options.point ?
|
||||||
|
options.point.times($.pixelDensityRatio) :
|
||||||
|
this.getCanvasCenter();
|
||||||
|
var context = this._getContext(options.useSketch);
|
||||||
|
|
||||||
|
context.translate(point.x, 0);
|
||||||
|
context.scale(-1, 1);
|
||||||
|
context.translate(-point.x, 0);
|
||||||
|
},
|
||||||
|
|
||||||
// private
|
// private
|
||||||
_restoreRotationChanges: function(useSketch) {
|
_restoreRotationChanges: function(useSketch) {
|
||||||
var context = this._getContext(useSketch);
|
var context = this._getContext(useSketch);
|
||||||
|
@ -208,12 +208,14 @@ $.Navigator = function( options ){
|
|||||||
var degrees = options.viewer.viewport ?
|
var degrees = options.viewer.viewport ?
|
||||||
options.viewer.viewport.getRotation() :
|
options.viewer.viewport.getRotation() :
|
||||||
options.viewer.degrees || 0;
|
options.viewer.degrees || 0;
|
||||||
|
|
||||||
rotate(degrees);
|
rotate(degrees);
|
||||||
options.viewer.addHandler("rotate", function (args) {
|
options.viewer.addHandler("rotate", function (args) {
|
||||||
rotate(args.degrees);
|
rotate(args.degrees);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Remove the base class' (Viewer's) innerTracker and replace it with our own
|
// Remove the base class' (Viewer's) innerTracker and replace it with our own
|
||||||
this.innerTracker.destroy();
|
this.innerTracker.destroy();
|
||||||
this.innerTracker = new $.MouseTracker({
|
this.innerTracker = new $.MouseTracker({
|
||||||
@ -271,6 +273,22 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /*
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
/* Flip navigator element
|
||||||
|
* @param {Boolean} state - Flip state to set.
|
||||||
|
*/
|
||||||
|
setFlip: function(state) {
|
||||||
|
this.viewport.setFlip(state);
|
||||||
|
|
||||||
|
this.setDisplayTransform(this.viewer.viewport.getFlip() ? "scale(-1,1)" : "scale(1,1)");
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
setDisplayTransform: function(rule) {
|
||||||
|
setElementTransform(this.displayRegion, rule);
|
||||||
|
setElementTransform(this.canvas, rule);
|
||||||
|
setElementTransform(this.element, rule);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to update the navigator minimap's viewport rectangle when a change in the viewer's viewport occurs.
|
* Used to update the navigator minimap's viewport rectangle when a change in the viewer's viewport occurs.
|
||||||
@ -399,6 +417,7 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /*
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @inner
|
* @inner
|
||||||
@ -406,6 +425,9 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /*
|
|||||||
*/
|
*/
|
||||||
function onCanvasClick( event ) {
|
function onCanvasClick( event ) {
|
||||||
if ( event.quick && this.viewer.viewport ) {
|
if ( event.quick && this.viewer.viewport ) {
|
||||||
|
if(this.viewer.viewport.flipped){
|
||||||
|
event.position.x = this.viewport.getContainerSize().x - event.position.x;
|
||||||
|
}
|
||||||
this.viewer.viewport.panTo(this.viewport.pointFromPixel(event.position));
|
this.viewer.viewport.panTo(this.viewport.pointFromPixel(event.position));
|
||||||
this.viewer.viewport.applyConstraints();
|
this.viewer.viewport.applyConstraints();
|
||||||
}
|
}
|
||||||
@ -424,6 +446,11 @@ function onCanvasDrag( event ) {
|
|||||||
if( !this.panVertical ){
|
if( !this.panVertical ){
|
||||||
event.delta.y = 0;
|
event.delta.y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this.viewer.viewport.flipped){
|
||||||
|
event.delta.x = -event.delta.x;
|
||||||
|
}
|
||||||
|
|
||||||
this.viewer.viewport.panBy(
|
this.viewer.viewport.panBy(
|
||||||
this.viewport.deltaPointsFromPixels(
|
this.viewport.deltaPointsFromPixels(
|
||||||
event.delta
|
event.delta
|
||||||
@ -488,11 +515,15 @@ function onCanvasScroll( event ) {
|
|||||||
* @param {Number} degrees
|
* @param {Number} degrees
|
||||||
*/
|
*/
|
||||||
function _setTransformRotate( element, degrees ) {
|
function _setTransformRotate( element, degrees ) {
|
||||||
element.style.webkitTransform = "rotate(" + degrees + "deg)";
|
setElementTransform(element, "rotate(" + degrees + "deg)");
|
||||||
element.style.mozTransform = "rotate(" + degrees + "deg)";
|
}
|
||||||
element.style.msTransform = "rotate(" + degrees + "deg)";
|
|
||||||
element.style.oTransform = "rotate(" + degrees + "deg)";
|
function setElementTransform( element, rule ) {
|
||||||
element.style.transform = "rotate(" + degrees + "deg)";
|
element.style.webkitTransform = rule;
|
||||||
|
element.style.mozTransform = rule;
|
||||||
|
element.style.msTransform = rule;
|
||||||
|
element.style.oTransform = rule;
|
||||||
|
element.style.transform = rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
}( OpenSeadragon ));
|
}( OpenSeadragon ));
|
||||||
|
@ -206,6 +206,9 @@
|
|||||||
* @property {Number} [degrees=0]
|
* @property {Number} [degrees=0]
|
||||||
* Initial rotation.
|
* Initial rotation.
|
||||||
*
|
*
|
||||||
|
* @property {Boolean} [flipped=false]
|
||||||
|
* Initial flip state.
|
||||||
|
*
|
||||||
* @property {Number} [minZoomLevel=null]
|
* @property {Number} [minZoomLevel=null]
|
||||||
*
|
*
|
||||||
* @property {Number} [maxZoomLevel=null]
|
* @property {Number} [maxZoomLevel=null]
|
||||||
@ -478,6 +481,10 @@
|
|||||||
* Note: {@link OpenSeadragon.Options.showNavigationControl} is overriding
|
* Note: {@link OpenSeadragon.Options.showNavigationControl} is overriding
|
||||||
* this setting when set to false.
|
* this setting when set to false.
|
||||||
*
|
*
|
||||||
|
* @property {Boolean} [showFlipControl=false]
|
||||||
|
* If true then the flip controls will be displayed as part of the
|
||||||
|
* standard controls.
|
||||||
|
*
|
||||||
* @property {Boolean} [showSequenceControl=true]
|
* @property {Boolean} [showSequenceControl=true]
|
||||||
* If sequenceMode is true, then provide buttons for navigating forward and
|
* If sequenceMode is true, then provide buttons for navigating forward and
|
||||||
* backward through the images.
|
* backward through the images.
|
||||||
@ -688,6 +695,12 @@
|
|||||||
* @property {String} rotateright.HOVER
|
* @property {String} rotateright.HOVER
|
||||||
* @property {String} rotateright.DOWN
|
* @property {String} rotateright.DOWN
|
||||||
*
|
*
|
||||||
|
* @property {Object} flip - Images for the flip button.
|
||||||
|
* @property {String} flip.REST
|
||||||
|
* @property {String} flip.GROUP
|
||||||
|
* @property {String} flip.HOVER
|
||||||
|
* @property {String} flip.DOWN
|
||||||
|
*
|
||||||
* @property {Object} previous - Images for the previous button.
|
* @property {Object} previous - Images for the previous button.
|
||||||
* @property {String} previous.REST
|
* @property {String} previous.REST
|
||||||
* @property {String} previous.GROUP
|
* @property {String} previous.GROUP
|
||||||
@ -1120,6 +1133,7 @@ function OpenSeadragon( options ){
|
|||||||
showHomeControl: true, //HOME
|
showHomeControl: true, //HOME
|
||||||
showFullPageControl: true, //FULL
|
showFullPageControl: true, //FULL
|
||||||
showRotationControl: false, //ROTATION
|
showRotationControl: false, //ROTATION
|
||||||
|
showFlipControl: false, //FLIP
|
||||||
controlsFadeDelay: 2000, //ZOOM/HOME/FULL/SEQUENCE
|
controlsFadeDelay: 2000, //ZOOM/HOME/FULL/SEQUENCE
|
||||||
controlsFadeLength: 1500, //ZOOM/HOME/FULL/SEQUENCE
|
controlsFadeLength: 1500, //ZOOM/HOME/FULL/SEQUENCE
|
||||||
mouseNavEnabled: true, //GENERAL MOUSE INTERACTIVITY
|
mouseNavEnabled: true, //GENERAL MOUSE INTERACTIVITY
|
||||||
@ -1141,6 +1155,9 @@ function OpenSeadragon( options ){
|
|||||||
// INITIAL ROTATION
|
// INITIAL ROTATION
|
||||||
degrees: 0,
|
degrees: 0,
|
||||||
|
|
||||||
|
// INITIAL FLIP STATE
|
||||||
|
flipped: false,
|
||||||
|
|
||||||
// APPEARANCE
|
// APPEARANCE
|
||||||
opacity: 1,
|
opacity: 1,
|
||||||
preload: false,
|
preload: false,
|
||||||
@ -1209,6 +1226,12 @@ function OpenSeadragon( options ){
|
|||||||
HOVER: 'rotateright_hover.png',
|
HOVER: 'rotateright_hover.png',
|
||||||
DOWN: 'rotateright_pressed.png'
|
DOWN: 'rotateright_pressed.png'
|
||||||
},
|
},
|
||||||
|
flip: { // Flip icon designed by Yaroslav Samoylov from the Noun Project and modified by Nelson Campos ncampos@criteriamarathon.com, https://thenounproject.com/term/flip/136289/
|
||||||
|
REST: 'flip_rest.png',
|
||||||
|
GROUP: 'flip_grouphover.png',
|
||||||
|
HOVER: 'flip_hover.png',
|
||||||
|
DOWN: 'flip_pressed.png'
|
||||||
|
},
|
||||||
previous: {
|
previous: {
|
||||||
REST: 'previous_rest.png',
|
REST: 'previous_rest.png',
|
||||||
GROUP: 'previous_grouphover.png',
|
GROUP: 'previous_grouphover.png',
|
||||||
|
@ -57,7 +57,8 @@ var I18N = {
|
|||||||
NextPage: "Next page",
|
NextPage: "Next page",
|
||||||
PreviousPage: "Previous page",
|
PreviousPage: "Previous page",
|
||||||
RotateLeft: "Rotate left",
|
RotateLeft: "Rotate left",
|
||||||
RotateRight: "Rotate right"
|
RotateRight: "Rotate right",
|
||||||
|
Flip: "Flip Horizontally"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1886,6 +1886,10 @@ function drawTiles( tiledImage, lastDrawn ) {
|
|||||||
degrees: tiledImage.viewport.degrees,
|
degrees: tiledImage.viewport.degrees,
|
||||||
useSketch: useSketch
|
useSketch: useSketch
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
if(tiledImage._drawer.viewer.viewport.flipped) {
|
||||||
|
tiledImage._drawer._flip({});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (tiledImage.getRotation(true) % 360 !== 0) {
|
if (tiledImage.getRotation(true) % 360 !== 0) {
|
||||||
tiledImage._drawer._offsetForRotation({
|
tiledImage._drawer._offsetForRotation({
|
||||||
@ -1969,6 +1973,10 @@ function drawTiles( tiledImage, lastDrawn ) {
|
|||||||
}
|
}
|
||||||
if (tiledImage.viewport.degrees !== 0) {
|
if (tiledImage.viewport.degrees !== 0) {
|
||||||
tiledImage._drawer._restoreRotationChanges(useSketch);
|
tiledImage._drawer._restoreRotationChanges(useSketch);
|
||||||
|
} else{
|
||||||
|
if(tiledImage._drawer.viewer.viewport.flipped) {
|
||||||
|
tiledImage._drawer._flip({});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,6 +367,7 @@ $.Viewer = function( options ) {
|
|||||||
maxZoomLevel: this.maxZoomLevel,
|
maxZoomLevel: this.maxZoomLevel,
|
||||||
viewer: this,
|
viewer: this,
|
||||||
degrees: this.degrees,
|
degrees: this.degrees,
|
||||||
|
flipped: this.flipped,
|
||||||
navigatorRotate: this.navigatorRotate,
|
navigatorRotate: this.navigatorRotate,
|
||||||
homeFillsViewer: this.homeFillsViewer,
|
homeFillsViewer: this.homeFillsViewer,
|
||||||
margins: this.viewportMargins
|
margins: this.viewportMargins
|
||||||
@ -1674,6 +1675,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|||||||
onFullScreenHandler = $.delegate( this, onFullScreen ),
|
onFullScreenHandler = $.delegate( this, onFullScreen ),
|
||||||
onRotateLeftHandler = $.delegate( this, onRotateLeft ),
|
onRotateLeftHandler = $.delegate( this, onRotateLeft ),
|
||||||
onRotateRightHandler = $.delegate( this, onRotateRight ),
|
onRotateRightHandler = $.delegate( this, onRotateRight ),
|
||||||
|
onFlipHandler = $.delegate( this, onFlip),
|
||||||
onFocusHandler = $.delegate( this, onFocus ),
|
onFocusHandler = $.delegate( this, onFocus ),
|
||||||
onBlurHandler = $.delegate( this, onBlur ),
|
onBlurHandler = $.delegate( this, onBlur ),
|
||||||
navImages = this.navImages,
|
navImages = this.navImages,
|
||||||
@ -1685,7 +1687,8 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|||||||
|
|
||||||
if( this.zoomInButton || this.zoomOutButton ||
|
if( this.zoomInButton || this.zoomOutButton ||
|
||||||
this.homeButton || this.fullPageButton ||
|
this.homeButton || this.fullPageButton ||
|
||||||
this.rotateLeftButton || this.rotateRightButton ) {
|
this.rotateLeftButton || this.rotateRightButton ||
|
||||||
|
this.flipButton ) {
|
||||||
//if we are binding to custom buttons then layout and
|
//if we are binding to custom buttons then layout and
|
||||||
//grouping is the responsibility of the page author
|
//grouping is the responsibility of the page author
|
||||||
useGroup = false;
|
useGroup = false;
|
||||||
@ -1789,7 +1792,22 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|||||||
onFocus: onFocusHandler,
|
onFocus: onFocusHandler,
|
||||||
onBlur: onBlurHandler
|
onBlur: onBlurHandler
|
||||||
}));
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( this.showFlipControl ) {
|
||||||
|
buttons.push( this.flipButton = new $.Button({
|
||||||
|
element: this.flipButton ? $.getElement( this.flipButton ) : null,
|
||||||
|
clickTimeThreshold: this.clickTimeThreshold,
|
||||||
|
clickDistThreshold: this.clickDistThreshold,
|
||||||
|
tooltip: $.getString( "Tooltips.Flip" ),
|
||||||
|
srcRest: resolveUrl( this.prefixUrl, navImages.flip.REST ),
|
||||||
|
srcGroup: resolveUrl( this.prefixUrl, navImages.flip.GROUP ),
|
||||||
|
srcHover: resolveUrl( this.prefixUrl, navImages.flip.HOVER ),
|
||||||
|
srcDown: resolveUrl( this.prefixUrl, navImages.flip.DOWN ),
|
||||||
|
onRelease: onFlipHandler,
|
||||||
|
onFocus: onFocusHandler,
|
||||||
|
onBlur: onBlurHandler
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( useGroup ) {
|
if ( useGroup ) {
|
||||||
@ -2602,6 +2620,25 @@ function onCanvasKeyPress( event ) {
|
|||||||
this.viewport.applyConstraints();
|
this.viewport.applyConstraints();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
case 114: //r - 90 degrees clockwise rotation
|
||||||
|
if(this.viewport.flipped){
|
||||||
|
this.viewport.setRotation(this.viewport.degrees - 90);
|
||||||
|
} else{
|
||||||
|
this.viewport.setRotation(this.viewport.degrees + 90);
|
||||||
|
}
|
||||||
|
this.viewport.applyConstraints();
|
||||||
|
return false;
|
||||||
|
case 82: //R - 90 degrees counterclockwise rotation
|
||||||
|
if(this.viewport.flipped){
|
||||||
|
this.viewport.setRotation(this.viewport.degrees + 90);
|
||||||
|
} else{
|
||||||
|
this.viewport.setRotation(this.viewport.degrees - 90);
|
||||||
|
}
|
||||||
|
this.viewport.applyConstraints();
|
||||||
|
return false;
|
||||||
|
case 102: //f
|
||||||
|
this.viewport.toggleFlip();
|
||||||
|
return false;
|
||||||
default:
|
default:
|
||||||
// console.log( 'navigator keycode %s', event.keyCode );
|
// console.log( 'navigator keycode %s', event.keyCode );
|
||||||
return true;
|
return true;
|
||||||
@ -2620,6 +2657,9 @@ function onCanvasClick( event ) {
|
|||||||
if ( !haveKeyboardFocus ) {
|
if ( !haveKeyboardFocus ) {
|
||||||
this.canvas.focus();
|
this.canvas.focus();
|
||||||
}
|
}
|
||||||
|
if(this.viewport.flipped){
|
||||||
|
event.position.x = this.viewport.getContainerSize().x - event.position.x;
|
||||||
|
}
|
||||||
|
|
||||||
var canvasClickEventArgs = {
|
var canvasClickEventArgs = {
|
||||||
tracker: event.eventSource,
|
tracker: event.eventSource,
|
||||||
@ -2739,6 +2779,9 @@ function onCanvasDrag( event ) {
|
|||||||
if( !this.panVertical ){
|
if( !this.panVertical ){
|
||||||
event.delta.y = 0;
|
event.delta.y = 0;
|
||||||
}
|
}
|
||||||
|
if(this.viewport.flipped){
|
||||||
|
event.delta.x = -event.delta.x;
|
||||||
|
}
|
||||||
|
|
||||||
if( this.constrainDuringPan ){
|
if( this.constrainDuringPan ){
|
||||||
var delta = this.viewport.deltaPointsFromPixels( event.delta.negate() );
|
var delta = this.viewport.deltaPointsFromPixels( event.delta.negate() );
|
||||||
@ -3064,6 +3107,10 @@ function onCanvasScroll( event ) {
|
|||||||
if (deltaScrollTime > this.minScrollDeltaTime) {
|
if (deltaScrollTime > this.minScrollDeltaTime) {
|
||||||
this._lastScrollTime = thisScrollTime;
|
this._lastScrollTime = thisScrollTime;
|
||||||
|
|
||||||
|
if(this.viewport.flipped){
|
||||||
|
event.position.x = this.viewport.getContainerSize().x - event.position.x;
|
||||||
|
}
|
||||||
|
|
||||||
if ( !event.preventDefaultAction && this.viewport ) {
|
if ( !event.preventDefaultAction && this.viewport ) {
|
||||||
gestureSettings = this.gestureSettingsByDeviceType( event.pointerType );
|
gestureSettings = this.gestureSettingsByDeviceType( event.pointerType );
|
||||||
if ( gestureSettings.scrollToZoom ) {
|
if ( gestureSettings.scrollToZoom ) {
|
||||||
@ -3429,11 +3476,11 @@ function onFullScreen() {
|
|||||||
function onRotateLeft() {
|
function onRotateLeft() {
|
||||||
if ( this.viewport ) {
|
if ( this.viewport ) {
|
||||||
var currRotation = this.viewport.getRotation();
|
var currRotation = this.viewport.getRotation();
|
||||||
if (currRotation === 0) {
|
|
||||||
currRotation = 270;
|
if ( this.viewport.flipped ){
|
||||||
}
|
currRotation = $.positiveModulo(currRotation + 90, 360);
|
||||||
else {
|
} else {
|
||||||
currRotation -= 90;
|
currRotation = $.positiveModulo(currRotation - 90, 360);
|
||||||
}
|
}
|
||||||
this.viewport.setRotation(currRotation);
|
this.viewport.setRotation(currRotation);
|
||||||
}
|
}
|
||||||
@ -3445,16 +3492,22 @@ function onRotateLeft() {
|
|||||||
function onRotateRight() {
|
function onRotateRight() {
|
||||||
if ( this.viewport ) {
|
if ( this.viewport ) {
|
||||||
var currRotation = this.viewport.getRotation();
|
var currRotation = this.viewport.getRotation();
|
||||||
if (currRotation === 270) {
|
|
||||||
currRotation = 0;
|
if ( this.viewport.flipped ){
|
||||||
}
|
currRotation = $.positiveModulo(currRotation - 90, 360);
|
||||||
else {
|
} else {
|
||||||
currRotation += 90;
|
currRotation = $.positiveModulo(currRotation + 90, 360);
|
||||||
}
|
}
|
||||||
this.viewport.setRotation(currRotation);
|
this.viewport.setRotation(currRotation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note: When pressed flip control button
|
||||||
|
*/
|
||||||
|
function onFlip() {
|
||||||
|
this.viewport.toggleFlip();
|
||||||
|
}
|
||||||
|
|
||||||
function onPrevious(){
|
function onPrevious(){
|
||||||
var previous = this._sequenceIndex - 1;
|
var previous = this._sequenceIndex - 1;
|
||||||
|
@ -107,6 +107,7 @@ $.Viewport = function( options ) {
|
|||||||
minZoomLevel: $.DEFAULT_SETTINGS.minZoomLevel,
|
minZoomLevel: $.DEFAULT_SETTINGS.minZoomLevel,
|
||||||
maxZoomLevel: $.DEFAULT_SETTINGS.maxZoomLevel,
|
maxZoomLevel: $.DEFAULT_SETTINGS.maxZoomLevel,
|
||||||
degrees: $.DEFAULT_SETTINGS.degrees,
|
degrees: $.DEFAULT_SETTINGS.degrees,
|
||||||
|
flipped: $.DEFAULT_SETTINGS.flipped,
|
||||||
homeFillsViewer: $.DEFAULT_SETTINGS.homeFillsViewer
|
homeFillsViewer: $.DEFAULT_SETTINGS.homeFillsViewer
|
||||||
|
|
||||||
}, options );
|
}, options );
|
||||||
@ -880,7 +881,6 @@ $.Viewport.prototype = {
|
|||||||
if (!this.viewer || !this.viewer.drawer.canRotate()) {
|
if (!this.viewer || !this.viewer.drawer.canRotate()) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.degrees = $.positiveModulo(degrees, 360);
|
this.degrees = $.positiveModulo(degrees, 360);
|
||||||
this._setContentBounds(
|
this._setContentBounds(
|
||||||
this.viewer.world.getHomeBounds(),
|
this.viewer.world.getHomeBounds(),
|
||||||
@ -1518,7 +1518,58 @@ $.Viewport.prototype = {
|
|||||||
var scale = this._contentBoundsNoRotate.width;
|
var scale = this._contentBoundsNoRotate.width;
|
||||||
var viewportToImageZoomRatio = (imageWidth / containerWidth) / scale;
|
var viewportToImageZoomRatio = (imageWidth / containerWidth) / scale;
|
||||||
return imageZoom * viewportToImageZoomRatio;
|
return imageZoom * viewportToImageZoomRatio;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles flip state and demands a new drawing on navigator and viewer objects.
|
||||||
|
* @function
|
||||||
|
* @return {OpenSeadragon.Viewport} Chainable.
|
||||||
|
*/
|
||||||
|
toggleFlip: function() {
|
||||||
|
this.setFlip(!this.getFlip());
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets flip state stored on viewport.
|
||||||
|
* @function
|
||||||
|
* @return {Boolean} Flip state.
|
||||||
|
*/
|
||||||
|
getFlip: function() {
|
||||||
|
return this.flipped;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets flip state according to the state input argument.
|
||||||
|
* @function
|
||||||
|
* @param {Boolean} state - Flip state to set.
|
||||||
|
* @return {OpenSeadragon.Viewport} Chainable.
|
||||||
|
*/
|
||||||
|
setFlip: function( state ) {
|
||||||
|
if ( this.flipped === state ) {
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.flipped = state;
|
||||||
|
if(this.viewer.navigator){
|
||||||
|
this.viewer.navigator.setFlip(this.getFlip());
|
||||||
|
}
|
||||||
|
this.viewer.forceRedraw();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Raised when flip state has been changed.
|
||||||
|
*
|
||||||
|
* @event flip
|
||||||
|
* @memberof OpenSeadragon.Viewer
|
||||||
|
* @type {object}
|
||||||
|
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.
|
||||||
|
* @property {Number} flipped - The flip state after this change.
|
||||||
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||||
|
*/
|
||||||
|
this.viewer.raiseEvent('flip', {"flipped": state});
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}( OpenSeadragon ));
|
}( OpenSeadragon ));
|
||||||
|
@ -118,6 +118,7 @@
|
|||||||
assert,
|
assert,
|
||||||
actual,
|
actual,
|
||||||
expected,
|
expected,
|
||||||
|
1e-15,
|
||||||
"Correctly converted coordinates " + orig
|
"Correctly converted coordinates " + orig
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -136,8 +137,8 @@
|
|||||||
viewer.open(DZI_PATH);
|
viewer.open(DZI_PATH);
|
||||||
};
|
};
|
||||||
|
|
||||||
function assertPointsEquals(assert, actual, expected, message) {
|
function assertPointsEquals(assert, actual, expected, variance, message) {
|
||||||
Util.assertPointsEquals(assert, actual, expected, 1e-15, message);
|
Util.assertPointsEquals(assert, actual, expected, variance, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests start here.
|
// Tests start here.
|
||||||
@ -470,6 +471,32 @@
|
|||||||
bounds,
|
bounds,
|
||||||
EPSILON,
|
EPSILON,
|
||||||
"Viewport.applyConstraints should move viewport.");
|
"Viewport.applyConstraints should move viewport.");
|
||||||
|
|
||||||
|
done();
|
||||||
|
};
|
||||||
|
viewer.addHandler('open', openHandler);
|
||||||
|
viewer.open(DZI_PATH);
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('applyConstraints flipped', function(assert) {
|
||||||
|
var done = assert.async();
|
||||||
|
var openHandler = function() {
|
||||||
|
viewer.removeHandler('open', openHandler);
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
|
||||||
|
viewport.setFlip(true);
|
||||||
|
|
||||||
|
viewport.fitBounds(new OpenSeadragon.Rect(1, 1, 1, 1), true);
|
||||||
|
viewport.visibilityRatio = 0.3;
|
||||||
|
viewport.applyConstraints(true);
|
||||||
|
var bounds = viewport.getBounds();
|
||||||
|
Util.assertRectangleEquals(
|
||||||
|
assert,
|
||||||
|
new OpenSeadragon.Rect(0.7, 0.7, 1, 1),
|
||||||
|
bounds,
|
||||||
|
EPSILON,
|
||||||
|
"Viewport.applyConstraints should move flipped viewport.");
|
||||||
|
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
viewer.addHandler('open', openHandler);
|
viewer.addHandler('open', openHandler);
|
||||||
@ -514,6 +541,32 @@
|
|||||||
new OpenSeadragon.Rect(1, 0, Math.sqrt(2), Math.sqrt(2), 45),
|
new OpenSeadragon.Rect(1, 0, Math.sqrt(2), Math.sqrt(2), 45),
|
||||||
EPSILON,
|
EPSILON,
|
||||||
"Viewport.applyConstraints with rotation should move viewport.");
|
"Viewport.applyConstraints with rotation should move viewport.");
|
||||||
|
|
||||||
|
done();
|
||||||
|
};
|
||||||
|
viewer.addHandler('open', openHandler);
|
||||||
|
viewer.open(DZI_PATH);
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('applyConstraints flipped with rotation', function(assert) {
|
||||||
|
var done = assert.async();
|
||||||
|
var openHandler = function() {
|
||||||
|
viewer.removeHandler('open', openHandler);
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
|
||||||
|
viewport.setFlip(true);
|
||||||
|
viewport.setRotation(45);
|
||||||
|
|
||||||
|
viewport.fitBounds(new OpenSeadragon.Rect(1, 1, 1, 1), true);
|
||||||
|
viewport.applyConstraints(true);
|
||||||
|
var bounds = viewport.getBounds();
|
||||||
|
Util.assertRectangleEquals(
|
||||||
|
assert,
|
||||||
|
bounds,
|
||||||
|
new OpenSeadragon.Rect(1, 0, Math.sqrt(2), Math.sqrt(2), 45),
|
||||||
|
EPSILON,
|
||||||
|
"Viewport.applyConstraints flipped and with rotation should move viewport.");
|
||||||
|
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
viewer.addHandler('open', openHandler);
|
viewer.addHandler('open', openHandler);
|
||||||
@ -742,6 +795,30 @@
|
|||||||
viewer.open(DZI_PATH);
|
viewer.open(DZI_PATH);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QUnit.test('panBy flipped', function(assert) {
|
||||||
|
var done = assert.async();
|
||||||
|
var openHandler = function(event) {
|
||||||
|
viewer.removeHandler('open', openHandler);
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
|
||||||
|
viewport.setFlip(true);
|
||||||
|
|
||||||
|
for (var i = 0; i < testPoints.length; i++){
|
||||||
|
var expected = viewport.getCenter().plus(testPoints[i]);
|
||||||
|
viewport.panBy(testPoints[i], true);
|
||||||
|
assert.propEqual(
|
||||||
|
viewport.getCenter(),
|
||||||
|
expected,
|
||||||
|
"Panned flipped by the correct amount."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
done();
|
||||||
|
};
|
||||||
|
viewer.addHandler('open', openHandler);
|
||||||
|
viewer.open(DZI_PATH);
|
||||||
|
});
|
||||||
|
|
||||||
QUnit.test('panTo', function(assert) {
|
QUnit.test('panTo', function(assert) {
|
||||||
var done = assert.async();
|
var done = assert.async();
|
||||||
var openHandler = function(event) {
|
var openHandler = function(event) {
|
||||||
@ -763,6 +840,29 @@
|
|||||||
viewer.open(DZI_PATH);
|
viewer.open(DZI_PATH);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QUnit.test('panTo flipped', function(assert) {
|
||||||
|
var done = assert.async();
|
||||||
|
var openHandler = function(event) {
|
||||||
|
viewer.removeHandler('open', openHandler);
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
|
||||||
|
viewport.setFlip(true);
|
||||||
|
|
||||||
|
for (var i = 0; i < testPoints.length; i++){
|
||||||
|
viewport.panTo(testPoints[i], true);
|
||||||
|
assert.propEqual(
|
||||||
|
viewport.getCenter(),
|
||||||
|
testPoints[i],
|
||||||
|
"Panned flipped to the correct location."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
done();
|
||||||
|
};
|
||||||
|
viewer.addHandler('open', openHandler);
|
||||||
|
viewer.open(DZI_PATH);
|
||||||
|
});
|
||||||
|
|
||||||
QUnit.test('zoomBy no ref point', function(assert) {
|
QUnit.test('zoomBy no ref point', function(assert) {
|
||||||
var done = assert.async();
|
var done = assert.async();
|
||||||
var openHandler = function(event) {
|
var openHandler = function(event) {
|
||||||
@ -821,6 +921,45 @@
|
|||||||
viewer.open(DZI_PATH);
|
viewer.open(DZI_PATH);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QUnit.test('zoomBy flipped with ref point', function(assert) {
|
||||||
|
var done = assert.async();
|
||||||
|
var openHandler = function(event) {
|
||||||
|
viewer.removeHandler('open', openHandler);
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
|
||||||
|
viewport.setFlip(true);
|
||||||
|
|
||||||
|
var expectedFlippedCenters = [
|
||||||
|
new OpenSeadragon.Point(5, 5),
|
||||||
|
new OpenSeadragon.Point(6.996, 6.996),
|
||||||
|
new OpenSeadragon.Point(7.246, 6.996),
|
||||||
|
new OpenSeadragon.Point(7.246, 6.996),
|
||||||
|
new OpenSeadragon.Point(7.621, 7.371),
|
||||||
|
new OpenSeadragon.Point(7.621, 7.371),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (var i = 0; i < testZoomLevels.length; i++) {
|
||||||
|
viewport.zoomBy(testZoomLevels[i], testPoints[i], true);
|
||||||
|
assert.propEqual(
|
||||||
|
testZoomLevels[i],
|
||||||
|
viewport.getZoom(),
|
||||||
|
"Zoomed flipped by the correct amount."
|
||||||
|
);
|
||||||
|
assertPointsEquals(
|
||||||
|
assert,
|
||||||
|
expectedFlippedCenters[i],
|
||||||
|
viewport.getCenter(),
|
||||||
|
1e-6,
|
||||||
|
"Panned flipped to the correct location."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
done();
|
||||||
|
};
|
||||||
|
viewer.addHandler('open', openHandler);
|
||||||
|
viewer.open(DZI_PATH);
|
||||||
|
});
|
||||||
|
|
||||||
QUnit.test('zoomTo no ref point', function(assert) {
|
QUnit.test('zoomTo no ref point', function(assert) {
|
||||||
var done = assert.async();
|
var done = assert.async();
|
||||||
var openHandler = function(event) {
|
var openHandler = function(event) {
|
||||||
@ -866,8 +1005,8 @@
|
|||||||
);
|
);
|
||||||
assertPointsEquals(
|
assertPointsEquals(
|
||||||
assert,
|
assert,
|
||||||
viewport.getCenter(),
|
|
||||||
expectedCenters[i],
|
expectedCenters[i],
|
||||||
|
viewport.getCenter(),
|
||||||
1e-14,
|
1e-14,
|
||||||
"Panned to the correct location."
|
"Panned to the correct location."
|
||||||
);
|
);
|
||||||
@ -879,6 +1018,45 @@
|
|||||||
viewer.open(DZI_PATH);
|
viewer.open(DZI_PATH);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QUnit.test('zoomTo flipped with ref point', function(assert) {
|
||||||
|
var done = assert.async();
|
||||||
|
var openHandler = function(event) {
|
||||||
|
viewer.removeHandler('open', openHandler);
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
|
||||||
|
viewport.setFlip(true);
|
||||||
|
|
||||||
|
var expectedFlippedCenters = [
|
||||||
|
new OpenSeadragon.Point(5, 5),
|
||||||
|
new OpenSeadragon.Point(4.7505, 4.7505),
|
||||||
|
new OpenSeadragon.Point(4.6005, 4.7505),
|
||||||
|
new OpenSeadragon.Point(4.8455, 4.9955),
|
||||||
|
new OpenSeadragon.Point(5.2205, 5.3705),
|
||||||
|
new OpenSeadragon.Point(5.2205, 5.3705),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (var i = 0; i < testZoomLevels.length; i++) {
|
||||||
|
viewport.zoomTo(testZoomLevels[i], testPoints[i], true);
|
||||||
|
assert.propEqual(
|
||||||
|
viewport.getZoom(),
|
||||||
|
testZoomLevels[i],
|
||||||
|
"Zoomed flipped to the correct level."
|
||||||
|
);
|
||||||
|
assertPointsEquals(
|
||||||
|
assert,
|
||||||
|
expectedFlippedCenters[i],
|
||||||
|
viewport.getCenter(),
|
||||||
|
1e-14,
|
||||||
|
"Panned flipped to the correct location."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
done();
|
||||||
|
};
|
||||||
|
viewer.addHandler('open', openHandler);
|
||||||
|
viewer.open(DZI_PATH);
|
||||||
|
});
|
||||||
|
|
||||||
QUnit.test('rotation', function(assert){
|
QUnit.test('rotation', function(assert){
|
||||||
var done = assert.async();
|
var done = assert.async();
|
||||||
var openHandler = function(event) {
|
var openHandler = function(event) {
|
||||||
@ -890,6 +1068,28 @@
|
|||||||
assert.propEqual(viewport.getRotation, 90, "Rotation should be 90 degrees");
|
assert.propEqual(viewport.getRotation, 90, "Rotation should be 90 degrees");
|
||||||
viewport.setRotation(-75);
|
viewport.setRotation(-75);
|
||||||
assert.propEqual(viewport.getRotation, -75, "Rotation should be -75 degrees");
|
assert.propEqual(viewport.getRotation, -75, "Rotation should be -75 degrees");
|
||||||
|
|
||||||
|
done();
|
||||||
|
};
|
||||||
|
|
||||||
|
viewer.addHandler('open', openHandler);
|
||||||
|
viewer.open(DZI_PATH);
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('rotation (flipped)', function(assert){
|
||||||
|
var done = assert.async();
|
||||||
|
var openHandler = function(event) {
|
||||||
|
viewer.removeHandler('open', openHandler);
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
|
||||||
|
viewport.setFlip(true);
|
||||||
|
|
||||||
|
assert.propEqual(viewport.getRotation, 0, "Original flipped rotation should be 0 degrees");
|
||||||
|
viewport.setRotation(90);
|
||||||
|
assert.propEqual(viewport.getRotation, 90, "Flipped rotation should be 90 degrees");
|
||||||
|
viewport.setRotation(-75);
|
||||||
|
assert.propEqual(viewport.getRotation, -75, "Flipped rotation should be -75 degrees");
|
||||||
|
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1140,4 +1340,44 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QUnit.test('toggleFlipState', function(assert) {
|
||||||
|
var done = assert.async();
|
||||||
|
var openHandler = function(event) {
|
||||||
|
viewer.removeHandler('open', openHandler);
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
|
||||||
|
assert.deepEqual(viewport.getFlip(), false, "Get original flip state should be false");
|
||||||
|
|
||||||
|
viewport.toggleFlip();
|
||||||
|
assert.deepEqual(viewport.getFlip(), true, "Toggling flip state variable, viewport should be true");
|
||||||
|
|
||||||
|
viewport.toggleFlip();
|
||||||
|
assert.deepEqual(viewport.getFlip(), false, "Toggling back flip state variable, viewport should be false again");
|
||||||
|
|
||||||
|
done();
|
||||||
|
};
|
||||||
|
viewer.addHandler('open', openHandler);
|
||||||
|
viewer.open(DZI_PATH);
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('setFlipState', function(assert) {
|
||||||
|
var done = assert.async();
|
||||||
|
var openHandler = function(event) {
|
||||||
|
viewer.removeHandler('open', openHandler);
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
|
||||||
|
assert.deepEqual(viewport.getFlip(), false, "Get original flip state should be false");
|
||||||
|
|
||||||
|
viewport.setFlip(true);
|
||||||
|
assert.deepEqual(viewport.getFlip(), true, "Setting flip state variable should be true");
|
||||||
|
|
||||||
|
viewport.setFlip(false);
|
||||||
|
assert.deepEqual(viewport.getFlip(), false, "Unsetting flip state variable, viewport should be false again");
|
||||||
|
|
||||||
|
done();
|
||||||
|
};
|
||||||
|
viewer.addHandler('open', openHandler);
|
||||||
|
viewer.open(DZI_PATH);
|
||||||
|
});
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
Loading…
Reference in New Issue
Block a user