From febe02334c96575207ec2768fb86040c256a0806 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Sun, 16 Aug 2026 08:33:54 +0800 Subject: feat(docs): enhance viewer UI with pagination and code highlighting Add line numbers, cursor glow effects, and syntax highlighting to the example viewer. Improve visual design with grid backgrounds, pill-shaped navigation buttons, and a "cargo add" quick link. --- docs/example-viewer.html | 263 ++++++++++++++++++++++++++++++++++++++++++++++- docs/examples.html | 140 ++++++++++++++++++++++++- 2 files changed, 399 insertions(+), 4 deletions(-) diff --git a/docs/example-viewer.html b/docs/example-viewer.html index dd51e95..0417c30 100644 --- a/docs/example-viewer.html +++ b/docs/example-viewer.html @@ -31,6 +31,117 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; overflow-x: hidden; + background-image: + linear-gradient( + to right, + rgba(212, 168, 75, 0.03) 1px, + transparent 1px + ), + linear-gradient( + to bottom, + rgba(212, 168, 75, 0.03) 1px, + transparent 1px + ), + linear-gradient( + to right, + rgba(212, 168, 75, 0.015) 1px, + transparent 1px + ), + linear-gradient( + to bottom, + rgba(212, 168, 75, 0.015) 1px, + transparent 1px + ); + background-size: + 40px 40px, + 40px 40px, + 20px 20px, + 20px 20px; + background-position: + calc(50% - 480px + 20px) 0, + calc(50% - 480px) 0, + calc(50% - 480px + 10px) 0, + calc(50% - 480px + 10px) 0; + } + + /* Dashed side lines along the viewer edges */ + html::before, + html::after { + content: ""; + position: fixed; + top: 0; + bottom: 0; + width: 1px; + background: repeating-linear-gradient( + to bottom, + rgba(212, 168, 75, 0.25) 0, + rgba(212, 168, 75, 0.25) 4px, + transparent 4px, + transparent 9px + ); + z-index: 49; + pointer-events: none; + } + + html::before { + left: max(0px, calc(50% - 480px)); + } + + html::after { + right: max(0px, calc(50% - 480px)); + } + + /* Cursor glow dot */ + .cursor-dot { + position: fixed; + pointer-events: none; + border-radius: 50%; + width: 400px; + height: 400px; + background: radial-gradient( + circle, + rgba(212, 168, 75, 0.06) 0%, + rgba(212, 168, 75, 0.02) 45%, + transparent 70% + ); + transform: translate(-50%, -50%); + z-index: 10000; + opacity: 0; + transition: + opacity 0.3s ease, + left 0.12s ease-out, + top 0.12s ease-out; + } + + /* Ink drop effect */ + .ink-drop { + position: fixed; + pointer-events: none; + border-radius: 50%; + background: radial-gradient( + circle, + rgba(212, 168, 75, 0.15) 0%, + rgba(196, 57, 49, 0.06) 50%, + transparent 100% + ); + width: 0; + height: 0; + transform: translate(-50%, -50%); + animation: inkSpread 0.9s ease-out forwards; + z-index: 9999; + } + + @keyframes inkSpread { + 0% { + width: 0; + height: 0; + opacity: 1; + } + 100% { + width: 500px; + height: 500px; + opacity: 0; + } } a { color: #d4a84b; @@ -83,6 +194,24 @@ color: #d4a84b; } + nav .nav-links .btn-nav { + display: inline-block; + padding: 0.35rem 1rem; + border: 1px solid #d4a84b; + border-radius: 20px; + color: #d4a84b; + font-weight: 600; + font-size: 0.85rem; + transition: + background 0.2s, + color 0.2s; + } + + nav .nav-links .btn-nav:hover { + background: #d4a84b; + color: #1a1410; + } + .viewer { margin-top: 4rem; padding: 1.5rem; @@ -184,6 +313,45 @@ font-variant-ligatures: inherit; } + /* Line numbers + hover highlight */ + .code-frame pre { + position: relative; + } + + .code-frame pre code { + counter-reset: line; + } + + .code-frame pre code .line { + display: block; + counter-increment: line; + } + + .code-frame pre code .line::before { + content: counter(line); + display: inline-block; + width: 2.5ch; + margin-right: 3ch; + text-align: right; + color: #6a5a4a; + user-select: none; + } + + .code-line-highlight { + position: absolute; + left: 0; + right: 0; + height: 28px; + background: rgba(255, 255, 255, 0.1); + border-left: 2px solid rgba(255, 255, 255, 0.45); + pointer-events: none; + opacity: 0; + transition: + opacity 0.15s ease, + top 0.08s ease; + z-index: 3; + } + .doc-box { background: #241c16; border: 1px solid #3a2e24; @@ -226,6 +394,13 @@ color: #e8ddd0; } + /* Markdown code blocks: drop the hljs theme's fg/bg, keep the pre styling */ + .doc-box pre code.hljs { + background: transparent !important; + color: #c0b0a0; + padding: 0 !important; + } + .loading { text-align: center; padding: 4rem 1rem; @@ -282,6 +457,12 @@ target="_blank" >GitHub + cargo add mingling @@ -325,6 +506,33 @@

+ + @@ -390,10 +598,18 @@ i++; } i++; // skip closing ``` - var codeText = escapeHtml(codeLines.join("\n")); + var rawCode = codeLines.join("\n"); + var highlighted; + if (lang && hljs.getLanguage(lang)) { + highlighted = hljs.highlight(rawCode, { + language: lang, + }).value; + } else { + highlighted = escapeHtml(rawCode); + } html += - "
" +
-                                codeText +
+                                "
" +
+                                highlighted +
                                 "
