PageSourceSearch

https://yourfitness.coach/js_v2/typer.js

js yourfitness.coach collected 2026-09-24 14:10:53 UTC 3,313 bytes, 116 lines download raw bytes

1var Typer = function(element) {
2  this.element = element;
3  var delim = element.dataset.delim || ",";
4  var words = element.dataset.words || "override these,sample typing";
5  this.words = words.split(delim).filter((v) => v); // non empty words
6  this.delay = element.dataset.delay || 200;
7  this.loop = element.dataset.loop || "true";
8  if (this.loop === "false" ) { this.loop = 1 }
9  this.deleteDelay = element.dataset.deletedelay || element.dataset.deleteDelay || 800;
10
11  this.progress = { word: 0, char: 0, building: true, looped: 0 };
12  this.typing = true;
13
14  var colors = element.dataset.colors || "black";
15  this.colors = colors.split(",");
16  this.element.style.color = this.colors[0];
17  this.colorIndex = 0;
18
19  this.doTyping();
20};
21
22Typer.prototype.start = function() {
23  if (!this.typing) {
24    this.typing = true;
25    this.doTyping();
26  }
27};
28Typer.prototype.stop = function() {
29  this.typing = false;
30};
31Typer.prototype.doTyping = function() {
32  var e = this.element;
33  var p = this.progress;
34  var w = p.word;
35  var c = p.char;
36  var currentDisplay = [...this.words[w]].slice(0, c).join("");
37  var atWordEnd;
38  if (this.cursor) {
39    this.cursor.element.style.opacity = "1";
40    this.cursor.on = true;
41    clearInterval(this.cursor.interval);
42    this.cursor.interval = setInterval(() => this.cursor.updateBlinkState(), 400);
43  }
44
45  e.innerHTML = currentDisplay;
46
47  if (p.building) {
48    atWordEnd = p.char === this.words[w].length;
49    if (atWordEnd) {
50      p.building = false;
51    } else {
52      p.char += 1;
53    }
54  } else {
55    if (p.char === 0) {
56      p.building = true;
57      p.word = (p.word + 1) % this.words.length;
58      this.colorIndex = (this.colorIndex + 1) % this.colors.length;
59      this.element.style.color = this.colors[this.colorIndex];
60    } else {
61      p.char -= 1;
62    }
63  }
64
65  if (p.word === this.words.length - 1) {
66    p.looped += 1;
67  }
68
69  if (!p.building && this.loop <= p.looped){
70    this.typing = false;
71  }
72
73  setTimeout(() => {
74    if (this.typing) { this.doTyping() };
75  }, atWordEnd ? this.deleteDelay : this.delay);
76};
77
78var Cursor = function(element) {
79  this.element = element;
80  this.cursorDisplay = element.dataset.cursordisplay || element.dataset.cursorDisplay || "_";
81  element.innerHTML = this.cursorDisplay;
82  this.on = true;
83  element.style.transition = "all 0.1s";
84  this.interval = setInterval(() => this.updateBlinkState(), 400);
85}
86Cursor.prototype.updateBlinkState = function() {
87  if (this.on) {
88    this.element.style.opacity = "0";
89    this.on = false;
90  } else {
91    this.element.style.opacity = "1";
92    this.on = true;
93  }
94}
95
96function TyperSetup() {
97  var typers = {};
98  for (let e of document.getElementsByClassName("typer")) {
99    typers[e.id] = new Typer(e);
100  }
101  for (let e of document.getElementsByClassName("typer-stop")) {
102    let owner = typers[e.dataset.owner];
103    e.onclick = () => owner.stop();
104  }
105  for (let e of document.getElementsByClassName("typer-start")) {
106    let owner = typers[e.dataset.owner];
107    e.onclick = () => owner.start();
108  }
109  for (let e of document.getElementsByClassName("cursor")) {
110    let t = new Cursor(e);
111    t.owner = typers[e.dataset.owner];
112    t.owner.cursor = t;
113  }
114}
115
116TyperSetup();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.