diff --git a/data/panaetius-theme/assets.json b/data/panaetius-theme/assets.json index 798cc82..0b66a91 100644 --- a/data/panaetius-theme/assets.json +++ b/data/panaetius-theme/assets.json @@ -9,8 +9,8 @@ "js": "2.lazyload.1168fc21175de558d316.min.js" }, "main": { - "css": "main.0cbee9de77c807b0b044.min.css", - "js": "main.48637aff6f96e597ae05.min.js" + "css": "main.26e4723e96e8bcd78b5f.min.css", + "js": "main.fc08d5d267c5846c8341.min.js" }, "vendors~app": { "js": "4.vendors~app.7827f3b332495242afbd.min.js" @@ -47,6 +47,7 @@ "a88fa636656948bd2edb86bce59f0eec.otf", "cf6ea537acbd7e39208334261f95783e.otf", "da9fb05ff6c5f02b52f5b416cfe61d39.otf" - ] + ], + "js": "6.6.91402cdcff834b1793e6.min.js" } } \ No newline at end of file diff --git a/layouts/post/single.html b/layouts/post/single.html index 730e5b4..8039221 100644 --- a/layouts/post/single.html +++ b/layouts/post/single.html @@ -3,8 +3,8 @@
{{ $page := . }} -
-
+
+
{{- with .Resources.Match "images/banner.svg" -}} {{ range . }}
@@ -17,11 +17,11 @@
-

{{ $page.Title }}

+

{{ $page.Title }}

-
-
-
-

On this page

-
+
+
+

On this page

