skip to Main Content
<svg width="100%" height="160px" viewBox="0 0 1098.72 89.55">
    <path id="curve" fill="transparent" d="M0.17,0.23c0,0,105.85,77.7,276.46,73.2s243.8-61.37,408.77-54.05c172.09,7.64,213.4,92.34,413.28,64.19"></path>
    <text width="100%">
        <textPath xlink:href="#curve">*The pictures are not technically selfies.</textPath>
    </text>
</svg>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
    $(document).ready(function() {
        const textPath = document.querySelector("textPath");
        const textPathLength = textPath.getComputedTextLength();
        const duration = 10000; // Adjust the duration as needed

        $(textPath).css("startOffset", textPathLength);

        function animateText() {
            $(textPath).animate(
                { "startOffset": -textPathLength },
                {
                    duration: duration,
                    easing: "linear",
                    complete: function() {
                        animateText();
                    }
                }
            );
        }

        animateText();
    });
</script>

I’m trying to move text on wave path but its not working. I want it to move on the path so I add it to section on the website. If I try with marquee tag its move but in straight line. I also try many marquee options but the result is not same as I want.

2

Answers


  1. Here is something you could do using UNPKG splitting script. You need to put the needed path in the CSS variable --path. Tweaking the animation will give you different results.

    Splitting({
      whitespace: true
    })
    html {
      font-family: Arial, Helvetica, sans-serif;
    }
    
    :root {
      --path: "M0.17,0.23c0,0,105.85,77.7,276.46,73.2s243.8-61.37,408.77-54.05c172.09,7.64,213.4,92.34,413.28,64.19";
    }
    
    .myText {
      height: 100px;
      font-family: Arial, Helvetica, sans-serif;
      text-transform: uppercase;
      color: red;
    }
    
    .char {
      position: absolute;
      offset-path: path(var(--path));
      offset-distance: calc(var(--char-index) * 1.5rem);
      animation: loop 4s cubic-bezier(.62, .01, .42, 1.01) infinite alternate calc(var(--char-index) * 10ms);
    }
    
    @keyframes loop {
      50% {
        offset-distance: calc((var(--char-index) * 1rem) + 40%);
      }
      100% {
        offset-distance: calc((var(--char-index) * 1rem));
      }
    }
    <script src="https://unpkg.com/[email protected]/dist/splitting.min.js"></script>
    
    <p>
      Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type
    </p>
    
    <p class="myText" data-splitting>Your text here</h1>
    
    <p>
      Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type
    </p>
    <p>
      Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type
    </p>
    <p>
      Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type
    </p>

    And even if that is not what you want, you could modify it or use it as a base or inspiration for your actual case of use

    Login or Signup to reply.
  2. Jquery’s animate() method can only animate CSS properties – SVG’s startOffset attribute can’t be changed via CSS.

    Alternative: animate your text via SMIL animation

    let svg = document.querySelector('svg')
    
    // pause and resume
    svg.addEventListener('mouseover', e => {
      svg.pauseAnimations();
    })
    
    svg.addEventListener('mouseleave', e => {
      svg.unpauseAnimations();
    })
    <svg width="100%" height="160px" viewBox="0 0 1098.72 89.55">
        <path id="curve" fill="transparent" d="M0.17,0.23c0,0,105.85,77.7,276.46,73.2s243.8-61.37,408.77-54.05c172.09,7.64,213.4,92.34,413.28,64.19"></path>
        <text width="100%">
            <textPath id="textPath" href="#curve" startOffset="100%">*The pictures are not technically selfies.
               <animate attributeName="startOffset" from="100%" to="-50%" begin="0s" dur="5s" repeatCount="indefinite" />
          </textPath>
        </text>
    </svg>

    You just need to add an <animate> elements to your textpath and specify parameters duration, initial and final values like so

    <textPath id="textPath" href="#curve" startOffset="100%">*The pictures are not technically selfies.
    <animate 
        attributeName="startOffset" 
        from="100%" 
        to="-50%" 
        begin="0s" 
        dur="5s" 
        repeatCount="indefinite" />
    </textPath>
    

    Now we can easily pause all animations by calling pauseAnimations()

    See also "How to pause and run just one SMIL animation in svg?"

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search