mirror of
https://github.com/openseadragon/openseadragon.git
synced 2025-01-31 23:21:42 +03:00
Working on rotating images.
So far only 90 degree rotation is supported. Only the image is currently being rotated. Overlays, debugger, and the navigator still need to be updated to support rotation.
This commit is contained in:
parent
26ad522f59
commit
b9583c43ac
@ -505,6 +505,7 @@ function updateViewport( drawer ) {
|
||||
Math.log( 2 )
|
||||
))
|
||||
),
|
||||
degrees = drawer.viewport.degrees,
|
||||
renderPixelRatioC,
|
||||
renderPixelRatioT,
|
||||
zeroRatioT,
|
||||
@ -529,7 +530,14 @@ function updateViewport( drawer ) {
|
||||
drawer.context.clearRect( 0, 0, viewportSize.x, viewportSize.y );
|
||||
}
|
||||
|
||||
//TODO
|
||||
//Change bounds for rotation
|
||||
if (degrees === 90 || degrees === 270) {
|
||||
var rotatedBounds = viewportBounds.rotate( degrees );
|
||||
viewportTL = rotatedBounds.getTopLeft();
|
||||
viewportBR = rotatedBounds.getBottomRight();
|
||||
}
|
||||
|
||||
//Don't draw if completely outside of the viewport
|
||||
if ( !drawer.wrapHorizontal &&
|
||||
( viewportBR.x < 0 || viewportTL.x > 1 ) ) {
|
||||
return;
|
||||
@ -571,6 +579,7 @@ function updateViewport( drawer ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//Perform calculations for draw if we haven't drawn this
|
||||
renderPixelRatioT = drawer.viewport.deltaPixelsFromPoints(
|
||||
drawer.source.getPixelRatio( level ),
|
||||
false
|
||||
@ -1192,7 +1201,11 @@ function drawTiles( drawer, lastDrawn ){
|
||||
} else {
|
||||
|
||||
if ( USE_CANVAS ) {
|
||||
// TODO do this in a more performant way
|
||||
// specifically, don't save,rotate,restore every time we draw a tile
|
||||
offsetForRotation( tile, drawer.canvas, drawer.context, drawer.viewport.degrees );
|
||||
tile.drawCanvas( drawer.context );
|
||||
restoreRotationChanges( tile, drawer.canvas, drawer.context );
|
||||
} else {
|
||||
tile.drawHTML( drawer.canvas );
|
||||
}
|
||||
@ -1218,6 +1231,32 @@ function drawTiles( drawer, lastDrawn ){
|
||||
}
|
||||
}
|
||||
|
||||
function offsetForRotation( tile, canvas, context, degrees ){
|
||||
var cx = canvas.width / 2,
|
||||
cy = canvas.height / 2,
|
||||
px = tile.position.x - cx,
|
||||
py = tile.position.y - cy;
|
||||
|
||||
context.save();
|
||||
|
||||
context.translate(cx, cy);
|
||||
context.rotate( Math.PI / 180 * degrees);
|
||||
tile.position.x = px;
|
||||
tile.position.y = py;
|
||||
}
|
||||
|
||||
function restoreRotationChanges( tile, canvas, context ){
|
||||
var cx = canvas.width / 2,
|
||||
cy = canvas.height / 2,
|
||||
px = tile.position.x + cx,
|
||||
py = tile.position.y + cy;
|
||||
|
||||
tile.position.x = px;
|
||||
tile.position.y = py;
|
||||
|
||||
context.restore();
|
||||
}
|
||||
|
||||
|
||||
function drawDebugInfo( drawer, tile, count, i ){
|
||||
|
||||
|
@ -533,6 +533,9 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
|
||||
navigatorPosition: null,
|
||||
navigatorSizeRatio: 0.2,
|
||||
|
||||
// INITIAL ROTATION
|
||||
degrees: 0,
|
||||
|
||||
//REFERENCE STRIP SETTINGS
|
||||
showReferenceStrip: false,
|
||||
referenceStripScroll: 'horizontal',
|
||||
@ -1924,4 +1927,23 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
|
||||
throw new Error(message);
|
||||
};
|
||||
|
||||
/**
|
||||
* http://stackoverflow.com/questions/246193
|
||||
* /how-do-i-round-a-number-in-javascript
|
||||
* @private
|
||||
* @inner
|
||||
* @function
|
||||
* @param {Number} num
|
||||
* @param {Number} decimals
|
||||
* @return {Number}
|
||||
*/
|
||||
$._round = function ( num, decimals ) {
|
||||
var coefficient;
|
||||
|
||||
decimals = decimals || 10;
|
||||
coefficient = Math.pow( 10, decimals );
|
||||
|
||||
return Math.round( num * coefficient ) / coefficient;
|
||||
};
|
||||
|
||||
}( OpenSeadragon ));
|
||||
|
21
src/point.js
21
src/point.js
@ -160,6 +160,27 @@ $.Point.prototype = {
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Rotates the point around the specified pivot
|
||||
* From http://stackoverflow.com/questions/4465931/rotate-rectangle-around-a-point
|
||||
* @function
|
||||
* @param {Number} degress to rotate around the pivot.
|
||||
* @param {OpenSeadragon.Point} pivot Point about which to rotate.
|
||||
* @returns {OpenSeadragon.Point}. A new point representing the point rotated around the specified pivot
|
||||
*/
|
||||
rotate: function ( degrees, pivot ) {
|
||||
var angle = degrees * Math.PI / 180.0,
|
||||
x = $._round(
|
||||
Math.cos( angle ) * ( this.x - pivot.x ) -
|
||||
Math.sin( angle ) * ( this.y - pivot.y ) + pivot.x
|
||||
),
|
||||
y = $._round(
|
||||
Math.sin( angle ) * ( this.x - pivot.x ) +
|
||||
Math.cos( angle ) * ( this.y - pivot.y ) + pivot.y
|
||||
);
|
||||
return new $.Point( x, y );
|
||||
},
|
||||
|
||||
/**
|
||||
* Add another Point to this point and return a new Point.
|
||||
* @function
|
||||
|
@ -69,14 +69,17 @@ $.Rect.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Provides the coordinates of the upper-left corner of the rectanglea s a
|
||||
* Provides the coordinates of the upper-left corner of the rectangle as a
|
||||
* point.
|
||||
* @function
|
||||
* @returns {OpenSeadragon.Point} The coordinate of the upper-left corner of
|
||||
* the rectangle.
|
||||
*/
|
||||
getTopLeft: function() {
|
||||
return new $.Point( this.x, this.y );
|
||||
return new $.Point(
|
||||
this.x,
|
||||
this.y
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -93,10 +96,38 @@ $.Rect.prototype = {
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Provides the coordinates of the top-right corner of the rectangle as a
|
||||
* point.
|
||||
* @function
|
||||
* @returns {OpenSeadragon.Point} The coordinate of the top-right corner of
|
||||
* the rectangle.
|
||||
*/
|
||||
getTopRight: function() {
|
||||
return new $.Point(
|
||||
this.x + this.width,
|
||||
this.y
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Provides the coordinates of the bottom-left corner of the rectangle as a
|
||||
* point.
|
||||
* @function
|
||||
* @returns {OpenSeadragon.Point} The coordinate of the bottom-left corner of
|
||||
* the rectangle.
|
||||
*/
|
||||
getBottomLeft: function() {
|
||||
return new $.Point(
|
||||
this.x,
|
||||
this.y + this.height
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Computes the center of the rectangle.
|
||||
* @function
|
||||
* @returns {OpenSeadragon.Point} The center of the rectangle as represnted
|
||||
* @returns {OpenSeadragon.Point} The center of the rectangle as represented
|
||||
* as represented by a 2-dimensional vector (x,y)
|
||||
*/
|
||||
getCenter: function() {
|
||||
@ -109,7 +140,7 @@ $.Rect.prototype = {
|
||||
/**
|
||||
* Returns the width and height component as a vector OpenSeadragon.Point
|
||||
* @function
|
||||
* @returns {OpenSeadragon.Point} The 2 dimensional vector represnting the
|
||||
* @returns {OpenSeadragon.Point} The 2 dimensional vector representing the
|
||||
* the width and height of the rectangle.
|
||||
*/
|
||||
getSize: function() {
|
||||
@ -117,7 +148,7 @@ $.Rect.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Determines if two Rectanlges have equivalent components.
|
||||
* Determines if two Rectangles have equivalent components.
|
||||
* @function
|
||||
* @param {OpenSeadragon.Rect} rectangle The Rectangle to compare to.
|
||||
* @return {Boolean} 'true' if all components are equal, otherwise 'false'.
|
||||
@ -131,7 +162,48 @@ $.Rect.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Provides a string representation of the retangle which is useful for
|
||||
* Rotates a rectangle around a point. Currently only 90, 180, and 270
|
||||
* degrees are supported.
|
||||
* @function
|
||||
* @param {Number} degrees The angle in degrees to rotate.
|
||||
* @param {OpenSeadragon.Point} pivot The point about which to rotate.
|
||||
* Defaults to the center of the rectangle.
|
||||
* @return {OpenSeadragon.Rect}
|
||||
*/
|
||||
rotate: function( degrees, pivot ) {
|
||||
// TODO support arbitrary rotation
|
||||
var width = this.width,
|
||||
height = this.height,
|
||||
newTopLeft;
|
||||
|
||||
pivot = pivot || this.getCenter();
|
||||
|
||||
switch ( degrees ) {
|
||||
case 90:
|
||||
newTopLeft = this.getBottomLeft();
|
||||
width = this.height;
|
||||
height = this.width;
|
||||
break;
|
||||
case 180:
|
||||
newTopLeft = this.getBottomRight();
|
||||
break;
|
||||
case 270:
|
||||
newTopLeft = this.getTopRight();
|
||||
width = this.height;
|
||||
height = this.width;
|
||||
break;
|
||||
default:
|
||||
newTopLeft = this.getTopLeft();
|
||||
break;
|
||||
}
|
||||
|
||||
newTopLeft = newTopLeft.rotate(degrees, pivot);
|
||||
|
||||
return new $.Rect(newTopLeft.x, newTopLeft.y, width, height);
|
||||
},
|
||||
|
||||
/**
|
||||
* Provides a string representation of the rectangle which is useful for
|
||||
* debugging.
|
||||
* @function
|
||||
* @returns {String} A string representation of the rectangle.
|
||||
|
@ -1074,6 +1074,19 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* @function
|
||||
* @name OpenSeadragon.Viewer.prototype.rotate
|
||||
* @return {OpenSeadragon.Viewer} Chainable.
|
||||
*/
|
||||
rotate: function(clockwise){
|
||||
clockwise = clockwise || true;
|
||||
this.viewport.degrees = ( this.viewport.degrees + (clockwise ? 90 : -90 ) + 360 ) % 360;
|
||||
//this.raiseEvent( 'rotate', { viewer: this } );
|
||||
this.drawer.update();
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Display a message in the viewport
|
||||
* @function
|
||||
@ -1696,5 +1709,9 @@ function onNext(){
|
||||
this.goToPage( next );
|
||||
}
|
||||
|
||||
function onRotate(){
|
||||
this.rotate();
|
||||
}
|
||||
|
||||
|
||||
}( OpenSeadragon ));
|
||||
|
@ -79,7 +79,8 @@ $.Viewport = function( options ) {
|
||||
wrapVertical: $.DEFAULT_SETTINGS.wrapVertical,
|
||||
defaultZoomLevel: $.DEFAULT_SETTINGS.defaultZoomLevel,
|
||||
minZoomLevel: $.DEFAULT_SETTINGS.minZoomLevel,
|
||||
maxZoomLevel: $.DEFAULT_SETTINGS.maxZoomLevel
|
||||
maxZoomLevel: $.DEFAULT_SETTINGS.maxZoomLevel,
|
||||
degrees: $.DEFAULT_SETTINGS.degrees
|
||||
|
||||
}, options );
|
||||
|
||||
@ -497,6 +498,7 @@ $.Viewport.prototype = {
|
||||
this.centerSpringX.target.value,
|
||||
this.centerSpringY.target.value
|
||||
);
|
||||
delta = delta.rotate( -this.degrees, new $.Point( 0, 0 ) );
|
||||
return this.panTo( center.plus( delta ), immediately );
|
||||
},
|
||||
|
||||
@ -531,6 +533,12 @@ $.Viewport.prototype = {
|
||||
* @return {OpenSeadragon.Viewport} Chainable.
|
||||
*/
|
||||
zoomBy: function( factor, refPoint, immediately ) {
|
||||
if( typeof refPoint != 'undefined' ) {
|
||||
refPoint = refPoint.rotate(
|
||||
-this.degrees,
|
||||
new $.Point( this.centerSpringX.target.value, this.centerSpringY.target.value )
|
||||
);
|
||||
}
|
||||
return this.zoomTo( this.zoomSpring.target.value * factor, refPoint, immediately );
|
||||
},
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user