Animate rotation

This commit is contained in:
Antoine Vandecreme 2017-01-07 19:24:29 +01:00
parent cfc339edea
commit fc69c6568d
3 changed files with 52 additions and 36 deletions

View File

@ -500,9 +500,9 @@ $.Drawer.prototype = {
if ( this.viewport.degrees !== 0 ) { if ( this.viewport.degrees !== 0 ) {
this._offsetForRotation({degrees: this.viewport.degrees}); this._offsetForRotation({degrees: this.viewport.degrees});
} }
if (tiledImage.getRotation() !== 0) { if (tiledImage.getRotation(true) !== 0) {
this._offsetForRotation({ this._offsetForRotation({
degrees: tiledImage.getRotation(), degrees: tiledImage.getRotation(true),
point: tiledImage.viewport.pixelFromPointNoRotate( point: tiledImage.viewport.pixelFromPointNoRotate(
tiledImage._getRotationPoint(true), true) tiledImage._getRotationPoint(true), true)
}); });
@ -569,7 +569,7 @@ $.Drawer.prototype = {
if ( this.viewport.degrees !== 0 ) { if ( this.viewport.degrees !== 0 ) {
this._restoreRotationChanges(); this._restoreRotationChanges();
} }
if (tiledImage.getRotation() !== 0) { if (tiledImage.getRotation(true) !== 0) {
this._restoreRotationChanges(); this._restoreRotationChanges();
} }
context.restore(); context.restore();

View File

@ -206,6 +206,7 @@ $.Spring.prototype = {
/** /**
* @function * @function
* @returns true if the value got updated, false otherwise
*/ */
update: function() { update: function() {
this.current.time = $.now(); this.current.time = $.now();
@ -229,11 +230,14 @@ $.Spring.prototype = {
( this.target.time - this.start.time ) ( this.target.time - this.start.time )
); );
var oldValue = this.current.value;
if (this._exponential) { if (this._exponential) {
this.current.value = Math.exp(currentValue); this.current.value = Math.exp(currentValue);
} else { } else {
this.current.value = currentValue; this.current.value = currentValue;
} }
return oldValue != this.current.value;
}, },
/** /**

View File

@ -132,7 +132,7 @@ $.TiledImage = function( options ) {
var fitBoundsPlacement = options.fitBoundsPlacement || OpenSeadragon.Placement.CENTER; var fitBoundsPlacement = options.fitBoundsPlacement || OpenSeadragon.Placement.CENTER;
delete options.fitBoundsPlacement; delete options.fitBoundsPlacement;
this._degrees = $.positiveModulo(options.degrees || 0, 360); var degrees = $.positiveModulo(options.degrees || 0, 360);
delete options.degrees; delete options.degrees;
$.extend( true, this, { $.extend( true, this, {
@ -186,6 +186,12 @@ $.TiledImage = function( options ) {
animationTime: this.animationTime animationTime: this.animationTime
}); });
this._degreesSpring = new $.Spring({
initial: degrees,
springStiffness: this.springStiffness,
animationTime: this.animationTime
});
this._updateForScale(); this._updateForScale();
if (fitBounds) { if (fitBounds) {
@ -269,16 +275,12 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
* @returns {Boolean} Whether the TiledImage animated. * @returns {Boolean} Whether the TiledImage animated.
*/ */
update: function() { update: function() {
var oldX = this._xSpring.current.value; var xUpdated = this._xSpring.update();
var oldY = this._ySpring.current.value; var yUpdated = this._ySpring.update();
var oldScale = this._scaleSpring.current.value; var scaleUpdated = this._scaleSpring.update();
var degreesUpdated = this._degreesSpring.update();
this._xSpring.update(); if (xUpdated || yUpdated || scaleUpdated || degreesUpdated) {
this._ySpring.update();
this._scaleSpring.update();
if (this._xSpring.current.value !== oldX || this._ySpring.current.value !== oldY ||
this._scaleSpring.current.value !== oldScale) {
this._updateForScale(); this._updateForScale();
this._needsDraw = true; this._needsDraw = true;
return true; return true;
@ -313,7 +315,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
*/ */
getBounds: function(current) { getBounds: function(current) {
return this.getBoundsNoRotate(current) return this.getBoundsNoRotate(current)
.rotate(this._degrees, this._getRotationPoint(current)); .rotate(this.getRotation(current), this._getRotationPoint(current));
}, },
/** /**
@ -362,7 +364,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
clip.width, clip.width,
clip.height); clip.height);
} }
return bounds.rotate(this._degrees, this._getRotationPoint(current)); return bounds.rotate(this.getRotation(current), this._getRotationPoint(current));
}, },
/** /**
@ -397,7 +399,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
point = new $.Point(viewerX, viewerY); point = new $.Point(viewerX, viewerY);
} }
point = point.rotate(-this._degrees, this._getRotationPoint(current)); point = point.rotate(-this.getRotation(current), this._getRotationPoint(current));
return current ? return current ?
this._viewportToImageDelta( this._viewportToImageDelta(
point.x - this._xSpring.current.value, point.x - this._xSpring.current.value,
@ -439,7 +441,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
point.y += this._ySpring.target.value; point.y += this._ySpring.target.value;
} }
return point.rotate(this._degrees, this._getRotationPoint(current)); return point.rotate(this.getRotation(current), this._getRotationPoint(current));
}, },
/** /**
@ -453,7 +455,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
* @param {Boolean} [current=false] - Pass true to use the current location; false for target location. * @param {Boolean} [current=false] - Pass true to use the current location; false for target location.
* @return {OpenSeadragon.Rect} A rect representing the coordinates in the viewport. * @return {OpenSeadragon.Rect} A rect representing the coordinates in the viewport.
*/ */
imageToViewportRectangle: function( imageX, imageY, pixelWidth, pixelHeight, current ) { imageToViewportRectangle: function(imageX, imageY, pixelWidth, pixelHeight, current) {
var rect = imageX; var rect = imageX;
if (rect instanceof $.Rect) { if (rect instanceof $.Rect) {
//they passed a rect instead of individual components //they passed a rect instead of individual components
@ -470,7 +472,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
coordA.y, coordA.y,
coordB.x, coordB.x,
coordB.y, coordB.y,
rect.degrees + this._degrees rect.degrees + this.getRotation(current)
); );
}, },
@ -502,7 +504,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
coordA.y, coordA.y,
coordB.x, coordB.x,
coordB.y, coordB.y,
rect.degrees - this._degrees rect.degrees - this.getRotation(current)
); );
}, },
@ -555,7 +557,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
// coordinates (x in [0, 1] and y in [0, aspectRatio]) // coordinates (x in [0, 1] and y in [0, aspectRatio])
_viewportToTiledImageRectangle: function(rect) { _viewportToTiledImageRectangle: function(rect) {
var scale = this._scaleSpring.current.value; var scale = this._scaleSpring.current.value;
rect = rect.rotate(-this.getRotation(), this._getRotationPoint(true)); rect = rect.rotate(-this.getRotation(true), this._getRotationPoint(true));
return new $.Rect( return new $.Rect(
(rect.x - this._xSpring.current.value) / scale, (rect.x - this._xSpring.current.value) / scale,
(rect.y - this._ySpring.current.value) / scale, (rect.y - this._ySpring.current.value) / scale,
@ -769,24 +771,34 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
}, },
/** /**
* Get the current rotation of this tiled image in degrees. * Get the rotation of this tiled image in degrees.
* @returns {Number} the current rotation of this tiled image in degrees. * @param {Boolean} [current=false] True for current rotation, false for target.
* @returns {Number} the rotation of this tiled image in degrees.
*/ */
getRotation: function() { getRotation: function(current) {
return this._degrees; return current ?
this._degreesSpring.current.value :
this._degreesSpring.target.value;
}, },
/** /**
* Set the current rotation of this tiled image in degrees. * Set the current rotation of this tiled image in degrees.
* @param {Number} degrees the rotation in degrees. * @param {Number} degrees the rotation in degrees.
* @param {Boolean} [immediately=false] Whether to animate to the new angle
* or rotate immediately.
* @fires OpenSeadragon.TiledImage.event:bounds-change * @fires OpenSeadragon.TiledImage.event:bounds-change
*/ */
setRotation: function(degrees) { setRotation: function(degrees, immediately) {
degrees = $.positiveModulo(degrees, 360); degrees = $.positiveModulo(degrees, 360);
if (this._degrees === degrees) { if (this._degreesSpring.target.value === degrees &&
this._degreesSpring.isAtTargetValue()) {
return; return;
} }
this._degrees = degrees; if (immediately) {
this._degreesSpring.resetTo(degrees);
} else {
this._degreesSpring.springTo(degrees);
}
this._needsDraw = true; this._needsDraw = true;
this._raiseBoundsChange(); this._raiseBoundsChange();
}, },
@ -1705,7 +1717,7 @@ function drawTiles( tiledImage, lastDrawn ) {
if (lastDrawn.length > 1 && if (lastDrawn.length > 1 &&
imageZoom > tiledImage.smoothTileEdgesMinZoom && imageZoom > tiledImage.smoothTileEdgesMinZoom &&
!tiledImage.iOSDevice && !tiledImage.iOSDevice &&
tiledImage.getRotation() === 0 && tiledImage.getRotation(true) === 0 &&
$.supportsCanvas) { $.supportsCanvas) {
// When zoomed in a lot (>100%) the tile edges are visible. // When zoomed in a lot (>100%) the tile edges are visible.
// So we have to composite them at ~100% and scale them up together. // So we have to composite them at ~100% and scale them up together.
@ -1739,9 +1751,9 @@ function drawTiles( tiledImage, lastDrawn ) {
useSketch: useSketch useSketch: useSketch
}); });
} }
if (tiledImage._degrees !== 0) { if (tiledImage.getRotation(true) !== 0) {
tiledImage._drawer._offsetForRotation({ tiledImage._drawer._offsetForRotation({
degrees: tiledImage._degrees, degrees: tiledImage.getRotation(true),
point: tiledImage.viewport.pixelFromPointNoRotate( point: tiledImage.viewport.pixelFromPointNoRotate(
tiledImage._getRotationPoint(true), true), tiledImage._getRotationPoint(true), true),
useSketch: useSketch useSketch: useSketch
@ -1754,7 +1766,7 @@ function drawTiles( tiledImage, lastDrawn ) {
tiledImage._drawer.saveContext(useSketch); tiledImage._drawer.saveContext(useSketch);
var box = tiledImage.imageToViewportRectangle(tiledImage._clip, true); var box = tiledImage.imageToViewportRectangle(tiledImage._clip, true);
box = box.rotate(-tiledImage._degrees, tiledImage._getRotationPoint()); box = box.rotate(-tiledImage.getRotation(true), tiledImage._getRotationPoint(true));
var clipRect = tiledImage._drawer.viewportToDrawerRectangle(box); var clipRect = tiledImage._drawer.viewportToDrawerRectangle(box);
if (sketchScale) { if (sketchScale) {
clipRect = clipRect.times(sketchScale); clipRect = clipRect.times(sketchScale);
@ -1816,7 +1828,7 @@ function drawTiles( tiledImage, lastDrawn ) {
} }
if (!sketchScale) { if (!sketchScale) {
if (tiledImage._degrees !== 0) { if (tiledImage.getRotation(true) !== 0) {
tiledImage._drawer._restoreRotationChanges(useSketch); tiledImage._drawer._restoreRotationChanges(useSketch);
} }
if (tiledImage.viewport.degrees !== 0) { if (tiledImage.viewport.degrees !== 0) {
@ -1832,9 +1844,9 @@ function drawTiles( tiledImage, lastDrawn ) {
useSketch: false useSketch: false
}); });
} }
if (tiledImage._degrees !== 0) { if (tiledImage.getRotation(true) !== 0) {
tiledImage._drawer._offsetForRotation({ tiledImage._drawer._offsetForRotation({
degrees: tiledImage._degrees, degrees: tiledImage.getRotation(true),
point: tiledImage.viewport.pixelFromPointNoRotate( point: tiledImage.viewport.pixelFromPointNoRotate(
tiledImage._getRotationPoint(true), true), tiledImage._getRotationPoint(true), true),
useSketch: false useSketch: false
@ -1849,7 +1861,7 @@ function drawTiles( tiledImage, lastDrawn ) {
bounds: bounds bounds: bounds
}); });
if (sketchScale) { if (sketchScale) {
if (tiledImage._degrees !== 0) { if (tiledImage.getRotation(true) !== 0) {
tiledImage._drawer._restoreRotationChanges(false); tiledImage._drawer._restoreRotationChanges(false);
} }
if (tiledImage.viewport.degrees !== 0) { if (tiledImage.viewport.degrees !== 0) {