[英]Fill Shapes/Icon In SVG Path (js)
I have a SVG with path我有一个带路径的 SVG
<svg width="100" height="100" stroke="black" fill="transparent">
<path d="M 10 10 H 90 V 90 H 10 L 10 10"/>
</svg>
and I have to fill some svg shapes / icons in the path with a gap
.我必须在路径中用
gap
填充一些 svg 形状/图标。 For example I have filled the svg path with the circle shape with a gap=2px
例如,我用
gap=2px
的圆形填充了 svg 路径
is there any javascript function or can we do it with just SVGs and the gap
between the circle should be customizable and it should work for all the svg with paths.有没有 javascript function 或者我们可以只用 SVG 来做吗?圆圈之间的
gap
应该是可定制的,它应该适用于所有带路径的 svg。 (thanks in advance) (提前致谢)
Instead of filling you will need a special stroke.你需要一个特殊的行程而不是填充。 The
stroke-dasharray
is similar to the border-style in css. However it will create only dashed lines. stroke-dasharray
类似于 css 中的 border-style。但是它只会创建虚线。 In the following example I'm using stroke-dasharray="0.1, 9.9"
meaning lines of 0.1 units and gaps of 9.9在下面的示例中,我使用
stroke-dasharray="0.1, 9.9"
表示 0.1 单位的线和 9.9 的间隙
To make them look like dotted I'm using stroke-linecap="round" and a thick line: stroke-width="6"
为了使它们看起来像虚线,我使用了 stroke-linecap="round" 和一条粗线:
stroke-width="6"
Please observe that line + gap = 0.1 + 9.9 = 10 and the square side length is 80 (a multiple of 10) ensuring that you have a dot in every corner.请注意线 + 间隙 = 0.1 + 9.9 = 10,正方形边长为 80(10 的倍数),确保每个角都有一个点。
<svg width="100" height="100" stroke="black" fill="transparent"> <path d="M 10 10 H 90 V 90 H 10 L 10 10" stroke-dasharray="0.1, 9.9" stroke-width="6" stroke-linecap="round" ></line>/> </svg>
Not using:不使用:
<marker>
getTotalLength
/ getPointAtLength
getTotalLength
/ getPointAtLength
Using:使用:
<defs>
to define any (compound) SVG group "markN" <defs>
定义任何(复合) SVG 组“markN”<svg-path-markers>
to proces <path>
<svg-path-markers>
处理<path>
customElements.define
script can be executed at any moment you want! customElements.define
脚本可以随时执行!<path marker="mark1" markers="4">
attributes indicating which markN to use <path marker="mark1" markers="4">
指示使用哪个 markN 的属性<path>
to link it to an <mpath>
(motionpath)<path>
的唯一 ID将其链接到<mpath>
(运动路径)<animateMotion>
to animate a "marker" <animateMotion>
为“标记”设置动画keyPoints="0,${dist}"
to position the "marker" keyPoints="0,${dist}"
到position “标记” Output: Output:
With:和:
<svg-path-markers> <svg viewBox="0 0 100 100" style="background:pink;max-height:180px"> <defs> <g id="mark1"><circle fill="red" cx="0" cy="0" r="8" /></g> <g id="mark2"><rect fill="green" x="-4" y="-4" width="8" height="8" /></g> <g id="mark3"><circle fill="yellow" cx="0" cy="0" r="2" /></g> </defs> <style>path{ stroke:green; fill:none }</style> <path marker="mark1" markers="4" d="M 10 10 H 90 V 90 H 10 L 10 10" /> <path marker="mark2" markers="8" d="M 10 10 H 90 V 90 H 10 L 10 10" /> <path marker="mark3" markers="16" d="M 10 10 H 90 V 90 H 10 L 10 10" /> </svg> </svg-path-markers> <script> customElements.define("svg-path-markers", class extends HTMLElement { connectedCallback() { setTimeout(() => { // wait till innerHTML is parsed this.querySelectorAll("[marker]").forEach( path => { let duration = "2"; // set to 0.00001 for instant display let count = ~~path.getAttribute("markers") || 4; let id = path.id || (path.id = this.localName + Math.random()*1e9); let marker = dist => `<use href="#${path.getAttribute("marker")}"> <animateMotion dur="${duration}" fill="freeze"calcMode="linear" keyPoints="0;${dist}" keyTimes="0;1" > <mpath href="#${id}"/></animateMotion></use>`; path.insertAdjacentHTML("afterend", Array(count).fill(0).map((_,i) => marker(i*(1/count))).join("")); } ) })}}) </script>
You can use getTotalLength() to find the length of the path and getPointAtLength() to find points along the path where you place the elements.您可以使用getTotalLength()查找路径的长度,使用getPointAtLength()查找放置元素的路径上的点。
In this example I append <use>
elements to a <g>
.在此示例中,我将 append
<use>
元素添加到<g>
中。
const p1 = document.getElementById('p1'); const p2 = document.getElementById('p2'); const c1 = document.getElementById('c1'); const c2 = document.getElementById('c2'); setIcons(p1, 'r1', c1, 10); setIcons(p2, 'p3', c2, 10); function setIcons(path, id, container, numb){ let total = parseInt(path.getTotalLength()); let gap = total / numb; [...Array(numb).keys()].map(i => { let point = path.getPointAtLength(i*gap); let use = document.createElementNS('http://www.w3.org/2000/svg','use'); use.setAttribute('href', `#${id}`); use.setAttribute('transform', `translate(${point.x} ${point.y})`); container.appendChild(use); }); }
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220 100" height="100" stroke="black" fill="transparent"> <defs> <rect id="r1" x="-5" y="-5" width="10" height="10" fill="red" /> <path id="p3" d="M -10 -12.5 A 5 5 90 0 0 10 -12.5 V 12.5 A 5 5 90 0 0 -10 12.5 Z" fill="red" /> </defs> <path id="p1" d="M 10 10 H 90 V 90 H 10 L 10 10" /> <g id="c1"></g> <g transform="translate(120 0)"> <path id="p2" d="m 0 90 V 50 A 1 1 1 0 1 90 50 V 90" /> <g id="c2"></g> </g> </svg>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.