Marker drawing line animation in SVG format

I'm currently working on creating an animated growing arrow. The path is being drawn correctly, but the marker arrow appears instantly at the end. Can someone guide me on how to attach a marker to the end of the path so that it moves along with it?

<?xml version="1.0" encoding="UTF-8"?>
<svg width="291px" height="260px" viewBox="0 0 391 260" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>Path</title>
  <defs>
        <marker id="Triangle" viewBox="0 0 10 10" refX="1" refY="5"
                markerUnits="strokeWidth" markerWidth="4" markerHeight="3"
                orient="auto">
            <path d="M 0 0 L 10 5 L 0 10 z" fill="context-stroke"/>
        </marker>
    </defs>
    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <path marker-end="url(#Triangle)" d="M273.097656,120.507813 C201.899566,163.577543 130.777516,213.94793 50.8398438,240.160156 C36.9248074,244.723012 17.4914196,262.184399 8.2265625,250.84375 C-1.53762975,238.89189 20.198756,222.272258 24.0078125,207.316406 C27.3670238,194.126823 28.5689142,180.441602 29.6132812,166.871094 C30.9603726,149.366986 31.1766739,131.782428 31.171875,114.226563 C31.1623478,79.3735161 8.15793288,37.1795952 29.5703125,9.6796875 C43.1473611,-7.75730878 67.7544299,32.013528 87.5742187,41.7890625 C105.639606,50.6992894 124.365537,58.2317755 143.085938,65.6679688 C150.003672,68.4158594 157.202901,70.4330349 164.40625,72.3085938 C177.173796,75.6329203 190.335014,77.4306133 202.960938,81.2578125 C220.824973,86.6728004 237.747783,94.999359 255.734375,99.9921875 C266.927708,103.099302 278.679688,103.638021 290.152344,105.460938" id="Path" stroke="#979797" stroke-width="10"></path>
    </g>
</svg>
html,
body {
  display: grid;
  place-items: center;
  min-height: 100vh;
}
svg {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  pointer-events: none;
  animation: animateDash 2s linear forwards infinite;
}
@keyframes animateDash {
  to {
    stroke-dashoffset: 0;
  }
}

Check out the code here

UPD: Alternatively, I am open to exploring other methods to achieve a similar outcome. Ideally, I would like to synchronize the length of the arrow with the scroll percentage of the page.

Answer №1

<marker> elements pertain to the precise geometry of an element

While animating, the <path> remains unchanged – causing all markers to retain their original positions.

Markers can only align with:

  • the starting point of an element: marker-start
  • the end point of a path command: marker-mid
  • the end points of an element: marker-end

In simpler terms, you cannot animate or move markers unless you modify the geometry of the element.

<h3>Path d Animation: Marker Movement Based on Geometry Alteration</h3>
<svg viewBox="0 0 391 260" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <marker id="arrow" overflow="visible" viewBox="0 0 10 10" refX="0" refY="0" markerUnits="strokeWidth" markerWidth="10" markerHeight="10" orient="auto-start-reverse">
      <path id="markerArrow" d="M -5 -5 l 10 5 l -10 5 z" opacity="0.5" />
    </marker>
    <marker id="markerStart" overflow="visible" viewBox="0 0 10 10" refX="5" refY="5" markerUnits="strokeWidth" markerWidth="10" markerHeight="10" orient="auto-start-reverse">
      <circle cx="5" cy="5" r="5" fill="green"></circle>
    </marker>
    <marker id="markerMid" overflow="visible" viewBox="0 0 10 10" refX="5" refY="5" markerUnits="strokeWidth" markerWidth="10" markerHeight="10" orient="auto-start-reverse">
      <circle cx="5" cy="5" r="5" fill="orange"></circle>
    </marker>
  </defs>
    <g stroke-width="1" fill="none" stroke="#ccc">
      <path marker-end="url(#arrow)" marker-mid="url(#markerMid)" marker-start="url(#markerStart)" id="motionPath3" pathLength="100" d="M0 50 l0 0  l0 0 l0 0">
        <animate xlink:href="#motionPath3" attributeName="d" attributeType="XML"
                 from="M0 50 l0 0  l0 0 l0 0"
                 to="M20 50 l25 0 l50 0 l100 0"
                 dur="2s"
    fill="freeze"
    repeatCount="indefinite" />
      </path>
    </g>
</svg>

Animate an Element Using <mpath>

  • Create a reusable <path> element for the motion path within a <defs> element
  • Add a marker/arrow element here as well
  • Integrate an SVG SMIL animation via <animateMotion>:
  <animateMotion dur="6s" repeatCount="indefinite" rotate="auto">
    <mpath href="#motionPath" />
  </animateMotion>

Alternative Technique: CSS offset-path

Note: Browser support (as of 2023) for this method is unfortunately still somewhat irregular.

body {
  margin: 1em;
}

svg {
  width: 20em;
  border: 1px solid #ccc;
  overflow: visible;
}

