-
Notifications
You must be signed in to change notification settings - Fork 0
/
scripts.js
207 lines (188 loc) · 7.37 KB
/
scripts.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
// an interactive chat-like user interface with a dynamic typewriter effect for each message.
const options = {
bottom: '64px', // default: '32px'
right: '32px', // default: '32px'
left: 'unset', // default: 'unset'
time: '0.5s', // default: '0.3s'
mixColor: '#fff', // default: '#fff'
backgroundColor: '#fff', // default: '#fff'
buttonColorDark: '#100f2c', // default: '#100f2c'
buttonColorLight: '#fff', // default: '#fff'
saveInCookies: false, // default: true,
label: '🌓', // default: ''
autoMatchOsTheme: true // default: true
}
// darkmode widget configuration
const darkmode = new Darkmode(options);
darkmode.showWidget();
window.onload = function() {
// declaring variables
var messagesEl = document.querySelector('.textsInBubbles');
var typingSpeed = 20;
var loadingText = '<b>•</b><b>•</b><b>•</b>';
var messageIndex = 0;
// returns a message based on time of the day.
var getCurrentTime = function() {
var date = new Date();
var hours = date.getHours();
var minutes = date.getMinutes();
var current = hours + (minutes * .01);
if (current >= 5 && current < 16) return 'Have a nice day 🌆.';
if (current >= 16 && current < 22) return 'Have a nice evening 🌃.';
if (current >= 22 || current < 5) return 'Have a good night 🌃.';
}
//array containing a series of messages to be displayed in the chat bubbles.
var textsInBubbles = [
'Hey there 👋.',
'I\'m Toheeb 🧑🏾.',
'An ambitious full-stack software engineer with a passion for creating innovative and scalable solutions 👨🏾💻.',
'I have worked on projects in various domains such as International Trade, Publishing, Financial and Insurance sectors, delivering high-quality software that meets the needs of the clients 🧮.',
'I am always eager to learn new skills and take on new challenges in the software development field 🧠.',
'You can reach me by <a style="text-decoration:none;" href="mailto:[email protected]">📧</a> & <a style="text-decoration:none;"href="tel:+447874315715">☎️</a>.',
'Here\'s a copy of my <a target="_blank" style="text-decoration:none;" href="Toheeb Badru CV Copy.pdf">CV</a> 📄.',
'Connect with me on <a target="_blank" style="text-decoration:none;" href="https://www.linkedin.com/in/toheeb-badru/">LinkedIn</a> & <a target="_blank"style="text-decoration:none;" href="https://github.com/TBadru">Github</a> .',
// 'Want to play some 1v1 <a target="_blank" href="chess.html">chess</a> ?', //
getCurrentTime(),
'🚀 D.'
]
// Retrieves the font size of the page.
var getFontSize = function() {
return parseInt(getComputedStyle(document.body).getPropertyValue('font-size'));
}
// converts pixel to rem relative to the font size
var pxToRem = function(px) {
return px / getFontSize() + 'rem';
}
// creates the HTML elements for a chat bubble containing a message and assigns classes, content, and styles to different parts of the bubble.
var createBubbleElements = function(message, position) {
var bubbleEl = document.createElement('div');
var messageEl = document.createElement('span');
var loadingEl = document.createElement('span');
bubbleEl.classList.add('bubble');
bubbleEl.classList.add('is-loading');
bubbleEl.classList.add('cornered');
bubbleEl.classList.add(position === 'right' ? 'right' : 'left');
messageEl.classList.add('message');
loadingEl.classList.add('loading');
messageEl.innerHTML = message;
loadingEl.innerHTML = loadingText;
bubbleEl.appendChild(loadingEl);
bubbleEl.appendChild(messageEl);
bubbleEl.style.opacity = 0;
return {
bubble: bubbleEl,
message: messageEl,
loading: loadingEl
}
}
// Calculates dimensions for the bubble and its contents (message and loading animation)
var getDimentions = function(elements) {
return dimensions = {
loading: {
w: '4rem',
h: '2.25rem'
},
bubble: {
w: pxToRem(elements.bubble.offsetWidth + 4),
h: pxToRem(elements.bubble.offsetHeight)
},
message: {
w: pxToRem(elements.message.offsetWidth + 4),
h: pxToRem(elements.message.offsetHeight)
}
}
}
//handles the animation and display of a chat bubble with a message.
//It appends the bubble to the container and adjusts its position if necessary.
//It utilizes the anime library from anime.js for animations, such as growing the bubble, showing the message, and simulating a typing effect.
var sendMessage = function(message, position) {
var loadingDuration = (message.replace(/<(?:.|\n)*?>/gm, '').length * typingSpeed) + 500;
var elements = createBubbleElements(message, position);
messagesEl.appendChild(elements.bubble);
messagesEl.appendChild(document.createElement('br'));
var dimensions = getDimentions(elements);
elements.bubble.style.width = '0rem';
elements.bubble.style.height = dimensions.loading.h;
elements.message.style.width = dimensions.message.w;
elements.message.style.height = dimensions.message.h;
elements.bubble.style.opacity = 1;
var bubbleOffset = elements.bubble.offsetTop + elements.bubble.offsetHeight;
if (bubbleOffset > messagesEl.offsetHeight) {
var scrollMessages = anime({
targets: messagesEl,
scrollTop: bubbleOffset,
duration: 750
});
}
var bubbleSize = anime({
targets: elements.bubble,
width: ['0rem', dimensions.loading.w],
marginTop: ['2.5rem', 0],
marginLeft: ['-2.5rem', 0],
duration: 800,
easing: 'easeOutElastic'
});
var loadingLoop = anime({
targets: elements.bubble,
scale: [1.05, .95],
duration: 1100,
loop: true,
direction: 'alternate',
easing: 'easeInOutQuad'
});
var dotsStart = anime({
targets: elements.loading,
translateX: ['-2rem', '0rem'],
scale: [.5, 1],
duration: 400,
delay: 25,
easing: 'easeOutElastic',
});
var dotsPulse = anime({
targets: elements.bubble.querySelectorAll('b'),
scale: [1, 1.25],
opacity: [.5, 1],
duration: 300,
loop: true,
direction: 'alternate',
delay: function(i) {return (i * 100) + 50}
});
setTimeout(function() {
loadingLoop.pause();
dotsPulse.restart({
opacity: 0,
scale: 0,
loop: false,
direction: 'forwards',
update: function(a) {
if (a.progress >= 65 && elements.bubble.classList.contains('is-loading')) {
elements.bubble.classList.remove('is-loading');
anime({
targets: elements.message,
opacity: [0, 1],
duration: 300,
});
}
}
});
bubbleSize.restart({
scale: 1,
width: [dimensions.loading.w, dimensions.bubble.w ],
height: [dimensions.loading.h, dimensions.bubble.h ],
marginTop: 0,
marginLeft: 0,
begin: function() {
if (messageIndex < textsInBubbles.length) elements.bubble.classList.remove('cornered');
}
})
}, loadingDuration - 50);
}
var sendMessages = function() {
var message = textsInBubbles[messageIndex];
if (!message) return;
sendMessage(message);
++messageIndex;
setTimeout(sendMessages, (message.replace(/<(?:.|\n)*?>/gm, '').length * typingSpeed) + anime.random(900, 1200));
}
sendMessages();
}