From 458a16ce1f900a6be8d2735a9d98304413d50698 Mon Sep 17 00:00:00 2001 From: Sebastien ROBERT Date: Wed, 22 Dec 2021 15:44:32 +0900 Subject: [PATCH] Introduced animation state and testing it to determine rendering when at rest --- src/openseadragon.js | 22 +++++++++++++++++++--- src/tiledimage.js | 6 ++++-- src/viewer.js | 31 +++++++++++++++++++++++-------- 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/openseadragon.js b/src/openseadragon.js index b01f5c25..1c413b30 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -1424,9 +1424,25 @@ function OpenSeadragon( options ){ * @property {Number} ALWAYS Apply subpixel rounding for transparency during animation and when animation is over. */ SUBPIXEL_ROUNDING_OCCURRENCES: { - NEVER: 0, - ONLY_AT_REST: 1, - ALWAYS: 2 + NEVER: 0, + ONLY_AT_REST: 1, + ALWAYS: 2 + }, + + /** + * An enumeration of animation states. + * @static + * @type {Object} + * @property {Number} AT_REST Indicates there are no more animations running and the image is at rest. + * @property {Number} ANIMATION_STARTED Indicates the image is in motion and it just started. + * @property {Number} ANIMATING Indicates the image was in motion and is still in motion. + * @property {Number} ANIMATION_FINISHED Indicates the image was in motion and is not in motion anymore. + */ + ANIMATION_STATES: { + AT_REST: 0, + ANIMATION_STARTED: 1, + ANIMATING: 2, + ANIMATION_FINISHED: 3 }, /** diff --git a/src/tiledimage.js b/src/tiledimage.js index a9d2e9e2..6e426e4e 100644 --- a/src/tiledimage.js +++ b/src/tiledimage.js @@ -2210,8 +2210,10 @@ function drawTiles( tiledImage, lastDrawn ) { if (isSubPixelRoundingRuleAlways(subPixelRoundingRule)) { shouldRoundPositionAndSize = true; } else if (isSubPixelRoundingRuleOnlyAtRest(subPixelRoundingRule)) { - var isAnimating = tiledImage.viewer && tiledImage.viewer.isAnimating(); - shouldRoundPositionAndSize = !isAnimating; + shouldRoundPositionAndSize = tiledImage.viewer && ( + tiledImage.viewer.getAnimationState() === $.ANIMATION_STATES.ANIMATION_FINISHED || + tiledImage.viewer.getAnimationState() === $.ANIMATION_STATES.AT_REST // Testing AT_REST here is for the very first render after loading. + ); } for (var i = lastDrawn.length - 1; i >= 0; i--) { diff --git a/src/viewer.js b/src/viewer.js index 2f23abe9..57b46cad 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -203,6 +203,7 @@ $.Viewer = function( options ) { fsBoundsDelta: new $.Point( 1, 1 ), prevContainerSize: null, animating: false, + animationState: $.ANIMATION_STATES.AT_REST, forceRedraw: false, mouseInside: false, group: null, @@ -713,6 +714,8 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, } THIS[ this.hash ].animating = false; + THIS[ this.hash ].animationState = $.ANIMATION_STATES.AT_REST; + this.world.removeAll(); this.imageLoader.clear(); @@ -2353,6 +2356,10 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, isAnimating: function () { return THIS[ this.hash ].animating; }, + + getAnimationState: function () { + return THIS[ this.hash ].animationState; + }, }); @@ -3502,6 +3509,8 @@ function updateOnce( viewer ) { var currentAnimating = THIS[ viewer.hash ].animating; if ( !currentAnimating && animated ) { + THIS[ viewer.hash ].animationState = $.ANIMATION_STATES.ANIMATION_STARTED; + /** * Raised when any spring animation starts (zoom, pan, etc.). * @@ -3515,7 +3524,18 @@ function updateOnce( viewer ) { abortControlsAutoHide( viewer ); } - if ( animated || THIS[ viewer.hash ].forceRedraw || viewer.world.needsDraw() ) { + var lastAnimation = false; + + if (currentAnimating) { + if (animated) { + THIS[ viewer.hash ].animationState = $.ANIMATION_STATES.ANIMATING; + } else { + THIS[ viewer.hash ].animationState = $.ANIMATION_STATES.ANIMATION_FINISHED; + lastAnimation = true; + } + } + + if ( animated || lastAnimation || THIS[ viewer.hash ].forceRedraw || viewer.world.needsDraw() ) { drawWorld( viewer ); viewer._drawOverlays(); if( viewer.navigator ){ @@ -3540,6 +3560,8 @@ function updateOnce( viewer ) { } if ( currentAnimating && !animated ) { + THIS[ viewer.hash ].animationState = $.ANIMATION_STATES.AT_REST; + /** * Raised when any spring animation ends (zoom, pan, etc.). * @@ -3558,13 +3580,6 @@ function updateOnce( viewer ) { THIS[ viewer.hash ].animating = animated; - // Intentionally use currentAnimating as the value at the current frame, - // regardless of THIS[ viewer.hash ].animating being updated. - if (currentAnimating && !animated) { - // Ensure a draw occurs once animation is over. - drawWorld( viewer ); - } - //viewer.profiler.endUpdate(); }