forked from cotes2020/jekyll-theme-chirpy
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
87 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,85 +1,95 @@ | ||
document.addEventListener('DOMContentLoaded', () => { | ||
// Back-to-Top Button Logic | ||
const btn = document.getElementById('back-to-top'); | ||
const tocWrapper = document.getElementById('toc-wrapper'); // Add reference to TOC wrapper | ||
if (!btn || !tocWrapper) return; | ||
|
||
// Create SVG container and progress circle | ||
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); | ||
const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle"); | ||
|
||
svg.setAttribute("id", "progress-circle"); | ||
svg.setAttribute("width", "44"); | ||
svg.setAttribute("height", "44"); | ||
|
||
circle.setAttribute("cx", "22"); | ||
circle.setAttribute("cy", "22"); | ||
circle.setAttribute("r", "20"); | ||
circle.setAttribute("stroke-width", "1"); | ||
circle.setAttribute("stroke-dasharray", `${2 * Math.PI * 20}`); | ||
circle.setAttribute("stroke-dashoffset", `${2 * Math.PI * 20}`); | ||
circle.setAttribute("fill", "none"); | ||
circle.style.stroke = "var(--btn-backtotop-color)"; | ||
|
||
svg.appendChild(circle); | ||
btn.appendChild(svg); | ||
|
||
// Create scroll percentage text | ||
const percentageText = document.createElement("div"); | ||
percentageText.id = "scroll-percentage"; | ||
percentageText.textContent = "0%"; | ||
btn.appendChild(percentageText); | ||
|
||
// Variables for scroll behavior | ||
let scrollTimeout; | ||
let tocTimeout; | ||
const circumference = 2 * Math.PI * 20; | ||
|
||
// Show TOC for 1-2 seconds when the page loads | ||
tocWrapper.classList.add('visible'); | ||
setTimeout(() => { | ||
tocWrapper.classList.remove('visible'); // Hide the TOC after 1.5s | ||
}, 1500); // 1.5 seconds after the page loads | ||
|
||
// Update progress on scroll | ||
const updateScrollProgress = () => { | ||
const scrollTop = window.scrollY; | ||
const docHeight = document.documentElement.scrollHeight - window.innerHeight; | ||
|
||
if (docHeight > 0) { | ||
const scrollFraction = scrollTop / docHeight; | ||
const drawLength = circumference * scrollFraction; | ||
const scrollPercentage = Math.round(scrollFraction * 100); | ||
|
||
// Update the circle progress | ||
circle.style.strokeDashoffset = circumference - drawLength; | ||
|
||
// Show the percentage text with background | ||
percentageText.textContent = `${scrollPercentage}`; | ||
|
||
// Add the visible class to show the text and background | ||
percentageText.classList.add('visible'); | ||
|
||
// Clear timeout to hide the text after a delay | ||
clearTimeout(scrollTimeout); | ||
|
||
// Hide the percentage text after a delay (500ms) | ||
scrollTimeout = setTimeout(() => { | ||
percentageText.classList.remove('visible'); | ||
}, 500); | ||
|
||
// Always show the TOC when scrolling | ||
if (btn) { | ||
// Create SVG container and progress circle | ||
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); | ||
const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle"); | ||
|
||
svg.setAttribute("id", "progress-circle"); | ||
svg.setAttribute("width", "44"); | ||
svg.setAttribute("height", "44"); | ||
|
||
circle.setAttribute("cx", "22"); | ||
circle.setAttribute("cy", "22"); | ||
circle.setAttribute("r", "20"); | ||
circle.setAttribute("stroke-width", "1"); | ||
circle.setAttribute("stroke-dasharray", `${2 * Math.PI * 20}`); | ||
circle.setAttribute("stroke-dashoffset", `${2 * Math.PI * 20}`); | ||
circle.setAttribute("fill", "none"); | ||
circle.style.stroke = "var(--btn-backtotop-color)"; | ||
|
||
svg.appendChild(circle); | ||
btn.appendChild(svg); | ||
|
||
// Create scroll percentage text | ||
const percentageText = document.createElement("div"); | ||
percentageText.id = "scroll-percentage"; | ||
percentageText.textContent = "0%"; | ||
btn.appendChild(percentageText); | ||
|
||
const circumference = 2 * Math.PI * 20; | ||
let scrollTimeout; | ||
|
||
const updateScrollProgress = () => { | ||
const scrollTop = window.scrollY; | ||
const docHeight = document.documentElement.scrollHeight - window.innerHeight; | ||
|
||
if (docHeight > 0) { | ||
const scrollFraction = scrollTop / docHeight; | ||
const drawLength = circumference * scrollFraction; | ||
const scrollPercentage = Math.round(scrollFraction * 100); | ||
|
||
// Update the circle progress | ||
circle.style.strokeDashoffset = circumference - drawLength; | ||
|
||
// Show the percentage text with background | ||
percentageText.textContent = `${scrollPercentage}`; | ||
percentageText.classList.add('visible'); | ||
|
||
// Hide the percentage text after a delay | ||
clearTimeout(scrollTimeout); | ||
scrollTimeout = setTimeout(() => { | ||
percentageText.classList.remove('visible'); | ||
}, 500); | ||
} | ||
}; | ||
|
||
// Use requestAnimationFrame to smooth scroll updates | ||
window.addEventListener('scroll', () => { | ||
window.requestAnimationFrame(updateScrollProgress); | ||
}); | ||
|
||
// Scroll to top on click | ||
btn.addEventListener('click', () => { | ||
window.scrollTo({ top: 0, behavior: 'smooth' }); | ||
}); | ||
} | ||
|
||
// TOC Wrapper Logic | ||
const tocWrapper = document.getElementById('toc-wrapper'); | ||
if (tocWrapper) { | ||
// Show TOC for a few seconds when the page loads | ||
tocWrapper.classList.add('visible'); | ||
setTimeout(() => { | ||
tocWrapper.classList.remove('visible'); // Hide the TOC after 1.5s | ||
}, 1500); // 1.5 seconds after the page loads | ||
|
||
let tocTimeout; | ||
|
||
// Show TOC on scroll | ||
const showTOCOnScroll = () => { | ||
tocWrapper.classList.add('visible'); // Add visible class to the TOC | ||
|
||
// Reset the timeout to hide TOC after some idle time (e.g., 1.2 seconds) | ||
// Hide TOC after some idle time | ||
clearTimeout(tocTimeout); | ||
tocTimeout = setTimeout(() => { | ||
tocWrapper.classList.remove('visible'); // Hide the TOC after 1.2 seconds of inactivity | ||
}, 500); // TOC hides after 1 seconds of inactivity | ||
} | ||
}; | ||
|
||
// Use requestAnimationFrame to smooth scroll updates | ||
window.addEventListener('scroll', () => { | ||
window.requestAnimationFrame(updateScrollProgress); | ||
}); | ||
}, 1200); // 1.2 seconds of inactivity | ||
}; | ||
|
||
window.addEventListener('scroll', () => { | ||
showTOCOnScroll(); | ||
}); | ||
} | ||
}); |