.strokeBG {
  marker-start: url(#markerStart);
  marker-mid: url(#markerRound);
  stroke-width: 0.33%;
}

.strokeAni {
  stroke-dasharray: 0 100;
  animation: animateDash 6s linear forwards infinite;
}

@keyframes animateDash {
  to {
    stroke-dasharray: 100 100;
  }
}

.strokeMarker2 {
  offset-path: path( "M273.1 120.5c-71.2 43.1-142.3 93.4-222.3 119.7 ... animations...
  animation: followpath 6s linear infinite;
}

@keyframes followpath {
  to {
    motion-offset: 100%;
    offset-distance: 100%;
  }
}
<!-- Additional Code Snippets for Reference -->

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having difficulty with loading images lazily in a jQuery Mobile app with LazyLoadXT feature

Struggling to incorporate lazy loading in my jQM app with Lazy Load XT v1.0.6. Oddly, images only appear when switching browser tabs, not while scrolling down. This happens on Firefox and Chrome. <img src="/img/default-img.jpg" data-src="/img/product/ ...

Transferring information from a Java file to AJAX

I have a Java class that prints progress as 1%, 2%, 3% of a process. Now, I am looking to utilize AJAX requests to read this progress and update it continuously on the webpage. Unfortunately, I cannot convert the Java file into a servlet since it is being ...

The operator in Javascript that uses question marks for conditionals is known as the

I understand that the expression: return A ? B : C translates to If A is true, return B; otherwise, return C But how should I interpret the following: return A ? B ? C : D : E This code is not mine; I simply want to comprehend it. I came across this a ...

Tips for creating a grid design with evenly spaced row gaps

I am currently working on a grid layout featuring cards of varying heights. My goal is to maintain a consistent gap between the cards, creating a mosaic-like design. I am utilizing Styled Components for this project, but the current code I have doesn' ...

Mastering the Art of Modifying HTML with Node.js

Is it possible to manipulate HTML using Node.js? 1. First, I need to retrieve data from a database. 2. Then, I need to modify or add HTML code within Node. In essence, the goal is to fetch data and integrate it into an HTML file. The JavaScript snippet ...

Implementing JSON parsing in an ESP32 application using AJAX script

Currently, I am engrossed in a project that involves utilizing ESP32. I'm obtaining data from various sensors and transmitting it to a webpage hosted on the same board. After doing some research online, I learned that it's considered "better" to ...

Issue with radio button list not functioning properly in Mozilla and Chrome browsers

My web application has a radiobuttonlist with an onclick event. It functions properly in IE, but not in some other browsers. Here is a snippet of the code: <asp:RadioButtonList ID="rbgThreadStatus" runat="server" RepeatDirection=&quo ...

Take action once the Promise outside of the then block has been successfully completed

Presented below is the code snippet: function getPromise():Promise<any> { let p = new Promise<any>((resolve, reject) => { //some logical resolve(data); }); p.finally(()=>{ //I want do something when ou ...

Struggling to maintain preventDefault functionality while utilizing a submitHandler, causing the form to bypass and directly access the AJAX PHP

I'm having trouble keeping my AJAX call within the same page. Despite multiple attempts with preventDefault(), the form keeps getting submitted. Below is the complete code for a form with ID "#leadform" and a button with ID "#submitButton". $(docume ...

Position the menu directly below the MaterialUI appbar

Here is a method for positioning a Menu (popover) below its parent item using the anchorEl. However, I am curious if there is an easier way to adjust the menu placement to be directly under the appbar while still aligning horizontally with the parent butto ...

Eliminate the blank choice from X-editable Select

Lately, I've been dealing with AngularJS and X-editable and one thing that has been troubling me is the fact that the select option always includes an empty first child. Here's the HTML <span editable-select="curuser.roles" e-name="roles" ...

Would it be possible to use a script to convert the y-axis values of the chart into Arabic numerals?

Currently, I am working on creating line and pie charts, but I need the Y-axis to display Arabic language. $('button').on('click', function(e) { $('#pie-chart3').empty(); var type = $(this).d ...

ASP.NET: How to Leverage UpdatePanel with OnLoad Event

I am attempting to run some javascript code during the OnLoad event of my UpdatePanel like this: <asp:UpdatePanel ID="updDropDowns" runat="server" OnLoad="javascript:ResetButtons();"> However, I am receiving an error saying "'javascript' ...

Here's a unique version: "Verify if the searched location matches the corresponding data in the API and notify the user with an alert in case of any discrepancies."

Currently, if a user doesn't input a valid location in the API (e.g. a spelling mistake), the console displays an error. How can I make an alert appear on the screen to notify the user when this happens? const cityRef = document.querySelector(&ap ...

The jQuery click event to change the color function is functioning properly, but there seems to be an issue with

I'm having trouble changing the font-family using the code below, even though the color is changing properly. What am I missing here and how can I correct it? $(document).ready(function(){ $("body").on("click",".selectableColor", function(){ ...

The jQuery click event does not fire within a bootstrap carousel

I am trying to set up a bootstrap carousel where clicking on an image inside it will trigger a self-made lightbox. However, I am facing some issues with the JavaScript code not being triggered with the following syntax: $('html').on("click", ".l ...

Having trouble with loading nested state in ui-router

Despite my efforts to find a solution online, I am stuck on a fairly basic issue. The router/index.html page I am working with appears to be correct, as there are no errors in the console. However, when the URL redirects to the login page, the entire page ...

Dealing with the "TypeError: Cannot read property 'style' of undefined" error in material-ui Transitions: A troubleshooting guide

While attempting to incorporate transitions within my react app, I encountered a recurring error whenever I tried to implement any transition module: "TypeError: Cannot read property 'style' of undefined". (anonymous function) node_modules/ ...

Is there a way in Vue.js for me to access a method from within the same component using the component's data?

Below is the code for a specific component: <template> <li v-for="(item, i) in this.menu" :key="i" @click="item.action()"> //attempting to call the method in the component {{menu.title}} <li> </template> <script> ...

Is there a way for me to insert a variable into the src attribute of my img tag like this: `<img alt="Avatar" src=`https://graph.facebook.com/${snAvatarSnuid}/picture`>`

I need assistance with passing a variable called snAvatarSnuid within the img src tag, specifically after facebook.com/ and before /picture as shown below: <img alt="Avatar" src=`https://graph.facebook.com/${snAvatarSnuid}/picture`> Note: 1) The ht ...