Skip to content

Commit 4e6ffee

Browse files
committed
Old-way is better this case;
1 parent 8f734de commit 4e6ffee

File tree

2 files changed

+98
-57
lines changed

2 files changed

+98
-57
lines changed

src/util/LoopController.js

Lines changed: 84 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,107 @@
1-
let loopIsActive = false;
2-
let animationFrame = null;
3-
const loopRegister = [];
4-
5-
class LoopController
6-
{
7-
constructor() {
8-
this.rafStep = this.rafStep.bind(this);
9-
}
10-
11-
getRegisteredItems() {
12-
return [...loopRegister];
13-
}
14-
15-
registerScrollbar(scrollbar) {
16-
if (!loopRegister.includes(scrollbar)) {
17-
loopRegister.push(scrollbar);
18-
19-
this.start();
1+
function LoopControllerClass() {
2+
/**
3+
* @typedef {Object} Scrollbar
4+
* @property {function} update
5+
*/
6+
7+
/**
8+
* @type {Scrollbar[]}
9+
*/
10+
const scrollbarsRegister = [];
11+
12+
/**
13+
* true if loop is active
14+
* @type {boolean}
15+
*/
16+
let isActive = false;
17+
/**
18+
* ID of requested animation frame
19+
* @type {null|number}
20+
*/
21+
let animationFrameId = null;
22+
23+
/**
24+
* Function that called in animation frame
25+
*/
26+
const animationFrameCallback = () => {
27+
if (!isActive) {return;}
28+
29+
for (let scrollbar of scrollbarsRegister) {
30+
scrollbar.update();
2031
}
2132

22-
return this;
33+
requestAnimationFrame(animationFrameCallback);
2334
};
2435

25-
unregisterScrollbar(scrollbar) {
26-
let index = loopRegister.indexOf(scrollbar);
36+
/**
37+
* Stop the loop if it wasn't active
38+
* @return {LoopControllerClass}
39+
*/
40+
this.start = () => {
41+
if (isActive) {return this;}
2742

28-
if (index !== -1) {
29-
loopRegister.length === 1 && this.stop();
43+
isActive = true;
3044

31-
loopRegister.splice(index, 1);
32-
}
33-
34-
return this;
45+
animationFrameId && cancelAnimationFrame(animationFrameId);
46+
requestAnimationFrame(animationFrameCallback);
3547
};
48+
/**
49+
* Stop the loop if it is active
50+
* @return {LoopControllerClass}
51+
*/
52+
this.stop = () => {
53+
if (!isActive) {return this;}
3654

37-
start() {
38-
if (!loopIsActive) {
39-
loopIsActive = true;
55+
isActive = false;
4056

41-
animationFrame && cancelAnimationFrame(animationFrame);
42-
animationFrame = requestAnimationFrame(this.rafStep);
43-
}
44-
45-
return this;
57+
animationFrameId && cancelAnimationFrame(animationFrameId);
58+
animationFrameId = null;
4659
};
4760

48-
rafStep() {
49-
if (!loopIsActive) {return;}
61+
/**
62+
* Return the array pf registered scrollbars
63+
* @return {Scrollbar[]}
64+
*/
65+
this.getRegisteredScrollbars = () => {
66+
return [...scrollbarsRegister];
67+
};
68+
/**
69+
* Add the scrollbar to list to iterate each loop
70+
* @param {Scrollbar} scrollbar
71+
* @return {LoopControllerClass}
72+
*/
73+
this.registerScrollbar = (scrollbar) => {
74+
if (scrollbarsRegister.indexOf(scrollbar) === -1) {
75+
scrollbarsRegister.push(scrollbar);
5076

51-
for (let i = 0; i < loopRegister.length; i++) {
52-
loopRegister[i].update();
77+
this.start();
5378
}
5479

55-
animationFrame = requestAnimationFrame(this.rafStep);
80+
return this;
5681
};
82+
/**
83+
* Remove the scrollbar from list to iterate each loop
84+
* @param {Scrollbar} scrollbar
85+
* @return {LoopControllerClass}
86+
*/
87+
this.unregisterScrollbar = (scrollbar) => {
88+
const index = scrollbarsRegister.indexOf(scrollbar);
5789

58-
stop() {
59-
if (loopIsActive) {
60-
loopIsActive = false;
61-
62-
animationFrame && cancelAnimationFrame(animationFrame);
90+
if (index !== -1) {
91+
scrollbarsRegister.splice(index, 1);
6392
}
6493

6594
return this;
6695
};
6796
}
6897

69-
const instance = new LoopController();
98+
export const LoopController = new LoopControllerClass();
99+
export default LoopController;
70100

71-
export default instance;
101+
/**
102+
* Return new instance of LoopControllerClass
103+
* @return {LoopControllerClass}
104+
*/
105+
export function createLoopController() {
106+
return new LoopControllerClass();
107+
}

tests/LoopController.spec.js

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import expect from "expect";
2-
import React from "react";
3-
import sinon from 'sinon';
4-
import LoopController from '../src/util/LoopController';
1+
import expect from "expect";
2+
import React from "react";
3+
import sinon from 'sinon';
4+
import { createLoopController, LoopController } from '../src/util/LoopController';
55

66
describe("LoopController", () => {
77
const ScrollbarMock = {
@@ -12,17 +12,18 @@ describe("LoopController", () => {
1212

1313
it("should register the scrollbar", () => {
1414
LoopController.registerScrollbar(ScrollbarMock);
15-
expect(LoopController.getRegisteredItems().length).toEqual(1);
15+
expect(LoopController.getRegisteredScrollbars().length).toEqual(1);
16+
expect(LoopController.getRegisteredScrollbars()[0]).toEqual(ScrollbarMock);
1617
});
1718

1819
it("should call an 'update' method of registered scrollbar", (done) => {
1920
setTimeout(() => {
20-
expect(spy.callCount).toBeGreaterThan(10);
21+
expect(spy.callCount).toBeGreaterThanOrEqual(30);
2122
done();
2223
}, 500);
2324
});
2425

25-
it("should call stop the loop when .stop() executed", (done) => {
26+
it("should stop the loop when .stop() executed", (done) => {
2627
let callCount = spy.callCount * 1;
2728
LoopController.stop();
2829

@@ -32,7 +33,7 @@ describe("LoopController", () => {
3233
}, 500);
3334
});
3435

35-
it("should call start the loop when .start() executed", (done) => {
36+
it("should start the loop when .start() executed", (done) => {
3637
let callCount = spy.callCount * 1;
3738
LoopController.start();
3839

@@ -44,6 +45,10 @@ describe("LoopController", () => {
4445

4546
it("should unregister the scrollbar", () => {
4647
LoopController.unregisterScrollbar(ScrollbarMock);
47-
expect(LoopController.getRegisteredItems().length).toEqual(0);
48+
expect(LoopController.getRegisteredScrollbars().length).toEqual(0);
49+
});
50+
51+
it("createLoopController should return new controller", () => {
52+
expect(createLoopController()).not.toEqual(LoopController);
4853
});
4954
});

0 commit comments

Comments
 (0)