BlogService now fetches from Media.JoshHeaps.Net API via HttpClient with in-memory caching (5-min TTL) and stale cache fallback. Removed Markdig/YamlDotNet dependencies. All page models now async. Co-Authored-By: Claude Opus 4.6 <[email protected]>
78 lines
2.0 KiB
JavaScript
78 lines
2.0 KiB
JavaScript
function typeText(selector, content) {
|
|
const element = document.querySelector(selector);
|
|
|
|
if (!element) {
|
|
console.log("Element not found.");
|
|
return;
|
|
}
|
|
|
|
simulateTyping(element, content);
|
|
}
|
|
|
|
let intervalId;
|
|
let index = 0;
|
|
const punctuation = ['.', '!', '?'];
|
|
const punctuationDict = {
|
|
'.': 150,
|
|
'!': 200,
|
|
'?': 200,
|
|
',': 100,
|
|
'`': 25,
|
|
};
|
|
|
|
let currentText = "";
|
|
|
|
function changeIntervalTime(element, text) {
|
|
clearInterval(intervalId);
|
|
simulateTyping(element, text, punctuationDict[text.charAt(index)] ?? 50);
|
|
}
|
|
|
|
function simulateTyping(element, text, speed = 50) {
|
|
intervalId = setInterval(() => {
|
|
if (index < text.length) {
|
|
if (text.charAt(index) === '`')
|
|
currentText = currentText.slice(0, -1);
|
|
else
|
|
currentText += text.charAt(index);
|
|
changeIntervalTime(element, text);
|
|
index++;
|
|
element.textContent = currentText;
|
|
} else {
|
|
clearInterval(intervalId);
|
|
}
|
|
}, speed);
|
|
}
|
|
|
|
function showClickedContents(option) {
|
|
if (option === 'projects') {
|
|
document.querySelector("#ProjectsBox").scrollIntoView({
|
|
behavior: "smooth",
|
|
block: "start",
|
|
inline: "nearest"
|
|
});
|
|
}
|
|
else if (option === 'contact') {
|
|
navigator.clipboard.writeText('435-890-2957').then(() => {
|
|
console.log('copied');
|
|
});
|
|
document.querySelector("#Contacts").scrollIntoView({
|
|
behavior: "smooth",
|
|
block: "start",
|
|
inline: "nearest"
|
|
});
|
|
}
|
|
else if (option === 'demos') {
|
|
document.querySelector("#DemosBox").scrollIntoView({
|
|
behavior: "smooth",
|
|
block: "start",
|
|
inline: "nearest"
|
|
});
|
|
}
|
|
else if (option === 'blog') {
|
|
document.querySelector("#BlogBox").scrollIntoView({
|
|
behavior: "smooth",
|
|
block: "start",
|
|
inline: "nearest"
|
|
});
|
|
}
|
|
} |