admin管理员组文章数量:1397031
I want to position elements on along an SVG curve. I found that we can use textpath
to position text along the path
of an SVG can we do the same with list-elements? If so how to achieve that functionality
Html for positioning text along an SVG
<svg viewBox="0 0 425 300">
<path id="curve"
d="M6,150C49.63,93,105.79,36.65,156.2,47.55,207.89,58.74,213,131.91,264,150c40.67,14.43,108.57-6.91,229-145" />
<text x="25">
<textPath xlink:href="#curve">
This text is now curved
</textPath>
</text>
</svg>
CSS for the same - Just makes it look nice
body {
background-color: #333;
font-family: 'Luckiest Guy', cursive;
font-size: 40px;
}
path {
fill: transparent;
}
text {
fill: #FF9800;
}
body {
background-color: #333;
font-family: 'Luckiest Guy', cursive;
font-size: 40px;
}
path {
fill: transparent;
}
text {
fill: #FF9800;
}
<svg viewBox="0 0 425 300">
<path id="curve"
d="M6,150C49.63,93,105.79,36.65,156.2,47.55,207.89,58.74,213,131.91,264,150c40.67,14.43,108.57-6.91,229-145" />
<text x="25">
<textPath xlink:href="#curve">
This text is now curved
</textPath>
</text>
</svg>
I want to position elements on along an SVG curve. I found that we can use textpath
to position text along the path
of an SVG can we do the same with list-elements? If so how to achieve that functionality
Html for positioning text along an SVG
<svg viewBox="0 0 425 300">
<path id="curve"
d="M6,150C49.63,93,105.79,36.65,156.2,47.55,207.89,58.74,213,131.91,264,150c40.67,14.43,108.57-6.91,229-145" />
<text x="25">
<textPath xlink:href="#curve">
This text is now curved
</textPath>
</text>
</svg>
CSS for the same - Just makes it look nice
body {
background-color: #333;
font-family: 'Luckiest Guy', cursive;
font-size: 40px;
}
path {
fill: transparent;
}
text {
fill: #FF9800;
}
body {
background-color: #333;
font-family: 'Luckiest Guy', cursive;
font-size: 40px;
}
path {
fill: transparent;
}
text {
fill: #FF9800;
}
<svg viewBox="0 0 425 300">
<path id="curve"
d="M6,150C49.63,93,105.79,36.65,156.2,47.55,207.89,58.74,213,131.91,264,150c40.67,14.43,108.57-6.91,229-145" />
<text x="25">
<textPath xlink:href="#curve">
This text is now curved
</textPath>
</text>
</svg>
Can I achieve this functionality for other elements? list elements for example
Note: My final objective is to position small circles (filled) along the curve that are equally spaced.
I'm not very well versed with CSS so if you could point me to resources that will help me achieve this functionality I'll be very grateful
Thanks in Advance
Share Improve this question edited Jun 20, 2021 at 19:31 Alexandr_TT 14.6k3 gold badges31 silver badges58 bronze badges asked Jun 11, 2021 at 16:29 Franticsword546Franticsword546 836 bronze badges 3- Why do you mention "list elements" twice? That normally means text, so your question is troubling me. Do you want that, or simply just the circles. Someone asked a very similar question a week or two ago, but appeared to not be happy with the answer they got. Was that you? – Paul LeBeau Commented Jun 12, 2021 at 8:13
- Does "along the curve equaly spaced" mean "spread to fill the length of the curve", or just "at a specified spacing from one another starting at the beginning"? A mockup image would be useful. – Paul LeBeau Commented Jun 12, 2021 at 8:18
- By along the curve equally spaced I meant that the circles should be spread to fill the length of the curve – Franticsword546 Commented Jun 14, 2021 at 3:41
3 Answers
Reset to default 6You can't do what you want with CSS.
You'll need to use some Javascript. Here's a little example where you can adjust the number of circles, and they will be spaced out evenly along the total length of the path.
let countField = document.getElementById("count");
function updateCircles()
{
let n = countField.value;
// Find the curve path element
let curve = document.getElementById("curve");
// Get the total length of the path
let curveLength = curve.getTotalLength();
// Calculate the spacing between the circles
let spacing = curveLength / (n - 1);
let svg = curve.ownerSVGElement;
// Remove any existing circles
let oldCircles = svg.querySelectorAll("circle");
oldCircles.forEach(oldCircle => svg.removeChild(oldCircle));
// Add the n new circles
for (var i = 0; i < n; i++)
{
// Get the x,y position of a point x along the path
let coords = curve.getPointAtLength(i * spacing);
// Make a circle
let circle = document.createElementNS(svg.namespaceURI, "circle");
circle.cx.baseVal.value = coords.x;
circle.cy.baseVal.value = coords.y;
circle.r.baseVal.value = 6;
// Append it to the SVG
svg.appendChild(circle);
}
}
// Update the circles at the start to show the initial set of circles
updateCircles();
// Update the circles whenever the input changes
countField.addEventListener("input", updateCircles);
path {
fill: none;
stroke: linen;
}
circle {
fill: rgba(0,0,0, 0.5);
}
<svg viewBox="0 0 500 160">
<path id="curve"
d="M6,150C49.63,93,105.79,36.65,156.2,47.55,207.89,58.74,213,131.91,264,150c40.67,14.43,108.57-6.91,229-145" />
</svg>
<input type="range" id="count" value="4" min="3" max="32"/>
Note: My final objective is to position small circles (filled) along the curve that are equally spaced.
textPath
is used to place text along a curve. But you can use Unicode characters instead of text characters.
By using textPath and placing unicode characters inside
<tspan dx =" 5 "fill =" gold "> ⚫ </ tspan>
tags, you can easily place as many circles as you like on one curve.
Here is a link to the unicode characters of the various circles.
Unicode characters can be styled - fill =" red "
, resized - font-size =" 32px "
set the distance between circles dx =" 10 "
<svg width="600" height="400" viewBox="80 100 400 300">
<path id="pathChain" d="M100,200 C100,100 250,100 250,200 S 400,300 400,200" stroke="skyblue" fill="none"/>
<text font-size="14px" x="0" y="0" font-family="Times New Roman" fill="grey" shape-rendering ="crispEdges" >
<textPath id="result" xlink:href="#pathChain">
<tspan dx="0" dy="-2" fill="green" > ⚫ </tspan> <tspan dx="5" dy="-2" fill="gold"> ⚫</tspan><tspan dx="5" fill="crimson"> ⚫</tspan><tspan dx="10" fill="dodgerblue"> ⚫</tspan><tspan dx="0" fill="green" > ⚫ </tspan> <tspan dx="5" fill="gold"> ⚫</tspan><tspan dx="5" fill="crimson"> ⚫</tspan><tspan dx="10" fill="dodgerblue"> ⚫</tspan><tspan dx="0" fill="green" > ⚫ </tspan> <tspan dx="5" fill="gold"> ⚫</tspan><tspan dx="5" fill="crimson"> ⚫</tspan><tspan dx="10" fill="dodgerblue"> ⚫</tspan><tspan dx="0" fill="green" > ⚫ </tspan> <tspan dx="5" fill="gold"> ⚫</tspan><tspan dx="5" fill="crimson"> ⚫</tspan><tspan dx="10" fill="dodgerblue"> ⚫</tspan>
</textPath>
</text>
</svg>
Another example that mimics the chain using unicode characters
Added animation of chain links movement
<svg width="600" height="400" viewBox="100 100 400 300">
<path id="pathChain" d="M100,200 C100,100 250,100 250,200 S 400,300 400,200" stroke="grey" fill="none"/>
<text font-size="36" font-family="Times New Roman" fill="grey" >
<textPath id="result" xlink:href="#pathChain">
<tspan dx="0" > ᴑ </tspan> <tspan dx="-15"> - </tspan><tspan dx="-15"> ᴑ</tspan><tspan dx="-15"> -</tspan><tspan dx="-15"> ᴑ </tspan><tspan dx="-15"> - </tspan><tspan dx="-15"> ᴑ</tspan><tspan dx="-15"> -</tspan><tspan dx="-15"> ᴑ </tspan><tspan dx="-15"> - </tspan><tspan dx="-15"> ᴑ</tspan><tspan dx="-15"> -</tspan><tspan dx="-15"> ᴑ </tspan><tspan dx="-15"> - </tspan><tspan dx="-15"> ᴑ</tspan><tspan dx="-15"> -</tspan><tspan dx="-15"> ᴑ </tspan><tspan dx="-15"> - </tspan><tspan dx="-15"> ᴑ</tspan><tspan dx="-15"> -</tspan><tspan dx="-15"> ᴑ </tspan>
<animate dur="10s" repeatCount="2" attributeName="startOffset" values="1%;55%;1%"/>
</textPath>
</text>
</svg>
You can't place shapes arbitrarily along a path in SVG using just CSS. Your choices here are:
- Don't use a shape, use a text element with tabs and circle characters instead ( e.g. Unicode circle (U+23FA)) and change the font-color to whatever you want
- Use a marker - but placement of these is set to the start, middle & end of each curve segment (marker tutorial)
- Use javascript (e.g. pointAtLength) to calculate the locations of points along a path that you would like to draw circles and set the cx, cy of your circles to those points.
本文标签: javascriptPosition any kind of elements on SVG CurvesStack Overflow
版权声明:本文标题:javascript - Position any kind of elements on SVG Curves - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744148488a2592951.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论