@figliolia/chalk-animation 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/Animation.js +25 -36
  3. package/dist/cjs/ChalkAnimation.js +26 -21
  4. package/dist/cjs/Decor.js +18 -0
  5. package/dist/cjs/Effects.js +28 -3
  6. package/dist/cjs/FrameRate.js +26 -0
  7. package/dist/cjs/InstanceTracker.js +4 -2
  8. package/dist/cjs/__tests__/ChalkAnimation.test.js +95 -0
  9. package/dist/cjs/package.json +2 -2
  10. package/dist/mjs/Animation.js +20 -33
  11. package/dist/mjs/ChalkAnimation.js +26 -23
  12. package/dist/mjs/Decor.js +14 -0
  13. package/dist/mjs/Effects.js +27 -2
  14. package/dist/mjs/FrameRate.js +24 -0
  15. package/dist/mjs/InstanceTracker.js +2 -2
  16. package/dist/mjs/__tests__/ChalkAnimation.test.js +93 -0
  17. package/dist/mjs/index.js +2 -2
  18. package/dist/mjs/package.json +3 -2
  19. package/dist/types/Animation.d.ts +16 -0
  20. package/dist/types/ChalkAnimation.d.ts +21 -0
  21. package/dist/types/Decor.d.ts +5 -0
  22. package/dist/{mjs → types}/Effects.d.ts +2 -2
  23. package/dist/types/FrameRate.d.ts +11 -0
  24. package/dist/{mjs → types}/InstanceTracker.d.ts +1 -0
  25. package/dist/types/__tests__/ChalkAnimation.test.d.ts +1 -0
  26. package/dist/{cjs → types}/index.d.ts +1 -0
  27. package/dist/types/types.d.ts +6 -0
  28. package/package.json +7 -8
  29. package/src/Animation.ts +20 -34
  30. package/src/ChalkAnimation.ts +25 -26
  31. package/src/Decor.ts +24 -0
  32. package/src/Effects.ts +14 -6
  33. package/src/FrameRate.ts +28 -0
  34. package/src/InstanceTracker.ts +5 -3
  35. package/src/__tests__/ChalkAnimation.test.ts +108 -0
  36. package/src/index.ts +1 -0
  37. package/src/types.ts +14 -0
  38. package/dist/cjs/Animation.d.ts +0 -20
  39. package/dist/cjs/ChalkAnimation.d.ts +0 -10
  40. package/dist/cjs/Effects.d.ts +0 -13
  41. package/dist/cjs/InstanceTracker.d.ts +0 -14
  42. package/dist/cjs/animateString.d.ts +0 -2
  43. package/dist/cjs/animateString.js +0 -18
  44. package/dist/cjs/types.d.ts +0 -1
  45. package/dist/mjs/Animation.d.ts +0 -20
  46. package/dist/mjs/ChalkAnimation.d.ts +0 -10
  47. package/dist/mjs/animateString.d.ts +0 -2
  48. package/dist/mjs/animateString.js +0 -14
  49. package/dist/mjs/index.d.ts +0 -4
  50. package/dist/mjs/types.d.ts +0 -1
  51. package/src/animateString.ts +0 -15
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # chalk-animation
2
2
 
3
- > Colorful animations in terminal output
3
+ Colorful animations in terminal output
4
4
 
5
5
 
6
6
  ## Available animations
