diff options
| author | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2018-12-12 12:35:13 -0200 |
|---|---|---|
| committer | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2018-12-19 10:56:47 -0200 |
| commit | b7185d1f46eaa76dc5ce05b3ca91c7591a1e2c5a (patch) | |
| tree | 882bab2da6942b3198ad52ee2df1730bbd0f0894 | |
| parent | 2dcfe14b69f31bc079a8ce6cb9a96974cde0a552 (diff) | |
| download | mullvadvpn-b7185d1f46eaa76dc5ce05b3ca91c7591a1e2c5a.tar.xz mullvadvpn-b7185d1f46eaa76dc5ce05b3ca91c7591a1e2c5a.zip | |
Simplify `KeyframeAnimation`'s internal state
Use only the current and target frames.
| -rw-r--r-- | gui/packages/desktop/src/main/keyframe-animation.js | 87 | ||||
| -rw-r--r-- | gui/packages/desktop/src/main/tray-icon-controller.js | 33 | ||||
| -rw-r--r-- | gui/packages/desktop/test/keyframe-animation.spec.js | 102 |
3 files changed, 58 insertions, 164 deletions
diff --git a/gui/packages/desktop/src/main/keyframe-animation.js b/gui/packages/desktop/src/main/keyframe-animation.js index a365c5d1f9..fe79eb35a4 100644 --- a/gui/packages/desktop/src/main/keyframe-animation.js +++ b/gui/packages/desktop/src/main/keyframe-animation.js @@ -3,27 +3,22 @@ export type OnFrameFn = (frame: number) => void; export type OnFinishFn = (void) => void; export type KeyframeAnimationOptions = { - startFrame?: number, - endFrame?: number, - beginFromCurrentState?: boolean, - advanceTo?: 'end', + start?: number, + end: number, }; export type KeyframeAnimationRange = [number, number]; export default class KeyframeAnimation { _speed: number = 200; // ms - _reverse: boolean = false; _onFrame: ?OnFrameFn; _onFinish: ?OnFinishFn; - _frameRange: KeyframeAnimationRange; - _numFrames: number; _currentFrame: number = 0; + _targetFrame: number = 0; _isRunning: boolean = false; _isFinished: boolean = false; - _isFirstRun: boolean = true; _timeout = null; @@ -50,54 +45,18 @@ export default class KeyframeAnimation { return this._speed; } - set reverse(newValue: boolean) { - this._reverse = newValue; - } - get reverse(): boolean { - return this._reverse; - } - get isFinished(): boolean { return this._isFinished; } - constructor(numFrames: number) { - this._numFrames = numFrames; - this._frameRange = [0, numFrames]; - } - - play(options: KeyframeAnimationOptions = {}) { - const { startFrame, endFrame, beginFromCurrentState, advanceTo } = options; - - if (startFrame !== undefined && endFrame !== undefined) { - if (startFrame < 0 || startFrame >= this._numFrames) { - throw new Error('Invalid start frame'); - } + play(options: KeyframeAnimationOptions) { + const { start, end } = options; - if (endFrame < 0 || endFrame >= this._numFrames) { - throw new Error('Invalid end frame'); - } - - if (startFrame < endFrame) { - this._frameRange = [startFrame, endFrame]; - } else { - this._frameRange = [endFrame, startFrame]; - } - } else { - this._frameRange = [0, this._numFrames - 1]; + if (start !== undefined) { + this._currentFrame = start; } - if (!beginFromCurrentState || this._isFirstRun) { - this._currentFrame = this._frameRange[this._reverse ? 1 : 0]; - } - - if (this._isFirstRun) { - this._isFirstRun = false; - } - - if (advanceTo === 'end') { - this._currentFrame = this._frameRange[this._reverse ? 0 : 1]; - } + this._targetFrame = end; this._isRunning = true; this._isFinished = false; @@ -132,6 +91,7 @@ export default class KeyframeAnimation { _didFinish() { this._isFinished = true; + this._isRunning = false; if (this._onFinish) { this._onFinish(); @@ -141,10 +101,7 @@ export default class KeyframeAnimation { _onUpdateFrame() { this._advanceFrame(); - if (this._isFinished) { - // mark animation as not running when finished - this._isRunning = false; - } else { + if (!this._isFinished) { this._render(); // check once again since onFrame() may stop animation @@ -159,28 +116,12 @@ export default class KeyframeAnimation { return; } - const lastFrame = this._frameRange[this._reverse ? 0 : 1]; - if (this._currentFrame === lastFrame) { + if (this._currentFrame === this._targetFrame) { this._didFinish(); + } else if (this._currentFrame < this._targetFrame) { + this._currentFrame += 1; } else { - this._currentFrame = this._nextFrame(this._currentFrame, this._frameRange, this._reverse); - } - } - - _nextFrame(cur: number, frameRange: KeyframeAnimationRange, isReverse: boolean): number { - if (isReverse) { - if (cur < frameRange[0]) { - return cur + 1; - } else if (cur > frameRange[0]) { - return cur - 1; - } - } else { - if (cur > frameRange[1]) { - return cur - 1; - } else if (cur < frameRange[1]) { - return cur + 1; - } + this._currentFrame -= 1; } - return cur; } } diff --git a/gui/packages/desktop/src/main/tray-icon-controller.js b/gui/packages/desktop/src/main/tray-icon-controller.js index 469a76e086..c6f1e4d321 100644 --- a/gui/packages/desktop/src/main/tray-icon-controller.js +++ b/gui/packages/desktop/src/main/tray-icon-controller.js @@ -14,15 +14,15 @@ export default class TrayIconController { constructor(tray: Tray, initialType: TrayIconType) { this._loadImages(); + this._iconType = initialType; - const animation = new KeyframeAnimation(this._iconImages.length); + const initialFrame = this._targetFrame(); + const animation = new KeyframeAnimation(); animation.speed = 100; animation.onFrame = (frameNumber) => tray.setImage(this._iconImages[frameNumber]); - animation.reverse = this._isReverseAnimation(initialType); - animation.play({ advanceTo: 'end' }); + animation.play({ start: initialFrame, end: initialFrame }); this._animation = animation; - this._iconType = initialType; } dispose() { @@ -41,16 +41,12 @@ export default class TrayIconController { return; } + this._iconType = type; + const animation = this._animation; - if (type === 'secured') { - animation.reverse = true; - animation.play({ beginFromCurrentState: true, startFrame: 8, endFrame: 9 }); - } else { - animation.reverse = this._isReverseAnimation(type); - animation.play({ beginFromCurrentState: true }); - } + const frame = this._targetFrame(); - this._iconType = type; + animation.play({ end: frame }); } _loadImages() { @@ -62,7 +58,16 @@ export default class TrayIconController { ); } - _isReverseAnimation(type: TrayIconType): boolean { - return type === 'unsecured'; + _targetFrame(): number { + switch (this._iconType) { + case 'unsecured': + return 0; + case 'securing': + return 9; + case 'secured': + return 8; + default: + throw new Error(`Unknown tray icon type: ${(this._iconType: empty)}`); + } } } diff --git a/gui/packages/desktop/test/keyframe-animation.spec.js b/gui/packages/desktop/test/keyframe-animation.spec.js index dce633dfbb..b893c98572 100644 --- a/gui/packages/desktop/test/keyframe-animation.spec.js +++ b/gui/packages/desktop/test/keyframe-animation.spec.js @@ -1,14 +1,12 @@ // @flow import KeyframeAnimation from '../src/main/keyframe-animation'; -import { nativeImage } from 'electron'; describe('lib/keyframe-animation', function() { this.timeout(1000); const newAnimation = () => { - const images = [1, 2, 3, 4, 5].map(() => nativeImage.createEmpty()); - const animation = new KeyframeAnimation(images); + const animation = new KeyframeAnimation(); animation.speed = 1; return animation; }; @@ -16,8 +14,8 @@ describe('lib/keyframe-animation', function() { it('should play sequence', (done) => { const seq = []; const animation = newAnimation(); - animation.onFrame = () => { - seq.push(animation._currentFrame); + animation.onFrame = (frame) => { + seq.push(frame); }; animation.onFinish = () => { expect(seq).to.be.deep.equal([0, 1, 2, 3, 4]); @@ -25,14 +23,14 @@ describe('lib/keyframe-animation', function() { done(); }; - animation.play(); + animation.play({ end: 4 }); }); it('should play one frame', (done) => { const seq = []; const animation = newAnimation(); - animation.onFrame = () => { - seq.push(animation._currentFrame); + animation.onFrame = (frame) => { + seq.push(frame); }; animation.onFinish = () => { expect(seq).to.be.deep.equal([3]); @@ -40,14 +38,14 @@ describe('lib/keyframe-animation', function() { done(); }; - animation.play({ startFrame: 3, endFrame: 3 }); + animation.play({ start: 3, end: 3 }); }); it('should play sequence with custom frames', (done) => { const seq = []; const animation = newAnimation(); - animation.onFrame = () => { - seq.push(animation._currentFrame); + animation.onFrame = (frame) => { + seq.push(frame); }; animation.onFinish = () => { expect(seq).to.be.deep.equal([2, 3, 4]); @@ -55,17 +53,14 @@ describe('lib/keyframe-animation', function() { done(); }; - animation.play({ - startFrame: 2, - endFrame: 4, - }); + animation.play({ start: 2, end: 4 }); }); it('should play sequence with custom frames in reverse', (done) => { const seq = []; const animation = newAnimation(); - animation.onFrame = () => { - seq.push(animation._currentFrame); + animation.onFrame = (frame) => { + seq.push(frame); }; animation.onFinish = () => { expect(seq).to.be.deep.equal([4, 3, 2]); @@ -73,18 +68,14 @@ describe('lib/keyframe-animation', function() { done(); }; - animation.reverse = true; - animation.play({ - startFrame: 4, - endFrame: 2, - }); + animation.play({ start: 4, end: 2 }); }); it('should begin from current state starting below range', (done) => { const seq = []; const animation = newAnimation(); - animation.onFrame = () => { - seq.push(animation._currentFrame); + animation.onFrame = (frame) => { + seq.push(frame); }; animation.onFinish = () => { expect(seq).to.be.deep.equal([0, 1, 2, 3, 4]); @@ -93,43 +84,14 @@ describe('lib/keyframe-animation', function() { }; animation._currentFrame = 0; - animation._isFirstRun = false; - - animation.play({ - beginFromCurrentState: true, - startFrame: 3, - endFrame: 4, - }); - }); - - it('should begin from current state starting below range reverse', (done) => { - const seq = []; - const animation = newAnimation(); - animation.onFrame = () => { - seq.push(animation._currentFrame); - }; - animation.onFinish = () => { - expect(seq).to.be.deep.equal([0, 1, 2, 3]); - expect(animation._currentFrame).to.be.equal(3); - done(); - }; - - animation._currentFrame = 0; - animation._isFirstRun = false; - animation.reverse = true; - - animation.play({ - beginFromCurrentState: true, - startFrame: 3, - endFrame: 4, - }); + animation.play({ end: 4 }); }); it('should begin from current state starting above range', (done) => { const seq = []; const animation = newAnimation(); - animation.onFrame = () => { - seq.push(animation._currentFrame); + animation.onFrame = (frame) => { + seq.push(frame); }; animation.onFinish = () => { expect(seq).to.be.deep.equal([4, 3, 2]); @@ -138,20 +100,14 @@ describe('lib/keyframe-animation', function() { }; animation._currentFrame = 4; - animation._isFirstRun = false; - - animation.play({ - beginFromCurrentState: true, - startFrame: 1, - endFrame: 2, - }); + animation.play({ end: 2 }); }); it('should begin from current state starting above range reverse', (done) => { const seq = []; const animation = newAnimation(); - animation.onFrame = () => { - seq.push(animation._currentFrame); + animation.onFrame = (frame) => { + seq.push(frame); }; animation.onFinish = () => { expect(seq).to.be.deep.equal([4, 3, 2, 1]); @@ -160,21 +116,14 @@ describe('lib/keyframe-animation', function() { }; animation._currentFrame = 4; - animation._isFirstRun = false; - animation.reverse = true; - - animation.play({ - beginFromCurrentState: true, - startFrame: 1, - endFrame: 3, - }); + animation.play({ end: 1 }); }); it('should play sequence in reverse', (done) => { const seq = []; const animation = newAnimation(); - animation.onFrame = () => { - seq.push(animation._currentFrame); + animation.onFrame = (frame) => { + seq.push(frame); }; animation.onFinish = () => { expect(seq).to.be.deep.equal([4, 3, 2, 1, 0]); @@ -182,7 +131,6 @@ describe('lib/keyframe-animation', function() { done(); }; - animation.reverse = true; - animation.play(); + animation.play({ start: 4, end: 0 }); }); }); |
