0

I want to move an animated gif along an svg path on scroll, I've been trying to adapt Text moving along an SVG <textPath> but it's not working. I'd like to know what the best solution is.

        <svg id="text-container" viewBox="0 0 1000 194" xmlns="http://www.w3.org/2000/svg">
          <path id="text-curve" d="M0 100s269.931 86.612 520 0c250.069-86.612 480 0 480 0" fill="none"/>
          
          <text y="40" font-size="2.1em">
            <textPath id="text-path" href="#text-curve">
              <img src="../imagesIndex/originals/dragon.gif" height="194px"/>
            </textPath>
          </text>
        </svg>

I can get Text moving along the SVG curve but not the image. I've tried expanding the SVG viewbox, shrinking the image with the defined height above, I've tried changing the SVG <textPath to <path it didn't work. I'm getting nowhere.

The image appears, but it won't move along the SVG's path.

Here's the Javascript

    <script>
      console.clear();

var textPath = document.querySelector('#text-path');

var textContainer = document.querySelector('#text-container');

var path = document.querySelector( textPath.getAttribute('href') );

var pathLength = path.getTotalLength();
console.log(pathLength);

function updateTextPathOffset(offset){
  textPath.setAttribute('startOffset', offset); 
}

updateTextPathOffset(pathLength);

function onScroll(){
  requestAnimationFrame(function(){
    var rect = textContainer.getBoundingClientRect();
    var scrollPercent = rect.y / window.innerHeight;
    console.log(scrollPercent);
    updateTextPathOffset( scrollPercent * 2 * pathLength );
  });
}

window.addEventListener('scroll',onScroll);
    </script>

Apologies if this question is a duplicate. I do have a Greensock GSAP, ShockinglyGreen subscription, all libraries available, but I'm yet to dig into it.

Sam
  • 1,659
  • 4
  • 23
  • 42
  • 2
    an HTML element can't be the child of an SVG element. The only valid children of textPath elements are tspan or a elements. – Robert Longson Jul 01 '21 at 12:56
  • Cheers, I've set off down a GSAP journey. If you post that as an answer I'll accept it. – Sam Jul 01 '21 at 16:12
  • It's not really an answer though is it, it tells you what you're doing wrong so you can figure out how to do it some other way. Write that other way in your own answer if you like. – Robert Longson Jul 01 '21 at 16:16

1 Answers1

1

Here's some sample code to position an SVG <image> element at a position along a path determined by the page scroll.

var path = document.querySelector('#text-curve');
var cat = document.querySelector('#cat');
var catWidth = 40;
var catHeight = 40;

function updateImagePosition(offset) {
  let pt = path.getPointAtLength(offset * path.getTotalLength());
  cat.setAttribute("x", pt.x - catWidth/2);
  cat.setAttribute("y", pt.y - catHeight/2);
}

// From: https://stackoverflow.com/questions/2387136/cross-browser-method-to-determine-vertical-scroll-percentage-in-javascript
function getScrollFraction() {
    var h = document.documentElement, 
        b = document.body,
        st = 'scrollTop',
        sh = 'scrollHeight';
    return (h[st]||b[st]) / ((h[sh]||b[sh]) - h.clientHeight);
}

function onScroll() {
  updateImagePosition( getScrollFraction() );
}


updateImagePosition(0);

window.addEventListener('scroll', onScroll);
body {
  min-height: 1000px;
}

svg {
  display: block;
  position: sticky;
  top: 20px;
}
<svg id="text-container" viewBox="0 0 1000 194">
  <path id="text-curve" d="M0 100s269.931 86.612 520 0c250.069-86.612 480 0 480 0" fill="none" stroke="gold"/>
  <image id="cat" x="0" y="100" xlink:href="https://placekitten.com/40/40"/>
</svg>
Paul LeBeau
  • 97,474
  • 9
  • 154
  • 181
  • Cheers Paul, I'll learn Javascript at some point I think, I can see what it's doing, would be good to do it myself. – Sam Jul 05 '21 at 17:55