@@ -1,18 +1,28 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Animation = void 0;
4
- const InstanceTracker_1 = require("./InstanceTracker");
5
- class Animation extends InstanceTracker_1.InstanceTracker {
4
+ const FrameRate_1 = require("./FrameRate");
5
+ const Decor_1 = require("./Decor");
6
+ class Animation extends FrameRate_1.FrameRate {
6
7
  constructor(effect, str, delay = 0, speed = 0) {
7
- super();
8
+ super(delay, speed);
8
9
  this.stopped = false;
9
- this.currentFrame = 0;
10
10
  this.initialized = false;
11
- this.controller = null;
11
+ this.replace = Decor_1.Decor.chainable(this, (str) => {
12
+ this.text = str.split(Animation.LINE_BREAKS);
13
+ this.lines = this.text.length;
14
+ });
15
+ this.stop = Decor_1.Decor.chainable(this, () => {
16
+ this.clearFrames();
17
+ this.stopped = true;
18
+ });
19
+ this.start = Decor_1.Decor.chainable(this, () => {
20
+ this.clearFrames();
21
+ this.stopped = false;
22
+ this.render();
23
+ });
12
24
  this.effect = effect;
13
- this.speed = speed;
14
- this.delay = delay;
15
- this.text = str.split(/\r\n|\r|\n/);
25
+ this.text = str.split(Animation.LINE_BREAKS);
16
26
  this.lines = this.text.length;
17
27
  }
18
28
  render() {
@@ -20,41 +30,20 @@ class Animation extends InstanceTracker_1.InstanceTracker {
20
30
  Animation.LOG("\n".repeat(this.lines - 1));
21
31
  this.initialized = true;
22
32
  }
23
- Animation.LOG(this.frame());
24
- this.controller = setTimeout(() => {
33
+ Animation.LOG(this.nextFrame());
34
+ this.schedule(() => {
25
35
  if (!this.stopped) {
26
36
  this.render();
27
37
  }
28
- }, this.delay / this.speed);
38
+ });
29
39
  }
30
- frame() {
31
- this.currentFrame++;
40
+ nextFrame() {
41
+ this.increment();
32
42
  return ("\u001B[" +
33
43
  `${this.lines}` +
34
44
  "F\u001B[G\u001B[2K" +
35
- this.text.map((str) => this.effect(str, this.currentFrame)).join("\n"));
36
- }
37
- replace(str) {
38
- this.text = str.split(/\r\n|\r|\n/);
39
- this.lines = this.text.length;
40
- return this;
41
- }
42
- stop() {
43
- this.clearFrames();
44
- this.stopped = true;
45
- return this;
46
- }
47
- start() {
48
- this.clearFrames();
49
- this.stopped = false;
50
- this.render();
51
- return this;
52
- }
53
- clearFrames() {
54
- if (this.controller) {
55
- clearTimeout(this.controller);
56
- this.controller = null;
57
- }
45
+ this.text.map(str => this.effect(str, this.current)).join("\n"));
58
46
  }
59
47
  }
60
48
  exports.Animation = Animation;
49
+ Animation.LINE_BREAKS = /\r\n|\r|\n/;
@@ -1,30 +1,35 @@
1
1
  "use strict";
2
+ var _a;
2
3
  Object.defineProperty(exports, "__esModule", { value: true });
3
4
  exports.ChalkAnimation = void 0;
4
5
  const Effects_1 = require("./Effects");
5
6
  const Animation_1 = require("./Animation");
6
- const animateString_1 = require("./animateString");
7
+ /**
8
+ * Chalk Animation
9
+ *
10
+ * Console animations for your CLI tools
11
+ *
12
+ * ```typescript
13
+ * const animation = ChalkAnimation.rainbow("hello!");
14
+ * animation.stop();
15
+ * animation.start();
16
+ * ```
17
+ */
7
18
  class ChalkAnimation {
8
- static rainbow(str, speed = 1) {
9
- return (0, animateString_1.animateString)(Effects_1.Effects.rainbow, str, 15, speed);
10
- }
11
- static pulse(str, speed = 1) {
12
- return (0, animateString_1.animateString)(Effects_1.Effects.pulse, str, 16, speed);
13
- }
14
- static glitch(str, speed = 1) {
15
- return (0, animateString_1.animateString)(Effects_1.Effects.glitch, str, 55, speed);
16
- }
17
- static radar(str, speed = 1) {
18
- return (0, animateString_1.animateString)(Effects_1.Effects.radar, str, 50, speed);
19
- }
20
- static neon(str, speed = 1) {
21
- return (0, animateString_1.animateString)(Effects_1.Effects.neon, str, 500, speed);
22
- }
23
- static karaoke(str, speed = 1) {
24
- return (0, animateString_1.animateString)(Effects_1.Effects.karaoke, str, 50, speed);
25
- }
26
- static clearAllAnimations() {
27
- return Animation_1.Animation.clearAll();
19
+ static configure(effect, delay) {
20
+ return (str, speed = 1) => {
21
+ if (!speed || speed <= 0) {
22
+ throw new Error("Expected `speed` to be an number greater than 0");
23
+ }
24
+ return new Animation_1.Animation(Effects_1.Effects[effect], str, delay, speed).start();
25
+ };
28
26
  }
29
27
  }
30
28
  exports.ChalkAnimation = ChalkAnimation;
29
+ _a = ChalkAnimation;
30
+ ChalkAnimation.neon = _a.configure("neon", 500);
31
+ ChalkAnimation.radar = _a.configure("radar", 50);
32
+ ChalkAnimation.pulse = _a.configure("pulse", 16);
33
+ ChalkAnimation.glitch = _a.configure("glitch", 55);
34
+ ChalkAnimation.rainbow = _a.configure("rainbow", 15);
35
+ ChalkAnimation.karaoke = _a.configure("karaoke", 50);
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Decor = void 0;
4
+ class Decor {
5
+ static bound(target, _propertyKey, descriptor) {
6
+ const operation = descriptor.value;
7
+ if (operation) {
8
+ descriptor.value = operation.bind(target);
9
+ }
10
+ }
11
+ static chainable(instance, func) {
12
+ return (...params) => {
13
+ func(...params);
14
+ return instance;
15
+ };
16
+ }
17
+ }
18
+ exports.Decor = Decor;
@@ -1,4 +1,10 @@
1
1
  "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
2
8
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
9
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
10
  };
@@ -6,12 +12,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
12
  exports.Effects = void 0;
7
13
  const chalk_1 = __importDefault(require("chalk"));
8
14
  const gradient_string_1 = __importDefault(require("gradient-string"));
15
+ const Decor_1 = require("./Decor");
9
16
  class Effects {
10
17
  static rainbow(str, frame) {
11
18
  const hue = 5 * frame;
12
19
  const leftColor = { h: hue % 360, s: 1, v: 1 };
13
20
  const rightColor = { h: (hue + 1) % 360, s: 1, v: 1 };
14
- return (0, gradient_string_1.default)(leftColor, rightColor)(str, Effects.longHsv);
21
+ return (0, gradient_string_1.default)(leftColor, rightColor)(str, this.longHsv);
15
22
  }
16
23
  static pulse(str, frame) {
17
24
  frame = (frame % 120) + 1;
@@ -56,7 +63,7 @@ class Effects {
56
63
  i += skip;
57
64
  if (str[i]) {
58
65
  if (str[i] !== "\n" && str[i] !== "\r" && Math.random() > 0.995) {
59
- chunks.push(Effects.glitchChars[Math.floor(Math.random() * Effects.glitchChars.length)]);
66
+ chunks.push(this.glitchChars[Math.floor(Math.random() * this.glitchChars.length)]);
60
67
  }
61
68
  else if (Math.random() > 0.005) {
62
69
  chunks.push(str[i]);
@@ -104,6 +111,24 @@ class Effects {
104
111
  chalk_1.default.white(str.substr(chars)));
105
112
  }
106
113
  }
107
- exports.Effects = Effects;
108
114
  Effects.longHsv = { interpolation: "hsv", hsvSpin: "long" };
109
115
  Effects.glitchChars = "x*0987654321[]0-~@#(____!!!!\\|?????....0000\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
116
+ __decorate([
117
+ Decor_1.Decor.bound
118
+ ], Effects, "rainbow", null);
119
+ __decorate([
120
+ Decor_1.Decor.bound
121
+ ], Effects, "pulse", null);
122
+ __decorate([
123
+ Decor_1.Decor.bound
124
+ ], Effects, "glitch", null);
125
+ __decorate([
126
+ Decor_1.Decor.bound
127
+ ], Effects, "radar", null);
128
+ __decorate([
129
+ Decor_1.Decor.bound
130
+ ], Effects, "neon", null);
131
+ __decorate([
132
+ Decor_1.Decor.bound
133
+ ], Effects, "karaoke", null);
134
+ exports.Effects = Effects;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FrameRate = void 0;
4
+ const InstanceTracker_1 = require("./InstanceTracker");
5
+ class FrameRate extends InstanceTracker_1.InstanceTracker {
6
+ constructor(delay, speed) {
7
+ super();
8
+ this.current = 0;
9
+ this.controller = null;
10
+ this.delay = delay;
11
+ this.speed = speed;
12
+ }
13
+ schedule(func) {
14
+ this.controller = setTimeout(func, this.delay / this.speed);
15
+ }
16
+ increment() {
17
+ this.current++;
18
+ }
19
+ clearFrames() {
20
+ if (this.controller) {
21
+ clearTimeout(this.controller);
22
+ this.controller = null;
23
+ }
24
+ }
25
+ }
26
+ exports.FrameRate = FrameRate;
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+ var _a;
2
3
  Object.defineProperty(exports, "__esModule", { value: true });
3
4
  exports.InstanceTracker = void 0;
4
5
  const event_emitter_1 = require("@figliolia/event-emitter");
@@ -19,12 +20,13 @@ class InstanceTracker {
19
20
  }
20
21
  }
21
22
  exports.InstanceTracker = InstanceTracker;
23
+ _a = InstanceTracker;
22
24
  InstanceTracker.LOG = console.log;
23
25
  InstanceTracker.IDs = new event_emitter_1.AutoIncrementingID();
24
26
  InstanceTracker.bucket = new Map();
27
+ InstanceTracker.loggers = ["log", "warn", "info", "error"];
25
28
  (() => {
26
- const methods = ["log", "warn", "info", "error"];
27
- methods.forEach((method) => {
29
+ _a.loggers.forEach(method => {
28
30
  const original = console[method];
29
31
  console[method] = function (...args) {
30
32
  InstanceTracker.clearAll();
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ChalkAnimation_1 = require("../ChalkAnimation");
4
+ const Effects_1 = require("../Effects");
5
+ const InstanceTracker_1 = require("../InstanceTracker");
6
+ const animations = [
7
+ "rainbow",
8
+ "pulse",
9
+ "glitch",
10
+ "radar",
11
+ "neon",
12
+ "karaoke",
13
+ ];
14
+ describe("Chalk Animation", () => {
15
+ afterAll(() => {
16
+ jest.restoreAllMocks();
17
+ });
18
+ describe("Spawn", () => {
19
+ beforeAll(() => {
20
+ jest.spyOn(InstanceTracker_1.InstanceTracker, "LOG").mockImplementation(() => { });
21
+ });
22
+ afterEach(() => {
23
+ InstanceTracker_1.InstanceTracker.clearAll();
24
+ InstanceTracker_1.InstanceTracker.IDs.reset();
25
+ });
26
+ animations.forEach(name => {
27
+ it(`ChalkAnimation.${name} - returns an initialized animation instance`, () => {
28
+ const animation = ChalkAnimation_1.ChalkAnimation[name]("hello");
29
+ expect(animation.effect).toEqual(Effects_1.Effects[name]);
30
+ expect(typeof animation.ID).toEqual("string");
31
+ expect(animation.text).toEqual(["hello"]);
32
+ expect(animation.lines).toEqual(1);
33
+ expect(animation.speed).toEqual(1);
34
+ expect(animation.current).toEqual(1);
35
+ expect(animation.initialized).toEqual(true);
36
+ expect(animation.stopped).toEqual(false);
37
+ expect(animation.controller).not.toEqual(null);
38
+ expect(InstanceTracker_1.InstanceTracker.bucket.size).toEqual(1);
39
+ animation.stop();
40
+ expect(animation.stopped).toEqual(true);
41
+ expect(animation.controller).toEqual(null);
42
+ });
43
+ InstanceTracker_1.InstanceTracker.loggers.forEach(method => {
44
+ it(`ChalkAnimation.${name} - subsequent console.${method} stop the animation`, () => {
45
+ const animation = ChalkAnimation_1.ChalkAnimation[name]("hello");
46
+ expect(animation.stopped).toEqual(false);
47
+ console[method]("");
48
+ expect(animation.stopped).toEqual(true);
49
+ });
50
+ });
51
+ it(`ChalkAnimation.${name} - can be stopped and restarted`, () => {
52
+ const animation = ChalkAnimation_1.ChalkAnimation[name]("hello");
53
+ animation.stop();
54
+ expect(animation.stopped).toEqual(true);
55
+ animation.start();
56
+ expect(animation.current).toEqual(2);
57
+ });
58
+ it(`ChalkAnimation.${name} - can be manually rendered at a desired frame rate`, () => {
59
+ const animation = ChalkAnimation_1.ChalkAnimation[name]("hello").stop();
60
+ expect(animation.current).toEqual(1);
61
+ animation.render();
62
+ expect(animation.current).toEqual(2);
63
+ animation.render();
64
+ expect(animation.current).toEqual(3);
65
+ });
66
+ it(`ChalkAnimation.${name} - text can be replaced`, () => {
67
+ if (name === "radar") {
68
+ return;
69
+ }
70
+ const animation = ChalkAnimation_1.ChalkAnimation[name]("Y Y Y").stop();
71
+ const f1 = animation.nextFrame();
72
+ animation.replace("Z Z Z");
73
+ const f2 = animation.nextFrame();
74
+ expect(f1.includes("Y")).toEqual(true);
75
+ expect(f1.includes("Z")).toEqual(false);
76
+ expect(f2.includes("Y")).toEqual(false);
77
+ expect(f2.includes("Z")).toEqual(true);
78
+ });
79
+ it(`ChalkAnimation.${name} - supports multiline strings`, () => {
80
+ const animation = ChalkAnimation_1.ChalkAnimation[name]("Lorem\nipsum\ndolor\nsit\namet").stop();
81
+ const frame = animation.nextFrame();
82
+ expect(animation.lines).toEqual(5);
83
+ expect(frame.split("\n")).toHaveLength(5);
84
+ });
85
+ it(`ChalkAnimation.${name} - supports 5K+ frames`, () => {
86
+ const animation = ChalkAnimation_1.ChalkAnimation[name]("Lorem\nipsum\ndolor\nsit\namet").stop();
87
+ for (let i = 0; i < 5000; i++) {
88
+ expect(() => {
89
+ animation.nextFrame();
90
+ }).not.toThrow();
91
+ }
92
+ });
93
+ });
94
+ });
95
+ });
@@ -1,3 +1,3 @@
1
1
  {
2
- "type": "commonjs"
3
- }
2
+ "type": "commonjs"
3
+ }
@@ -1,20 +1,16 @@
1
- import { InstanceTracker } from "./InstanceTracker";
2
- export class Animation extends InstanceTracker {
3
- effect;
1
+ import { FrameRate } from "./FrameRate.js";
2
+ import { Decor } from "./Decor.js";
3
+ export class Animation extends FrameRate {
4
4
  lines;
5
- speed;
6
- delay;
7
5
  text;
8
6
  stopped = false;
9
- currentFrame = 0;
10
7
  initialized = false;
11
- controller = null;
8
+ effect;
9
+ static LINE_BREAKS = /\r\n|\r|\n/;
12
10
  constructor(effect, str, delay = 0, speed = 0) {
13
- super();
11
+ super(delay, speed);
14
12
  this.effect = effect;
15
- this.speed = speed;
16
- this.delay = delay;
17
- this.text = str.split(/\r\n|\r|\n/);
13
+ this.text = str.split(Animation.LINE_BREAKS);
18
14
  this.lines = this.text.length;
19
15
  }
20
16
  render() {
@@ -22,40 +18,31 @@ export class Animation extends InstanceTracker {
22
18
  Animation.LOG("\n".repeat(this.lines - 1));
23
19
  this.initialized = true;
24
20
  }
25
- Animation.LOG(this.frame());
26
- this.controller = setTimeout(() => {
21
+ Animation.LOG(this.nextFrame());
22
+ this.schedule(() => {
27
23
  if (!this.stopped) {
28
24
  this.render();
29
25
  }
30
- }, this.delay / this.speed);
26
+ });
31
27
  }
32
- frame() {
33
- this.currentFrame++;
28
+ nextFrame() {
29
+ this.increment();
34
30
  return ("\u001B[" +
35
31
  `${this.lines}` +
36
32
  "F\u001B[G\u001B[2K" +
37
- this.text.map((str) => this.effect(str, this.currentFrame)).join("\n"));
33
+ this.text.map(str => this.effect(str, this.current)).join("\n"));
38
34
  }
39
- replace(str) {
40
- this.text = str.split(/\r\n|\r|\n/);
35
+ replace = Decor.chainable(this, (str) => {
36
+ this.text = str.split(Animation.LINE_BREAKS);
41
37
  this.lines = this.text.length;
42
- return this;
43
- }
44
- stop() {
38
+ });
39
+ stop = Decor.chainable(this, () => {
45
40
  this.clearFrames();
46
41
  this.stopped = true;
47
- return this;
48
- }
49
- start() {
42
+ });
43
+ start = Decor.chainable(this, () => {
50
44
  this.clearFrames();
51
45
  this.stopped = false;
52
46
  this.render();
53
- return this;
54
- }
55
- clearFrames() {
56
- if (this.controller) {
57
- clearTimeout(this.controller);
58
- this.controller = null;
59
- }
60
- }
47
+ });
61
48
  }
@@ -1,26 +1,29 @@
1
- import { Effects } from "./Effects";
2
- import { Animation } from "./Animation";
3
- import { animateString } from "./animateString";
1
+ import { Effects } from "./Effects.js";
2
+ import { Animation } from "./Animation.js";
3
+ /**
4
+ * Chalk Animation
5
+ *
6
+ * Console animations for your CLI tools
7
+ *
8
+ * ```typescript
9
+ * const animation = ChalkAnimation.rainbow("hello!");
10
+ * animation.stop();
11
+ * animation.start();
12
+ * ```
13
+ */
4
14
  export class ChalkAnimation {
5
- static rainbow(str, speed = 1) {
6
- return animateString(Effects.rainbow, str, 15, speed);
7
- }
8
- static pulse(str, speed = 1) {
9
- return animateString(Effects.pulse, str, 16, speed);
10
- }
11
- static glitch(str, speed = 1) {
12
- return animateString(Effects.glitch, str, 55, speed);
13
- }
14
- static radar(str, speed = 1) {
15
- return animateString(Effects.radar, str, 50, speed);
16
- }
17
- static neon(str, speed = 1) {
18
- return animateString(Effects.neon, str, 500, speed);
19
- }
20
- static karaoke(str, speed = 1) {
21
- return animateString(Effects.karaoke, str, 50, speed);
22
- }
23
- static clearAllAnimations() {
24
- return Animation.clearAll();
15
+ static neon = this.configure("neon", 500);
16
+ static radar = this.configure("radar", 50);
17
+ static pulse = this.configure("pulse", 16);
18
+ static glitch = this.configure("glitch", 55);
19
+ static rainbow = this.configure("rainbow", 15);
20
+ static karaoke = this.configure("karaoke", 50);
21
+ static configure(effect, delay) {
22
+ return (str, speed = 1) => {
23
+ if (!speed || speed <= 0) {
24
+ throw new Error("Expected `speed` to be an number greater than 0");
25
+ }
26
+ return new Animation(Effects[effect], str, delay, speed).start();
27
+ };
25
28
  }
26
29
  }
@@ -0,0 +1,14 @@
1
+ export class Decor {
2
+ static bound(target, _propertyKey, descriptor) {
3
+ const operation = descriptor.value;
4
+ if (operation) {
5
+ descriptor.value = operation.bind(target);
6
+ }
7
+ }
8
+ static chainable(instance, func) {
9
+ return (...params) => {
10
+ func(...params);
11
+ return instance;
12
+ };
13
+ }
14
+ }
@@ -1,5 +1,12 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
1
7
  import chalk from "chalk";
2
8
  import gradient from "gradient-string";
9
+ import { Decor } from "./Decor.js";
3
10
  export class Effects {
4
11
  static longHsv = { interpolation: "hsv", hsvSpin: "long" };
5
12
  static glitchChars = "x*0987654321[]0-~@#(____!!!!\\|?????....0000\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
@@ -7,7 +14,7 @@ export class Effects {
7
14
  const hue = 5 * frame;
8
15
  const leftColor = { h: hue % 360, s: 1, v: 1 };
9
16
  const rightColor = { h: (hue + 1) % 360, s: 1, v: 1 };
10
- return gradient(leftColor, rightColor)(str, Effects.longHsv);
17
+ return gradient(leftColor, rightColor)(str, this.longHsv);
11
18
  }
12
19
  static pulse(str, frame) {
13
20
  frame = (frame % 120) + 1;
@@ -52,7 +59,7 @@ export class Effects {
52
59
  i += skip;
53
60
  if (str[i]) {
54
61
  if (str[i] !== "\n" && str[i] !== "\r" && Math.random() > 0.995) {
55
- chunks.push(Effects.glitchChars[Math.floor(Math.random() * Effects.glitchChars.length)]);
62
+ chunks.push(this.glitchChars[Math.floor(Math.random() * this.glitchChars.length)]);
56
63
  }
57
64
  else if (Math.random() > 0.005) {
58
65
  chunks.push(str[i]);
@@ -100,3 +107,21 @@ export class Effects {
100
107
  chalk.white(str.substr(chars)));
101
108
  }
102
109
  }
110
+ __decorate([
111
+ Decor.bound
112
+ ], Effects, "rainbow", null);
113
+ __decorate([
114
+ Decor.bound
115
+ ], Effects, "pulse", null);
116
+ __decorate([
117
+ Decor.bound
118
+ ], Effects, "glitch", null);
119
+ __decorate([
120
+ Decor.bound
121
+ ], Effects, "radar", null);
122
+ __decorate([
123
+ Decor.bound
124
+ ], Effects, "neon", null);
125
+ __decorate([
126
+ Decor.bound
127
+ ], Effects, "karaoke", null);
@@ -0,0 +1,24 @@
1
+ import { InstanceTracker } from "./InstanceTracker.js";
2
+ export class FrameRate extends InstanceTracker {
3
+ current = 0;
4
+ speed;
5
+ delay;
6
+ controller = null;
7
+ constructor(delay, speed) {
8
+ super();
9
+ this.delay = delay;
10
+ this.speed = speed;
11
+ }
12
+ schedule(func) {
13
+ this.controller = setTimeout(func, this.delay / this.speed);
14
+ }
15
+ increment() {
16
+ this.current++;
17
+ }
18
+ clearFrames() {
19
+ if (this.controller) {
20
+ clearTimeout(this.controller);
21
+ this.controller = null;
22
+ }
23
+ }
24
+ }
@@ -4,14 +4,14 @@ export class InstanceTracker {
4
4
  static LOG = console.log;
5
5
  static IDs = new AutoIncrementingID();
6
6
  static bucket = new Map();
7
+ static loggers = ["log", "warn", "info", "error"];
7
8
  constructor() {
8
9
  InstanceTracker.clearAll();
9
10
  this.ID = InstanceTracker.IDs.get();
10
11
  InstanceTracker.bucket.set(this.ID, this.instance);
11
12
  }
12
13
  static {
13
- const methods = ["log", "warn", "info", "error"];
14
- methods.forEach((method) => {
14
+ this.loggers.forEach(method => {
15
15
  const original = console[method];
16
16
  console[method] = function (...args) {
17
17
  InstanceTracker.clearAll();