Skip to content

Commit

Permalink
[Bug] Interval animation doesn't stop when speed is set to 0 (#1397)
Browse files Browse the repository at this point in the history
* Fix: If time series speed is set to 0, the timeline should stop animation (Step by interval mode)

* Added tests for clamp

Co-authored-by: Ilya Boyandin <ilyabo@gmail.com>
  • Loading branch information
heshan0131 and ilyabo committed Feb 4, 2021
1 parent 9476c29 commit 29bfa40
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 18 deletions.
43 changes: 25 additions & 18 deletions src/components/common/animation-control/animation-controller.js
Expand Up @@ -77,9 +77,10 @@ function AnimationControllerFactory() {
_timer = null;

_startOrPauseAnimation() {
if (!this._timer && this.props.isAnimating) {
const {isAnimating, speed} = this.props;
if (!this._timer && isAnimating && speed > 0) {
this._startAnimation();
} else if (this._timer && !this.props.isAnimating) {
} else if (this._timer && !isAnimating) {
this._pauseAnimation();
}
}
Expand Down Expand Up @@ -130,31 +131,37 @@ function AnimationControllerFactory() {
};

_startAnimation = () => {
this._pauseAnimation();
if (this.props.animationWindow === ANIMATION_WINDOW.interval) {
// animate by interval
// 30*600
const {steps, speed} = this.props;
if (!Array.isArray(steps) || !steps.length) {
Console.warn('animation steps should be an array');
return;
const {speed} = this.props;
this._clearTimer();
if (speed > 0) {
if (this.props.animationWindow === ANIMATION_WINDOW.interval) {
// animate by interval
// 30*600
const {steps} = this.props;
if (!Array.isArray(steps) || !steps.length) {
Console.warn('animation steps should be an array');
return;
}
// when speed = 1, animation should loop through 600 frames at 60 FPS
// calculate delay based on # steps
const delay = (BASE_SPEED * (1000 / FPS)) / steps.length / (speed || 1);
this._animate(delay);
} else {
this._timer = requestAnimationFrame(this._nextFrame);
}
// when speed = 1, animation should loop through 600 frames at 60 FPS
// calculate delay based on # steps
const delay = (BASE_SPEED * (1000 / FPS)) / steps.length / (speed || 1);
this._animate(delay);
} else {
this._timer = requestAnimationFrame(this._nextFrame);
}

this.setState({isAnimating: true});
};

_pauseAnimation = () => {
_clearTimer = () => {
if (this._timer) {
cancelAnimationFrame(this._timer);
this._timer = null;
}
};

_pauseAnimation = () => {
this._clearTimer();
this.setState({isAnimating: false});
};

Expand Down
10 changes: 10 additions & 0 deletions test/node/utils/data-utils-test.js
Expand Up @@ -21,6 +21,7 @@
import test from 'tape';

import {
clamp,
getRoundingDecimalFromStep,
preciseRound,
normalizeSliderValue,
Expand All @@ -32,6 +33,15 @@ import {
} from 'utils/data-utils';
import {ALL_FIELD_TYPES} from 'constants';

test('dataUtils -> clamp', t => {
t.equal(clamp([0,1], 2), 1, 'should clamp 2 to 1 for [0,1]');
t.equal(clamp([0,1], 0.5), 0.5, 'should not clamp 0.5 for [0,1]');
t.equal(clamp([-1,1], -2), -1, 'should clamp -2 to -1 for [-1,1]');
t.equal(clamp([0,10], 11), 10, 'should clamp 11 to 10 for [0,10]');
t.equal(clamp([0,0], 1), 0, 'should clamp 1 to 0 for [0,0]');
t.end();
});

test('dataUtils -> preciseRound', t => {
t.equal(preciseRound(1.234, 2), '1.23', 'should round 1.234 correctly');
t.equal(preciseRound(13.234, 0), '13', 'should round 13.234 correctly');
Expand Down

0 comments on commit 29bfa40

Please sign in to comment.