+
{{ .TableOfContents }}
-
+
{{ partial "related.html" $page }}
- {{/*
- -
- -
-
*/}}
diff --git a/src/js/toc.js b/src/js/toc.js new file mode 100644 index 0000000..09b507c --- /dev/null +++ b/src/js/toc.js @@ -0,0 +1,122 @@ +export function animatedToc() { + var toc = document.querySelector(".toc"); + var tocPath = document.querySelector(".toc-marker path"); + var tocItems; + + // Factor of screen size that the element must cross + // before it's considered visible + var TOP_MARGIN = 0.1, + BOTTOM_MARGIN = 0.2; + + var pathLength; + + var lastPathStart, lastPathEnd; + + window.addEventListener("resize", drawPath, false); + window.addEventListener("scroll", sync, false); + + drawPath(); + + function drawPath() { + tocItems = [].slice.call(toc.querySelectorAll("li")); + + // Cache element references and measurements + tocItems = tocItems.map(function (item) { + var anchor = item.querySelector("a"); + var target = document.getElementById( + anchor.getAttribute("href").slice(1) + ); + + return { + listItem: item, + anchor: anchor, + target: target, + }; + }); + + // Remove missing targets + tocItems = tocItems.filter(function (item) { + return !!item.target; + }); + + var path = []; + var pathIndent; + + tocItems.forEach(function (item, i) { + var x = item.anchor.offsetLeft - 5, + y = item.anchor.offsetTop, + height = item.anchor.offsetHeight; + + if (i === 0) { + path.push("M", x, y, "L", x, y + height); + item.pathStart = 0; + } else { + // Draw an additional line when there's a change in + // indent levels + if (pathIndent !== x) path.push("L", pathIndent, y); + + path.push("L", x, y); + + // Set the current path so that we can measure it + tocPath.setAttribute("d", path.join(" ")); + item.pathStart = tocPath.getTotalLength() || 0; + + path.push("L", x, y + height); + } + + pathIndent = x; + + tocPath.setAttribute("d", path.join(" ")); + item.pathEnd = tocPath.getTotalLength(); + }); + + pathLength = tocPath.getTotalLength(); + + sync(); + } + + function sync() { + var windowHeight = window.innerHeight; + + var pathStart = pathLength, + pathEnd = 0; + + var visibleItems = 0; + + tocItems.forEach(function (item) { + var targetBounds = item.target.getBoundingClientRect(); + + if ( + targetBounds.bottom > windowHeight * TOP_MARGIN && + targetBounds.top < windowHeight * (1 - BOTTOM_MARGIN) + ) { + pathStart = Math.min(item.pathStart, pathStart); + pathEnd = Math.max(item.pathEnd, pathEnd); + + visibleItems += 1; + + item.listItem.classList.add("visible"); + } else { + item.listItem.classList.remove("visible"); + } + }); + + // Specify the visible path or hide the path altogether + // if there are no visible items + if (visibleItems > 0 && pathStart < pathEnd) { + if (pathStart !== lastPathStart || pathEnd !== lastPathEnd) { + tocPath.setAttribute("stroke-dashoffset", "1"); + tocPath.setAttribute( + "stroke-dasharray", + "1, " + pathStart + ", " + (pathEnd - pathStart) + ", " + pathLength + ); + tocPath.setAttribute("opacity", 1); + } + } else { + tocPath.setAttribute("opacity", 0); + } + + lastPathStart = pathStart; + lastPathEnd = pathEnd; + } +} diff --git a/src/main.js b/src/main.js index dedd193..633a72c 100644 --- a/src/main.js +++ b/src/main.js @@ -5,10 +5,12 @@ window.addEventListener("DOMContentLoaded", async (event) => { const { default: App } = await import( /* webpackChunkName: "app" */ "./js/App" ); + const animatedToc = await import("./js/toc"); App.bootstrapify(); App.lazyload(); App.loadFontAwesome(); // App.navbarFade(); App.aos(); App.scrollBar(); + animatedToc.animatedToc(); }); diff --git a/src/scss/code-block.scss b/src/scss/code-block.scss new file mode 100644 index 0000000..1f5d32c --- /dev/null +++ b/src/scss/code-block.scss @@ -0,0 +1,3 @@ +div.highlight { + padding-bottom: 20px; +} diff --git a/src/scss/styles.scss b/src/scss/styles.scss index c19bd93..577f42b 100644 --- a/src/scss/styles.scss +++ b/src/scss/styles.scss @@ -5,8 +5,10 @@ @import "sticky-footer"; @import "search"; @import "search-bar"; -@import "toc"; @import "scroll-bar"; @import "admonition-icons"; @import "cards"; @import "fonts"; +@import "toc-marker"; +@import "code-block"; +@import "toc"; diff --git a/src/scss/toc-marker.scss b/src/scss/toc-marker.scss new file mode 100644 index 0000000..8e8fa59 --- /dev/null +++ b/src/scss/toc-marker.scss @@ -0,0 +1,41 @@ +@mixin toc-selected { + color: $text-gray; + transform: translate(5px); +} + +.toc { + line-height: 2; + + ul { + list-style: none; + padding-left: 0px; + } + + ul ul { + padding-left: 1em; + } + + li a { + display: inline-block; + color: $text-muted; + text-decoration: none; + transition: all 0.3s cubic-bezier(0.230, 1.000, 0.320, 1.000); + font-size: 0.9rem; + + &:hover { + @include toc-selected; + } + } + + li.visible>a { + @include toc-selected; + } +} + +// Adds offset to the headers in the post content to ignore the navbar height (avoids underscroll). +:target[id]:before { + content: ''; + display: block; + height: 58px; + margin: -30px 0 0; +} diff --git a/src/scss/toc.scss b/src/scss/toc.scss index 8ff5ed5..aff1b59 100644 --- a/src/scss/toc.scss +++ b/src/scss/toc.scss @@ -1,30 +1,10 @@ -div.toc-sidebar { - position: fixed; - right: 0; - // background-color: rgb(245,245,245); - background: repeating-linear-gradient(135deg, rgba(128, 50, 50, 0.025), rgba(160, 60, 60, 0.025) 5px, rgba(0,0,0,0) 5px, rgba(0,0,0,0) 10px); - height: 100%; - margin-top: -500%; - padding-top: 500%; - padding-bottom: 500%; - margin-right: 5%; - font-size: 0.9em; +div { + &.toc-container { + top: 56px; + background-color: white; + } - & li { - list-style: none; - padding-bottom: 10px; + &.toc-contents { + padding-left: 10px; } } - -#TableOfContents > ul { - margin-left: -40px; - - & > li ul { - margin-left: -15px; - } -} - -div.toc-contents a { - // color: $text-muted - color: $gray-700 -}