Home > Back-end >  linking textPath with javascript instead of xlink:href in html?
linking textPath with javascript instead of xlink:href in html?

Time:08-01

Is there a way to link a textPath to a path directly through javascript?

something like this maybe?

let path=document.querySelector("path");
let txt_path=document.querySelector("textPath");

textPath.href=path
<svg id="svg1" width="1000" height="1000">

<path fill="none" stroke="black" d="M 0 0 L 300 300" stroke-width="3"/>

  <text id="txt1" font-size="24" dy="-10">
    <textPath id="result" text-anchor="middle" startOffset="50%" >
       Hello there
    </textPath>
  </text>

</svg>

The entire idea is that I have too many paths and can't assign an id to every single one & instead directly linking them with javascript would be much more convenient

is something like this even possible? or is there no workaround ids?

Note: I tried this but it doesn't seem to support cross browser

CodePudding user response:

The path needs an id and the textPath then points to that id.

let path=document.querySelector("path");
let textPath=document.querySelector("textPath");

path.id = self.crypto.randomUUID();

textPath.href.baseVal = "#"   path.id;
<svg id="svg1" width="1000" height="1000">

<path fill="none" stroke="black" d="M 0 0 L 300 300" stroke-width="3"/>

  <text id="txt1" font-size="24" dy="-10">
    <textPath id="result" text-anchor="middle" startOffset="50%" >
       Hello there
    </textPath>
  </text>

</svg>

CodePudding user response:

It is all done by ID (only FireFox has the path attribute on textPath)

Write a Web Component, for symantic HTML : <svg-text-path> that generates a unique ID. No shadowDOM required then and all you global CSS applies.

<svg-text-path>Hello</svg-text-path>
<svg-text-path>Wonderful</svg-text-path>
<svg-text-path d="M0,90H180">Web Components</svg-text-path>

<style>
  svg { background:pink }
  textPath { fill: green }
  [d*="H"] svg {background:lightgreen}
</style>

<script>
  customElements.define("svg-text-path", class extends HTMLElement {
    connectedCallback() {
      setTimeout(() => { // make sure innerHTML is parsed
        let id = Math.random()*1e32;
        this.innerHTML = `<svg width="180" height="180">
             <path id="TP${id}" pathLength="100" fill="none" stroke="black" 
                   d="${this.getAttribute("d")||'M0,0L180,180'}" stroke-width="3"/>
             <text font-size="24" dy="-10">
             <textPath href="#TP${id}" text-anchor="middle" startOffset="50" >
              ${this.innerHTML}</textPath></text></svg>`;
        })
      }
    })
</script>

  • Note: You can only create Web Components in the HTML NameSpace extends HTMLElement, alas not (yet) in the SVG NameSpace. But as shown you can use Web Components to create SVG
  • Related