Flip text within textPath element of an SVG

Viewed 256

I've been having a huge problem here. There is some text within a textPath tag of an svg element that I need to flip 180 degrees. I've used all methods that would work with css but absolutely NOTHING works. Can anyone help me with flipping the text within the element.

function Init() {
  let w = wrap.clientWidth;
  let h = wrap.clientHeight;
  ellipse.setAttributeNS(null, "viewBox", `0 0 ${w}  ${h}`);
  let d = `M${w / 10},${h / 2}A${4 * w / 10},${4 * h / 10} 0 0 0 ${9 *
    w /
    10} ${5 * h / 10} A${4 * w / 10},${4 * h / 10} 0 0 0 ${w / 10} ${5 *
    h /
    10} A${4 * w / 10},${4 * h / 10} 0 0 0 ${9 * w / 10} ${5 * h / 10} A${4 *
    w /
    10},${4 * h / 10} 0 0 0 ${w / 10} ${5 * h / 10}`;

  thePath.setAttributeNS(null, "d", d);
  let path_length =  thePath.getTotalLength();
  
  
  //begin at a bigger size than needed
  let font_size = 100;
  ellipse.style.fontSize = font_size+"px"; 
  
  // while the text length is bigger than half path length 
  while(tp.getComputedTextLength() > path_length / 2 ){
    //reduce the font size
    font_size -=.25;
    //reset the font size 
    ellipse.style.fontSize = font_size+"px";
  }
}



window.setTimeout(function() {
  Init();
  window.addEventListener("resize", Init, false);
}, 15);

let so = 0;

function Marquee() {
  requestAnimationFrame(Marquee);
  tp.setAttributeNS(null, "startOffset", so + "%");
  if (so >= 50) {
    so = 0;
  }
  so += 0.02;
}

Marquee();
html, body {
    margin: 0;
    height: 100%;
    width: 100%;
}

body {
    font-family: "Arimo", sans-serif;
}

#wrap{
    width:100%;
    height:100%;
    position: fixed;
    top: 0;
    left: 0;  
}
text {
    text-transform: uppercase;
    font-weight: lighter;
}
<div id="wrap">
    <svg id="ellipse" version="1.1" viewBox="0 0 1000 1000">
    <path id="thePath" fill="transparent" d="M100,500A400,400 0 0 0 900 500 A400,400 0 0 0 100 500"  />

       <text stroke="black">
          <textPath xlink:href="#thePath" dy="5" id="tp" lengthAdjust="spacingAndGlyphs">Coming Soon • Coming Soon • Coming Soon • Coming Soon • Coming Soon • Coming Soon • Coming Soon •</textPath>
        </text>
    </svg>
</div>

1 Answers

As I've commented you need to teverse the path. Since the path is controled by the script you need to change the value for the d variable in the function Init

function Init() {
  let w = wrap.clientWidth;
  let h = wrap.clientHeight;
  ellipse.setAttributeNS(null, "viewBox", `0 0 ${w}  ${h}`);
  let d = `M${9*w / 10},${h / 2}
  A${4 * w / 10},${4 * h / 10} 0 0 1 ${w / 10} ${5 * h / 10}
  A${4 * w / 10},${4 * h / 10} 0 0 1 ${9 * w / 10} ${5 * h / 10} 
  A${4 * w / 10},${4 * h / 10} 0 0 1 ${w / 10} ${5 * h / 10} 
  A${4 * w / 10},${4 * h / 10} 0 0 1 ${9 * w / 10} ${5 * h / 10} `;

  thePath.setAttributeNS(null, "d", d);
  let path_length =  thePath.getTotalLength();
  
  
  //begin at a bigger size than needed
  let font_size = 100;
  ellipse.style.fontSize = font_size+"px"; 
  
  // while the text length is bigger than half path length 
  while(tp.getComputedTextLength() > path_length / 2 ){
    //reduce the font size
    font_size -=.25;
    //reset the font size 
    ellipse.style.fontSize = font_size+"px";
  }
}



window.setTimeout(function() {
  Init();
  window.addEventListener("resize", Init, false);
}, 15);

let so = 0;

function Marquee() {
  requestAnimationFrame(Marquee);
  tp.setAttributeNS(null, "startOffset", so + "%");
  if (so >= 50) {
    so = 0;
  }
  so += 0.02;
}

Marquee();
html, body {
    margin: 0;
    height: 100%;
    width: 100%;
}

body {
    font-family: "Arimo", sans-serif;
}

#wrap{
    width:100%;
    height:100%;
    position: fixed;
    top: 0;
    left: 0;  
}
text {
    text-transform: uppercase;
    font-weight: lighter;
}
<div id="wrap">
    <svg id="ellipse" version="1.1" viewBox="0 0 1000 1000">
    <path id="thePath" fill="transparent"  />

       <text stroke="black">
          <textPath xlink:href="#thePath" dy="5" id="tp" lengthAdjust="spacingAndGlyphs">Coming Soon • Coming Soon • Coming Soon • Coming Soon • Coming Soon • Coming Soon • Coming Soon •</textPath>
        </text>
    </svg>
</div>

Also please read the related blog post: https://codepen.io/enxaneta/post/animate-marquee-on-svg-curve

UPDATE

the OP is asking;

Is there anyway to make the svg spin anti clockwise

I'm not very sure what he means by this since the original demo is spinning anticlockwise. Please try changing the function Marquee() like so: instead of increasing the startOffset so you decrease it.

let so = 50;

function Marquee() {
  requestAnimationFrame(Marquee);
  tp.setAttributeNS(null, "startOffset", so + "%");
  if (so <= 0) {
    so = 50;
  }
  so -= 0.02;
}

Marquee();
Related