I am working with a svg element as following where I am trying to apply motion-path to a svg
circle.
let u = 0;
let curve = document.querySelector('#curve')
let totalLength = curve.getTotalLength();
let dot = document.querySelector('#dot');
let p = curve.getPointAtLength(u * totalLength);
dot.setAttribute("transform", `translate(${p.x}, ${p.y})`);
let d = curve.getAttribute('d');
dot.style.setProperty('--mp', d)
#dot {
offset-path: path('M 29.928125,119.32884 C 59.868756,78.85387 99.789596,30.283895 138.66049,30.104515 c 80.46172,-0.37133 90.87185,137.794285 140.7729,129.699295 40.35037,-6.54568 49.90105,-80.94994 86.53937,-78.86548 33.24073,1.89117 22.2547,70.77048 73.14399,70.77048 39.92084,0 58.65264,-56.66496 99.80211,-56.66496 49.90105,0 69.86147,80.94995 99.8021,48.56997');
animation: move 3000ms infinite alternate ease-in-out;
}
@keyframes move {
100% {
offset-distance: 100%;
}
}
<div id="container" ></div>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<g>
<circle id="dot" r="10" cy="0.5" cx="0.5" style="fill: #dd1819; "></circle>
</g>
<path id="curve" d="M 29.928125,119.32884 C 59.868756,78.85387 99.789596,30.283895 138.66049,30.104515 c 80.46172,-0.37133 90.87185,137.794285 140.7729,129.699295 40.35037,-6.54568 49.90105,-80.94994 86.53937,-78.86548 33.24073,1.89117 22.2547,70.77048 73.14399,70.77048 39.92084,0 58.65264,-56.66496 99.80211,-56.66496 49.90105,0 69.86147,80.94995 99.8021,48.56997" style="fill: none; stroke:black; stroke-width: 1; /*transform:translate(100px, 100px);*/" />
</svg>
I can't make the circle follow the path with the code above.
Also, I intend to use CSS variable
instead of manually copying the path. So if I do the following it does not even work
let u = 0;
let curve = document.querySelector('#curve')
let totalLength = curve.getTotalLength();
let dot = document.querySelector('#dot');
let p = curve.getPointAtLength(u * totalLength);
dot.setAttribute("transform", `translate(${p.x}, ${p.y})`);
let d = curve.getAttribute('d');
dot.style.setProperty('--mp', d)
#dot {
offset-path: path(var(--mp);
animation: move 3000ms infinite alternate ease-in-out;
}
@keyframes move {
100% {
offset-distance: 100%;
}
}
<div id="container" ></div>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<g>
<circle id="dot" r="10" cy="0.5" cx="0.5" style="fill: #dd1819; "></circle>
</g>
<path id="curve" d="M 29.928125,119.32884 C 59.868756,78.85387 99.789596,30.283895 138.66049,30.104515 c 80.46172,-0.37133 90.87185,137.794285 140.7729,129.699295 40.35037,-6.54568 49.90105,-80.94994 86.53937,-78.86548 33.24073,1.89117 22.2547,70.77048 73.14399,70.77048 39.92084,0 58.65264,-56.66496 99.80211,-56.66496 49.90105,0 69.86147,80.94995 99.8021,48.56997" style="fill: none; stroke:black; stroke-width: 1; /*transform:translate(100px, 100px);*/" />
</svg>
To summarize, what is the correct way to apply CSS motion path on a svg
element by using CSS variable.
Update With the suggestion from G-Cyrillus and biberman, the following works
let u = 0;
let curve = document.querySelector('#curve')
let totalLength = curve.getTotalLength();
let dot = document.querySelector('#dot');
let p = curve.getPointAtLength(u * totalLength);
// dot.setAttribute("transform", `translate(${p.x}, ${p.y})`);
let d = curve.getAttribute('d');
dot.style.setProperty('--mp', '"' d '"')
#dot {
offset-path: path(var(--mp));
animation: move 3000ms infinite alternate ease-in-out;
}
@keyframes move {
100% {
offset-distance: 100%;
}
}
<div id="container" ></div>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<g>
<circle id="dot" r="10" cy="0.5" cx="0.5" style="fill: #dd1819; "></circle>
</g>
<path
id="curve"
d="M 29.928125,119.32884 C 59.868756,78.85387 99.789596,30.283895 138.66049,30.104515 c 80.46172,-0.37133 90.87185,137.794285 140.7729,129.699295 40.35037,-6.54568 49.90105,-80.94994 86.53937,-78.86548 33.24073,1.89117 22.2547,70.77048 73.14399,70.77048 39.92084,0 58.65264,-56.66496 99.80211,-56.66496 49.90105,0 69.86147,80.94995 99.8021,48.56997"
style="fill: none; stroke:black; stroke-width: 1; /*transform:translate(100px, 100px);*/" />
</svg>
CodePudding user response:
Your code works (not only in FF;), if you omit the JavaScript, because the animation is done with CSS.
Working example: (i removed the svg container, because it isn't used)
#dot {
offset-path: path('M 29.928125,119.32884 C 59.868756,78.85387 99.789596,30.283895 138.66049,30.104515 c 80.46172,-0.37133 90.87185,137.794285 140.7729,129.699295 40.35037,-6.54568 49.90105,-80.94994 86.53937,-78.86548 33.24073,1.89117 22.2547,70.77048 73.14399,70.77048 39.92084,0 58.65264,-56.66496 99.80211,-56.66496 49.90105,0 69.86147,80.94995 99.8021,48.56997');
animation: move 3000ms infinite alternate ease-in-out;
}
@keyframes move {
100% {
offset-distance: 100%;
}
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<g>
<circle id="dot" r="10" cy="0.5" cx="0.5" style="fill: #dd1819; "></circle>
</g>
<path id="curve" d="M 29.928125,119.32884 C 59.868756,78.85387 99.789596,30.283895 138.66049,30.104515 c 80.46172,-0.37133 90.87185,137.794285 140.7729,129.699295 40.35037,-6.54568 49.90105,-80.94994 86.53937,-78.86548 33.24073,1.89117 22.2547,70.77048 73.14399,70.77048 39.92084,0 58.65264,-56.66496 99.80211,-56.66496 49.90105,0 69.86147,80.94995 99.8021,48.56997" style="fill: none; stroke:black; stroke-width: 1;" />
</svg>
CodePudding user response:
You are missing the " from your d string , and you have a typo with path(var(--mp)) that you did not close properly ;)
let u = 0;
let curve = document.querySelector('#curve')
let totalLength = curve.getTotalLength();
let dot = document.querySelector('#dot');
let p = curve.getPointAtLength(u * totalLength);
//dot.setAttribute("transform", `translate(${p.x}, ${p.y})`);// is this usefull?
let d = curve.getAttribute('d');
dot.style.setProperty('--mp', '"' d '"')
#dot {
offset-path: path(var(--mp));
animation: move 3000ms infinite alternate ease-in-out;
}
@keyframes move {
100% {
offset-distance: 100%;
}
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<g>
<circle id="dot" r="10" cy="0.5" cx="0.5" style="fill: #dd1819; "></circle>
</g>
<path id="curve" d="M 29.928125,119.32884 C 59.868756,78.85387 99.789596,30.283895 138.66049,30.104515 c 80.46172,-0.37133 90.87185,137.794285 140.7729,129.699295 40.35037,-6.54568 49.90105,-80.94994 86.53937,-78.86548 33.24073,1.89117 22.2547,70.77048 73.14399,70.77048 39.92084,0 58.65264,-56.66496 99.80211,-56.66496 49.90105,0 69.86147,80.94995 99.8021,48.56997" style="fill: none; stroke:black; stroke-width: 1; /*transform:translate(100px, 100px);*/" />
</svg>