"; continue; } @@ -594,6 +810,18 @@ delete codeContent.dataset.highlighted; hljs.highlightElement(codeContent); + // Wrap each line with a .line span for numbering + codeContent.innerHTML = codeContent.innerHTML + .split("\n") + .map(function (line) { + return ( + '' + + line + + "" + ); + }) + .join(""); + tabsEl .querySelectorAll("button") .forEach(function (b) { @@ -627,6 +855,35 @@ tabsEl.appendChild(btn); }); + // Line highlight on hover + (function () { + var pre = codePre; + var code = codeContent; + var hl = document.createElement("div"); + hl.className = "code-line-highlight"; + pre.appendChild(hl); + + var lineHeight = parseFloat( + getComputedStyle(code).lineHeight, + ); + + pre.addEventListener("mousemove", function (e) { + var rect = pre.getBoundingClientRect(); + var y = e.clientY - rect.top; + var index = Math.floor(y / lineHeight); + var lineCount = code.innerText.split("\n").length; + if (index < 0) index = 0; + if (index >= lineCount) index = lineCount - 1; + hl.style.top = index * lineHeight + "px"; + hl.style.height = lineHeight + "px"; + hl.style.opacity = "1"; + }); + + pre.addEventListener("mouseleave", function () { + hl.style.opacity = "0"; + }); + })(); + // Load first file if (files.length > 0) loadFile(files[0]); } diff --git a/docs/examples.html b/docs/examples.html index a200000..9d2ae8c 100644 --- a/docs/examples.html +++ b/docs/examples.html @@ -33,6 +33,37 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; overflow-x: hidden; + background-image: + linear-gradient( + to right, + rgba(212, 168, 75, 0.03) 1px, + transparent 1px + ), + linear-gradient( + to bottom, + rgba(212, 168, 75, 0.03) 1px, + transparent 1px + ), + linear-gradient( + to right, + rgba(212, 168, 75, 0.015) 1px, + transparent 1px + ), + linear-gradient( + to bottom, + rgba(212, 168, 75, 0.015) 1px, + transparent 1px + ); + background-size: + 40px 40px, + 40px 40px, + 20px 20px, + 20px 20px; + background-position: + calc(50% - 550px + 20px) 0, + calc(50% - 550px) 0, + calc(50% - 550px + 10px) 0, + calc(50% - 550px + 10px) 0; } a { @@ -55,6 +86,86 @@ padding: 0 1.5rem; } + /* Dashed side lines along the container edges */ + html::before, + html::after { + content: ""; + position: fixed; + top: 0; + bottom: 0; + width: 1px; + background: repeating-linear-gradient( + to bottom, + rgba(212, 168, 75, 0.25) 0, + rgba(212, 168, 75, 0.25) 4px, + transparent 4px, + transparent 9px + ); + z-index: 49; + pointer-events: none; + } + + html::before { + left: max(0px, calc(50% - 550px)); + } + + html::after { + right: max(0px, calc(50% - 550px)); + } + + /* Cursor glow dot */ + .cursor-dot { + position: fixed; + pointer-events: none; + border-radius: 50%; + width: 400px; + height: 400px; + background: radial-gradient( + circle, + rgba(212, 168, 75, 0.06) 0%, + rgba(212, 168, 75, 0.02) 45%, + transparent 70% + ); + transform: translate(-50%, -50%); + z-index: 10000; + opacity: 0; + transition: + opacity 0.3s ease, + left 0.12s ease-out, + top 0.12s ease-out; + } + + /* Ink drop effect */ + .ink-drop { + position: fixed; + pointer-events: none; + border-radius: 50%; + background: radial-gradient( + circle, + rgba(212, 168, 75, 0.15) 0%, + rgba(196, 57, 49, 0.06) 50%, + transparent 100% + ); + width: 0; + height: 0; + transform: translate(-50%, -50%); + animation: inkSpread 0.9s ease-out forwards; + z-index: 9999; + } + + @keyframes inkSpread { + 0% { + width: 0; + height: 0; + opacity: 1; + } + 100% { + width: 500px; + height: 500px; + opacity: 0; + } + } + /* ── Nav ── */ nav { position: fixed; @@ -107,7 +218,7 @@ display: inline-block; padding: 0.35rem 1rem; border: 1px solid #d4a84b; - border-radius: 2px; + border-radius: 20px; color: #d4a84b; font-weight: 600; font-size: 0.85rem; @@ -486,5 +597,32 @@ .replace(/"/g, """); } + + -- cgit