mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-22 21:26:10 +03:00
First draft of tiled image rotation.
This commit is contained in:
parent
bbf354b6b6
commit
65b59c08d6
@ -464,7 +464,7 @@ $.Drawer.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// private
|
// private
|
||||||
drawDebugInfo: function( tile, count, i ){
|
drawDebugInfo: function(tile, count, i, tiledImage) {
|
||||||
if ( !this.useCanvas ) {
|
if ( !this.useCanvas ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -479,6 +479,12 @@ $.Drawer.prototype = {
|
|||||||
if ( this.viewport.degrees !== 0 ) {
|
if ( this.viewport.degrees !== 0 ) {
|
||||||
this._offsetForRotation(this.viewport.degrees);
|
this._offsetForRotation(this.viewport.degrees);
|
||||||
}
|
}
|
||||||
|
if (tiledImage.degrees) {
|
||||||
|
this._offsetForRotation(
|
||||||
|
tiledImage.degrees,
|
||||||
|
tiledImage.viewport.pixelFromPointNoRotate(
|
||||||
|
tiledImage.getBounds(true).getTopLeft(), true));
|
||||||
|
}
|
||||||
|
|
||||||
context.strokeRect(
|
context.strokeRect(
|
||||||
tile.position.x * $.pixelDensityRatio,
|
tile.position.x * $.pixelDensityRatio,
|
||||||
@ -541,6 +547,9 @@ $.Drawer.prototype = {
|
|||||||
if ( this.viewport.degrees !== 0 ) {
|
if ( this.viewport.degrees !== 0 ) {
|
||||||
this._restoreRotationChanges();
|
this._restoreRotationChanges();
|
||||||
}
|
}
|
||||||
|
if (tiledImage.degrees) {
|
||||||
|
this._restoreRotationChanges();
|
||||||
|
}
|
||||||
context.restore();
|
context.restore();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -574,17 +583,19 @@ $.Drawer.prototype = {
|
|||||||
return new $.Point(canvas.width, canvas.height);
|
return new $.Point(canvas.width, canvas.height);
|
||||||
},
|
},
|
||||||
|
|
||||||
// private
|
getCanvasCenter: function() {
|
||||||
_offsetForRotation: function(degrees, useSketch) {
|
return new $.Point(this.canvas.width / 2, this.canvas.height / 2);
|
||||||
var cx = this.canvas.width / 2;
|
},
|
||||||
var cy = this.canvas.height / 2;
|
|
||||||
|
|
||||||
|
// private
|
||||||
|
_offsetForRotation: function(degrees, point, useSketch) {
|
||||||
|
point = point || this.getCanvasCenter();
|
||||||
var context = this._getContext(useSketch);
|
var context = this._getContext(useSketch);
|
||||||
context.save();
|
context.save();
|
||||||
|
|
||||||
context.translate(cx, cy);
|
context.translate(point.x, point.y);
|
||||||
context.rotate(Math.PI / 180 * degrees);
|
context.rotate(Math.PI / 180 * degrees);
|
||||||
context.translate(-cx, -cy);
|
context.translate(-point.x, -point.y);
|
||||||
},
|
},
|
||||||
|
|
||||||
// private
|
// private
|
||||||
|
@ -1375,6 +1375,21 @@ function OpenSeadragon( options ){
|
|||||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the modulo of a number but makes sure to always return
|
||||||
|
* a positive value.
|
||||||
|
* @param {Number} number the number to computes the modulo of
|
||||||
|
* @param {Number} modulo the modulo
|
||||||
|
* @returns {Number} the result of the modulo of number
|
||||||
|
*/
|
||||||
|
positiveModulo: function(number, modulo) {
|
||||||
|
var result = number % modulo;
|
||||||
|
if (result < 0) {
|
||||||
|
result += modulo;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if a point is within the bounding rectangle of the given element (hit-test).
|
* Determines if a point is within the bounding rectangle of the given element (hit-test).
|
||||||
* @function
|
* @function
|
||||||
|
@ -190,10 +190,7 @@ $.Point.prototype = {
|
|||||||
var sin;
|
var sin;
|
||||||
// Avoid float computations when possible
|
// Avoid float computations when possible
|
||||||
if (degrees % 90 === 0) {
|
if (degrees % 90 === 0) {
|
||||||
var d = degrees % 360;
|
var d = $.positiveModulo(degrees, 360);
|
||||||
if (d < 0) {
|
|
||||||
d += 360;
|
|
||||||
}
|
|
||||||
switch (d) {
|
switch (d) {
|
||||||
case 0:
|
case 0:
|
||||||
cos = 1;
|
cos = 1;
|
||||||
|
@ -81,10 +81,7 @@ $.Rect = function(x, y, width, height, degrees) {
|
|||||||
this.degrees = typeof(degrees) === "number" ? degrees : 0;
|
this.degrees = typeof(degrees) === "number" ? degrees : 0;
|
||||||
|
|
||||||
// Normalizes the rectangle.
|
// Normalizes the rectangle.
|
||||||
this.degrees = this.degrees % 360;
|
this.degrees = $.positiveModulo(this.degrees, 360);
|
||||||
if (this.degrees < 0) {
|
|
||||||
this.degrees += 360;
|
|
||||||
}
|
|
||||||
var newTopLeft, newWidth;
|
var newTopLeft, newWidth;
|
||||||
if (this.degrees >= 270) {
|
if (this.degrees >= 270) {
|
||||||
newTopLeft = this.getTopRight();
|
newTopLeft = this.getTopRight();
|
||||||
@ -442,13 +439,10 @@ $.Rect.prototype = {
|
|||||||
* @return {OpenSeadragon.Rect}
|
* @return {OpenSeadragon.Rect}
|
||||||
*/
|
*/
|
||||||
rotate: function(degrees, pivot) {
|
rotate: function(degrees, pivot) {
|
||||||
degrees = degrees % 360;
|
degrees = $.positiveModulo(degrees, 360);
|
||||||
if (degrees === 0) {
|
if (degrees === 0) {
|
||||||
return this.clone();
|
return this.clone();
|
||||||
}
|
}
|
||||||
if (degrees < 0) {
|
|
||||||
degrees += 360;
|
|
||||||
}
|
|
||||||
|
|
||||||
pivot = pivot || this.getCenter();
|
pivot = pivot || this.getCenter();
|
||||||
var newTopLeft = this.getTopLeft().rotate(degrees, pivot);
|
var newTopLeft = this.getTopLeft().rotate(degrees, pivot);
|
||||||
|
@ -159,8 +159,8 @@ $.TiledImage = function( options ) {
|
|||||||
crossOriginPolicy: $.DEFAULT_SETTINGS.crossOriginPolicy,
|
crossOriginPolicy: $.DEFAULT_SETTINGS.crossOriginPolicy,
|
||||||
placeholderFillStyle: $.DEFAULT_SETTINGS.placeholderFillStyle,
|
placeholderFillStyle: $.DEFAULT_SETTINGS.placeholderFillStyle,
|
||||||
opacity: $.DEFAULT_SETTINGS.opacity,
|
opacity: $.DEFAULT_SETTINGS.opacity,
|
||||||
compositeOperation: $.DEFAULT_SETTINGS.compositeOperation
|
compositeOperation: $.DEFAULT_SETTINGS.compositeOperation,
|
||||||
|
degrees: 0
|
||||||
}, options );
|
}, options );
|
||||||
|
|
||||||
this._xSpring = new $.Spring({
|
this._xSpring = new $.Spring({
|
||||||
@ -274,13 +274,19 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|||||||
* @param {Boolean} [current=false] - Pass true for the current location; false for target location.
|
* @param {Boolean} [current=false] - Pass true for the current location; false for target location.
|
||||||
*/
|
*/
|
||||||
getBounds: function(current) {
|
getBounds: function(current) {
|
||||||
if (current) {
|
return current ?
|
||||||
return new $.Rect( this._xSpring.current.value, this._ySpring.current.value,
|
new $.Rect(
|
||||||
this._worldWidthCurrent, this._worldHeightCurrent );
|
this._xSpring.current.value,
|
||||||
}
|
this._ySpring.current.value,
|
||||||
|
this._worldWidthCurrent,
|
||||||
return new $.Rect( this._xSpring.target.value, this._ySpring.target.value,
|
this._worldHeightCurrent,
|
||||||
this._worldWidthTarget, this._worldHeightTarget );
|
this.degrees) :
|
||||||
|
new $.Rect(
|
||||||
|
this._xSpring.target.value,
|
||||||
|
this._ySpring.target.value,
|
||||||
|
this._worldWidthTarget,
|
||||||
|
this._worldHeightTarget,
|
||||||
|
this.degrees);
|
||||||
},
|
},
|
||||||
|
|
||||||
// deprecated
|
// deprecated
|
||||||
@ -304,7 +310,8 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|||||||
bounds.x + clip.x,
|
bounds.x + clip.x,
|
||||||
bounds.y + clip.y,
|
bounds.y + clip.y,
|
||||||
clip.width,
|
clip.width,
|
||||||
clip.height);
|
clip.height,
|
||||||
|
this.degrees);
|
||||||
}
|
}
|
||||||
return bounds;
|
return bounds;
|
||||||
},
|
},
|
||||||
@ -660,6 +667,8 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|||||||
$.console.assert(!newClip || newClip instanceof $.Rect,
|
$.console.assert(!newClip || newClip instanceof $.Rect,
|
||||||
"[TiledImage.setClip] newClip must be an OpenSeadragon.Rect or null");
|
"[TiledImage.setClip] newClip must be an OpenSeadragon.Rect or null");
|
||||||
|
|
||||||
|
//TODO: should this._raiseBoundsChange(); be called?
|
||||||
|
|
||||||
if (newClip instanceof $.Rect) {
|
if (newClip instanceof $.Rect) {
|
||||||
this._clip = newClip.clone();
|
this._clip = newClip.clone();
|
||||||
} else {
|
} else {
|
||||||
@ -684,6 +693,23 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|||||||
this._needsDraw = true;
|
this._needsDraw = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current rotation of this tiled image in degrees.
|
||||||
|
* @returns {Number} the current rotation of this tiled image in degrees.
|
||||||
|
*/
|
||||||
|
getRotation: function() {
|
||||||
|
return this.degrees;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current rotation of this tiled image in degrees.
|
||||||
|
* @param {Number} the rotation in degrees.
|
||||||
|
*/
|
||||||
|
setRotation: function(degrees) {
|
||||||
|
this.degrees = $.positiveModulo(degrees, 360);
|
||||||
|
this._needsDraw = true;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {String} The TiledImage's current compositeOperation.
|
* @returns {String} The TiledImage's current compositeOperation.
|
||||||
*/
|
*/
|
||||||
@ -803,7 +829,8 @@ function updateViewport( tiledImage ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!tiledImage.wrapHorizontal && !tiledImage.wrapVertical) {
|
if (!tiledImage.wrapHorizontal && !tiledImage.wrapVertical) {
|
||||||
var tiledImageBounds = tiledImage.getClippedBounds(true);
|
var tiledImageBounds = tiledImage.getClippedBounds(true)
|
||||||
|
.getBoundingBox();
|
||||||
var intersection = viewportBounds.intersection(tiledImageBounds);
|
var intersection = viewportBounds.intersection(tiledImageBounds);
|
||||||
if (intersection === null) {
|
if (intersection === null) {
|
||||||
return;
|
return;
|
||||||
@ -1464,10 +1491,20 @@ function drawTiles( tiledImage, lastDrawn ) {
|
|||||||
tiledImage._drawer._clear(true, bounds);
|
tiledImage._drawer._clear(true, bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// When scaling, we must rotate only when blending the sketch canvas to avoid
|
// When scaling, we must rotate only when blending the sketch canvas to
|
||||||
// interpolation
|
// avoid interpolation
|
||||||
if (tiledImage.viewport.degrees !== 0 && !sketchScale) {
|
if (!sketchScale) {
|
||||||
tiledImage._drawer._offsetForRotation(tiledImage.viewport.degrees, useSketch);
|
if (tiledImage.viewport.degrees !== 0) {
|
||||||
|
tiledImage._drawer._offsetForRotation(
|
||||||
|
tiledImage.viewport.degrees, useSketch);
|
||||||
|
}
|
||||||
|
if (tiledImage.degrees !== 0) {
|
||||||
|
tiledImage._drawer._offsetForRotation(
|
||||||
|
tiledImage.degrees,
|
||||||
|
tiledImage.viewport.pixelFromPointNoRotate(
|
||||||
|
tiledImage.getBounds(true).getTopLeft(), true),
|
||||||
|
useSketch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var usedClip = false;
|
var usedClip = false;
|
||||||
@ -1535,14 +1572,28 @@ function drawTiles( tiledImage, lastDrawn ) {
|
|||||||
tiledImage._drawer.restoreContext( useSketch );
|
tiledImage._drawer.restoreContext( useSketch );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tiledImage.viewport.degrees !== 0 && !sketchScale) {
|
if (!sketchScale) {
|
||||||
tiledImage._drawer._restoreRotationChanges(useSketch);
|
if (tiledImage.degrees !== 0) {
|
||||||
|
tiledImage._drawer._restoreRotationChanges(useSketch);
|
||||||
|
}
|
||||||
|
if (tiledImage.viewport.degrees !== 0) {
|
||||||
|
tiledImage._drawer._restoreRotationChanges(useSketch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useSketch) {
|
if (useSketch) {
|
||||||
var offsetForRotation = tiledImage.viewport.degrees !== 0 && sketchScale;
|
if (sketchScale) {
|
||||||
if (offsetForRotation) {
|
if (tiledImage.viewport.degrees !== 0) {
|
||||||
tiledImage._drawer._offsetForRotation(tiledImage.viewport.degrees, false);
|
tiledImage._drawer._offsetForRotation(
|
||||||
|
tiledImage.viewport.degrees, false);
|
||||||
|
}
|
||||||
|
if (tiledImage.degrees !== 0) {
|
||||||
|
tiledImage._drawer._offsetForRotation(
|
||||||
|
tiledImage.degrees,
|
||||||
|
tiledImage.viewport.pixelFromPointNoRotate(
|
||||||
|
tiledImage.getBounds(true).getTopLeft(), true),
|
||||||
|
useSketch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tiledImage._drawer.blendSketch({
|
tiledImage._drawer.blendSketch({
|
||||||
opacity: tiledImage.opacity,
|
opacity: tiledImage.opacity,
|
||||||
@ -1551,8 +1602,13 @@ function drawTiles( tiledImage, lastDrawn ) {
|
|||||||
compositeOperation: tiledImage.compositeOperation,
|
compositeOperation: tiledImage.compositeOperation,
|
||||||
bounds: bounds
|
bounds: bounds
|
||||||
});
|
});
|
||||||
if (offsetForRotation) {
|
if (sketchScale) {
|
||||||
tiledImage._drawer._restoreRotationChanges(false);
|
if (tiledImage.degrees !== 0) {
|
||||||
|
tiledImage._drawer._restoreRotationChanges(false);
|
||||||
|
}
|
||||||
|
if (tiledImage.viewport.degrees !== 0) {
|
||||||
|
tiledImage._drawer._restoreRotationChanges(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
drawDebugInfo( tiledImage, lastDrawn );
|
drawDebugInfo( tiledImage, lastDrawn );
|
||||||
@ -1563,7 +1619,8 @@ function drawDebugInfo( tiledImage, lastDrawn ) {
|
|||||||
for ( var i = lastDrawn.length - 1; i >= 0; i-- ) {
|
for ( var i = lastDrawn.length - 1; i >= 0; i-- ) {
|
||||||
var tile = lastDrawn[ i ];
|
var tile = lastDrawn[ i ];
|
||||||
try {
|
try {
|
||||||
tiledImage._drawer.drawDebugInfo( tile, lastDrawn.length, i );
|
tiledImage._drawer.drawDebugInfo(
|
||||||
|
tile, lastDrawn.length, i, tiledImage);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
$.console.error(e);
|
$.console.error(e);
|
||||||
}
|
}
|
||||||
|
@ -1369,6 +1369,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|||||||
clip: queueItem.options.clip,
|
clip: queueItem.options.clip,
|
||||||
placeholderFillStyle: queueItem.options.placeholderFillStyle,
|
placeholderFillStyle: queueItem.options.placeholderFillStyle,
|
||||||
opacity: queueItem.options.opacity,
|
opacity: queueItem.options.opacity,
|
||||||
|
degrees: queueItem.options.degrees,
|
||||||
compositeOperation: queueItem.options.compositeOperation,
|
compositeOperation: queueItem.options.compositeOperation,
|
||||||
springStiffness: _this.springStiffness,
|
springStiffness: _this.springStiffness,
|
||||||
animationTime: _this.animationTime,
|
animationTime: _this.animationTime,
|
||||||
|
@ -852,11 +852,7 @@ $.Viewport.prototype = {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
degrees = degrees % 360;
|
this.degrees = $.positiveModulo(degrees, 360);
|
||||||
if (degrees < 0) {
|
|
||||||
degrees += 360;
|
|
||||||
}
|
|
||||||
this.degrees = degrees;
|
|
||||||
this._setContentBounds(
|
this._setContentBounds(
|
||||||
this.viewer.world.getHomeBounds(),
|
this.viewer.world.getHomeBounds(),
|
||||||
this.viewer.world.getContentFactor());
|
this.viewer.world.getContentFactor());
|
||||||
|
Loading…
Reference in New Issue
Block a user