-
-
Notifications
You must be signed in to change notification settings - Fork 989
Description
1. Describe the bug
When the user changes the page zoom level in Safari (⌘+ / ⌘− or track-pad pinch), any motion.path that animates the custom pathLength property immediately changes stroke length.
The drawn portion becomes progressively shorter the further you zoom out, resulting in visible clipping of the path animation.
Chrome, Edge and Firefox behave correctly.
2. Reproduction
git clone https://github.com/motiondivision/motion.git
cd motion
make bootstrap # installs and builds everything
yarn dev # alias for `yarn run dev`
Then open http://localhost:9991/?example=SVG-path in Safari, and follow the zoom steps in section 3.
3. Steps to reproduce
- Open http://localhost:9991/?example=SVG-path in Safari.
- Make sure page zoom is 100 %. Click the checkbox once to play the stroke animation – it completes as expected (full rounded rectangle + tick).
- Zoom out to 90 %, click again. The stroke covers only ~75 % of the intended length.
- Zoom out further to 80 % / 70 % and repeat – the stroke shrinks even more.
- Reset zoom; the stroke animates correctly again.
4. Expected behavior
pathLength
, stroke-dasharray
and stroke-dashoffset
should remain logically identical regardless of browser zoom level.
The full path should draw from 0 → 100 % every time, matching non-Safari browsers.
5. Actual behavior
Safari scales the numeric value returned by stroke-dasharray
/ stroke-dashoffset
when zooming, so the dash pattern is no longer normalized to 1.
Because Motion converts pathLength
→ "Xpx Ypx"
(absolute pixel units), the values shrink in CSS pixels during zoom, causing the visible shortening.
6. Screenshots
Zoom | Screenshot |
---|---|
100 % | ![]() |
90 % | ![]() |
80 % | ![]() |
70 % | ![]() |
8. Possible fix
Avoid emitting absolute px units for stroke-dasharray
and stroke-dashoffset
; instead write unit-less numbers.
Safari does not scale unit-less dash values on zoom, restoring parity with other browsers.
A small patch that resolves the issue locally:
// src/render/svg/utils/path.ts
- attrs[keys.offset] = px.transform!(-offset)
- attrs[keys.array] = `${px.transform!(length)} ${px.transform!(spacing)}`
+ attrs[keys.offset] = `${typeof offset === "string" ? -parseFloat(offset) : -offset}`
+ attrs[keys.array] = `${length} ${spacing}`
Note: This keeps the public API unchanged (
pathLength
,pathSpacing
, etc. still accept numbers) and only affects the internal serialization step for SVG paths.
9. Additional context
Similar Safari quirk: WebKit Bug 129248 (“zoom does not scale dash patterns”) – fixed by using unit-less dash values.
Related Framer Motion code: buildSVGPath
& svgEffect
(pathLength
→ stroke-dasharray/offset
).