2025-04-12 13:40:00
fuma-nama.vercel.app
#SVG
More about SVG.
Note that the example code is written in JSX (or React), not ordinary HTML.
#Animated Wires
Make the line, using line
or path
.
svg viewBox="0 0 50 50" className="bg-neutral-900 max-w-[100px] mx-auto">
g>
line x1="0" y1="0" x2="0" y2="50" stroke="white" strokeWidth="1" />
g>
svg>
Make it a mask.
svg viewBox="0 0 50 50" className="bg-neutral-900 max-w-[100px] mx-auto">
g>
rect x="0" y="0" width="50" height="10" fill="red" mask="url(#line)" />
mask id="line">
line id="" x1="0" y1="0" x2="0" y2="50" stroke="white" strokeWidth="1" />
mask>
g>
svg>
Add animation.
svg viewBox="0 0 50 50" className="bg-neutral-900 max-w-[100px] mx-auto">
g>
rect
x="0"
y="0"
width="50"
height="10"
fill="red"
mask="url(#animated_line)"
style={{
animation: "to-down linear infinite 2s",
}}
/>
mask id="animated_line">
line x1="0" y1="0" x2="0" y2="50" stroke="white" strokeWidth="1" />
mask>
g>
svg>
@keyframes to-down {
0% {
transform: translateY(-10px);
}
100% {
transform: translateY(50px);
}
}
Make styles.
svg viewBox="0 0 50 50" className="bg-neutral-900 max-w-[100px] mx-auto">
g>
line x1="0" y1="0" x2="0" y2="50" stroke="rgb(50,50,50)" strokeWidth="2" />
rect
x="0"
y="0"
width="100%"
height="20"
fill="url(#line_color)"
mask="url(#animated_line_fancy)"
style={{
"--height": "20px",
animation: "to-down-2 linear infinite 3s",
}}
/>
defs>
linearGradient id="line_color" x1="0" x2="0" y1="0" y2="1">
stop offset="0%" stopColor="rgba(255,0,255,0.1)" />
stop offset="100%" stopColor="rgb(255,100,255)" />
linearGradient>
defs>
mask id="animated_line_fancy">
line x1="0" y1="0" x2="0" y2="50" stroke="white" strokeWidth="2" />
mask>
g>
svg>
@keyframes to-down-2 {
0% {
transform: translateY(calc(var(--height) * -1));
}
100% {
transform: translateY(100%);
}
}
Most of these similar things are using the same technique.
Mask out an animated block, putting some animations and probably designed some parts in Figma or other SVG editors.
Unkey‘s landing page is a nice example.
#Clerk TOC
I made a clerk-like style Table Of Contents (TOC) on Fumadocs, you can try it out and play with the nice TOC.
To implement it, we have to render the TOC outline on server, without client-side JavaScript to make it compatible with SSR.
Since we’re on server, we don’t know the exact positions of elements.
My approach is to use absolute
positions, render the outline as different “components”, and snitch them together.
This isn’t hard, but we also want to render a highlighted part of outline where the items are active, or their corresponding heading is visible in the viewport.
Like:
I’ll call it the thumb. It has to be animated, so we can’t just change the color of these outline components.
We cannot animate the thumb with simple CSS solutions, lucky we have the exact rendered positions of TOC items, since the thumb is meant to be interactive, it is rendered on client!
Using the information from our browser, we can construct a “mask map” on client, look like this:
The method to construct this map is SVG – yes, our old friend.
svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 236">
path
d="M1 0 L1 20 L13 36 L13 56 L1 72 L1 92 L13 108 L13 128 L1 144 L1 164 L1 180 L1 200 L13 216 L13 236"
stroke="white"
strokeWidth="1"
fill="none"
/>
svg>
The d
property of SVG
isn’t a nonsense auto-generated string, it’s a list of commands.
See the Web Docs for more details, it’s quite a powerful tool.
With our new tool, we can tell SVG to render a line connecting each point of the outline.
This constructed a SVG that’s identical to our original TOC outline pre-rendered on server.
Similar to the technique we’ve learnt from Animated Wires, we can use the CSS mask-image
property to mask an animated div
block to render the thumb – a highlighted part of outline.
div
style={{
maskImage: `url("data:image/svg+xml,${
// URI encoded SVG image
encodeURIComponent(
``
)
})`,
}}
>
div
style={{
width: 1,
height: thumb.height,
transform: `translateY(${thumb.top}px)`,
transition: "all 500ms",
backgroundColor: "white",
}}
/>
div>
Check the source code to see my implementation in React.js.
Huge thanks to Clerk for inspiring me on this, I’ve never thought the TOC of a documentation site can be that interesting to play with.
Keep your files stored safely and securely with the SanDisk 2TB Extreme Portable SSD. With over 69,505 ratings and an impressive 4.6 out of 5 stars, this product has been purchased over 8K+ times in the past month. At only $129.99, this Amazon’s Choice product is a must-have for secure file storage.
Help keep private content private with the included password protection featuring 256-bit AES hardware encryption. Order now for just $129.99 on Amazon!
Help Power Techcratic’s Future – Scan To Support
If Techcratic’s content and insights have helped you, consider giving back by supporting the platform with crypto. Every contribution makes a difference, whether it’s for high-quality content, server maintenance, or future updates. Techcratic is constantly evolving, and your support helps drive that progress.
As a solo operator who wears all the hats, creating content, managing the tech, and running the site, your support allows me to stay focused on delivering valuable resources. Your support keeps everything running smoothly and enables me to continue creating the content you love. I’m deeply grateful for your support, it truly means the world to me! Thank you!
BITCOIN bc1qlszw7elx2qahjwvaryh0tkgg8y68enw30gpvge Scan the QR code with your crypto wallet app |
DOGECOIN D64GwvvYQxFXYyan3oQCrmWfidf6T3JpBA Scan the QR code with your crypto wallet app |
ETHEREUM 0xe9BC980DF3d985730dA827996B43E4A62CCBAA7a Scan the QR code with your crypto wallet app |
Please read the Privacy and Security Disclaimer on how Techcratic handles your support.
Disclaimer: As an Amazon Associate, Techcratic may earn from qualifying purchases.