Meanderer
A JavaScript micro-library for responsive CSS motion paths! :sparkles:
Install / Use
/learn @jh3y/MeandererREADME
Meanderer
A micro-library for scaling CSS motion path strings ✨

Installation
CDN
https://unpkg.com/meanderer@0.0.1/dist/meanderer{.min}.js
NPM
npm i meanderer
Usage
// Our path string
const PATH = "M32.074 13.446s-2.706-2.965-4.158-4.349c-2.003-1.908-3.941-3.942-6.268-5.437C19.33..."
// The bounds of our path
const WIDTH = 65
const HEIGHT = 30
// Generate a responsive path
const responsivePath = new Meanderer({
path: PATH,
width: WIDTH,
height: HEIGHT
})
// Generate a new scaled path when required. Here we are using ResizeObserver
// with a container that uses viewport units
const setPath = () => {
const scaledPath = responsivePath.generatePath(
CONTAINER.offsetWidth,
CONTAINER.offsetHeight
)
// Here, we apply the path to an element through a CSS variable.
// And then an element picks up on that. We could apply the motion path straight to the element though.
CONTAINER.style.setProperty("--path", `"${scaledPath}"`)
}
// Set up our Resize Observer that will get the ball rolling
const SizeObserver = new ResizeObserver(setPath)
// Observe! Done!
SizeObserver.observe(CONTAINER)
First things first. We need a path.
Unless you're constructing one by hand, it's likely you'll be extracting one from an SVG.
Before extracting one from an SVG, it's wise to run that SVG through an optimizer like SVGOMG(Use the precision slider for extra gains! 💪). This will normalize coordinates, etc. removing any translations which could skew the path translation.
Now you've got a path string, it's time to use it!
- Create variables for the
path, and a desiredwidthandheightfor thepathbounds. Thewidthandheightare in most cases going to be thex2andy2of your SVG'sviewBoxattribute.
const PATH = "M32.074 13.446s-2.706-2.965-4.158-4.349c-2.003-1.908-3.941-3.942-6.268-5.437C19.33..."
// The bounds of our path
const WIDTH = 65
const HEIGHT = 30
- Create a new responsive path by passing those variables inside an
Objectto a newMeandererinstance.
// Generate a responsive path
const responsivePath = new Meanderer({
path: PATH,
width: WIDTH,
height: HEIGHT
})
- Use your instance to generate scaled path strings for a given
widthandheight👍
responsivePath.generatePath(200, 400)
- Pass that to your element either directly or via CSS variable, etc. 🎉
Caveats
Meanderer will do its best to maintain aspect ratio of your paths. If the container dimensions passed in to generatePath don't match the aspect ratio of the path, Meanderer will handle this. It will do this by padding out the container and centering the path for you.
A way to enforce the correct aspect ratio for your container is to use your defined width and height in your CSS. Consider a container with a width of 25vmin. You've specified a width and height of 64 and 35.
.container {
height: calc((64 / 35) * 25vmin);
width: 25vmin;
}
stroke-path isn't currently taken into consideration. There have been experiments trying it out though. They didn't seem to affect the overall experience/result though.
Contributing
I'd love some contributions if you think this micro-library could be useful for you! Leave an issue or open a PR 👍
MIT Licensed | Made with 💻 by @jh3y 2020
Related Skills
node-connect
347.9kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
108.7kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
347.9kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
347.9kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
