Matching stroke-dashoffset in SVG between two distinct paths

I am currently working on animating stroke-dashoffset for two different paths to create a drawing effect. There are buttons provided to adjust the stroke-dashoffset values.

My goal is to ensure that the filled paths align vertically as they progress. Is this achievable?

https://i.sstatic.net/PIhiI.png

However, in the current demo, the stroke-dashoffsets of the two paths do not match because the jagged path is longer.

I would like to find a solution that does not involve simply placing one path over the other, as it would eliminate the unique "drawing" animation look and both paths have rounded ends.

const btnAdd = document.querySelector(".btn-add");
const btnSub = document.querySelector(".btn-sub");
const line = document.querySelector(".line");
const jaggedLine = document.querySelector(".jagged-line");
const lineLength = line.getTotalLength();
const jaggedLineLength = jaggedLine.getTotalLength();

line.setAttribute("stroke-dasharray", lineLength);
jaggedLine.setAttribute("stroke-dasharray", jaggedLineLength);
line.setAttribute("stroke-dashoffset", lineLength);
jaggedLine.setAttribute("stroke-dashoffset", jaggedLineLength);

let progress = 0;

const updateSVG = () => {
  line.setAttribute("stroke-dashoffset", lineLength - progress);
  jaggedLine.setAttribute("stroke-dashoffset", jaggedLineLength - progress);
};
btnAdd.addEventListener("click", () => {
  progress++;
  updateSVG();
});
btnSub.addEventListener("click", () => {
  progress--;
  updateSVG();
});
.svg {
  margin-top: 50px;
}
  <button class="btn-add">+</button>
  <button class="btn-sub">-</button>
  <div class="svg">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 73.76 45.715" height="172.781" width="278.7779">
      <g fill="none" stroke="#00aad4" stroke-linecap="round">
        <path
          d="M.8825 28.1368h7.6506l2.6171-10.6905 6.865 25.6202 3.1614-36.3492 3.9609 28.4864 1.1125-6.9395h8.7471l1.2762-7.3971 4.4477 23.966 2.3077-38.0867 1.6134 15.1554h7.5l3.3783 16.805 1.6625-13.5108h15.6946"
          opacity=".165" stroke-width=".965" stroke-linejoin="round" />
        <path d="M.8825.8825h71.995" opacity=".1648" stroke-width=".965" />
        <path class="jagged-line"
          d="M.8825 28.1368h7.6506l2.6171-10.6905 6.865 25.6202 3.1614-36.3492 3.9609 28.4864 1.1125-6.9395h8.7471l1.2762-7.3971 4.4477 23.966 2.3077-38.0867 1.6134 15.1554h7.5l3.3783 16.805 1.6625-13.5108h15.6946"
          stroke-width="1.765" stroke-linejoin="round" />
        <path class="line" d="M.8825.8825h71.995" stroke-width="1.765" />
      </g>
    </svg>
  </div>

Answer №1

One interesting feature in SVG is the pathLength attribute, which allows us to define the path length.

The pathLength attribute enables authors to specify the total length of a path, measured in user units. This value serves as a calibration tool for ensuring that the browser's distance calculations match those of the author, by scaling all distance computations using the ratio of pathLength to the computed value of the path length.

This can have an impact on the rendered lengths of paths, including text paths, animation paths, and various stroke operations. It affects any calculations that rely on the length of the path; for instance, the stroke-dasharray property assumes the start of the path at 0 and ends at the value set in the pathLength attribute.

MDN

If we assign the same value to the pathLength for both animations, they become more straightforward and synchronized.

.svg {
  display: inline-block;
  margin: 1em;
}

.line,
.jagged-line {
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  animation: dash 5s linear alternate infinite;
}

@keyframes dash {
  from {
    stroke-dashoffset: 100;
  }
  to {
    stroke-dashoffset: 0;
  }
}
<div class="svg">
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 73.76 45.715" height="172.781" width="278.7779">
      <g fill="none" stroke="#00aad4" stroke-linecap="round">
        <path
          d="M.8825 28.1368h7.6506l2.6171-10.6905 6.865 25.6202 3.1614-36.3492 3.9609 28.4864 1.1125-6.9395h8.7471l1.2762-7.3971 4.4477 23.966 2.3077-38.0867 1.6134 15.1554h7.5l3.3783 16.805 1.6625-13.5108h15.6946"
          opacity=".165" stroke-width=".965" stroke-linejoin="round" />
        <path d="M.8825.8825h71.995" opacity=".1648" stroke-width=".965" />
        <path class="jagged-line"
          d="M.8825 28.1368h7.6506l2.6171-10.6905 6.865 25.6202 3.1614-36.3492 3.9609 28.4864 1.1125-6.9395h8.7471l1.2762-7.3971 4.4477 23.966 2.3077-38.0867 1.6134 15.1554h7.5l3.3783 16.805 1.6625-13.5108h15.6946"
          stroke-width="1.765" stroke-linejoin="round" pathLength="100"/>
        <path class="line" d="M.8825.8825h71.995" stroke-width="1.765" pathLength="100"/>
      </g>
    </svg>

</div>

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

Different ways to activate the system bell in Node.js

Currently, I have a custom nodejs script running for an extended period and I'm seeking a way to receive a notification once the script finishes its execution. Is there a method in nodejs that can be used to activate the "System Bell" alert? ...

Learn how to easily set a radio button using Angular 4 and JavaScript

It seems like a simple task, but I am looking for a solution without using jQuery. I have the Id of a specific radio button control that I need to set. I tried the following code: let radiobutton = document.getElementById("Standard"); radiobutton.checke ...

Updating and removing items from a React state using push and pop methods

I am working on a component in React and have the following state: this.state = { Preferences: [] } I am trying to push an element only if it does not already exist in the array to avoid adding duplicate elements. If the element is already ...

The challenges of positioning HTML li elements in a floating layout

Check out my website: . I'm having an issue with the layout where two <li> elements are stacked on top of each other and one is floating next to them, but it's only floating next to the second one. How can I make it float next to the first ...

Populating an array in JavaScript with specific values from another array to meet a certain criteria

Looking to implement a function called populateAnimalArray, which takes an array as input and populates it with additional elements based on another argument specifying the required number. const animals = ['lion', 'tiger', 'cheet ...

I encountered a Node.js 203 error specifically on my computer - could this be linked to a specific environment and is there a way to resolve it

Let me explain what happened: I was working on a Nodejs-express-angular example by Brian Ford the other day, and everything was running smoothly. update:----------------this part of problem has been solved---------- However, after a few hours (during wh ...

Switch modules based on user options

My goal is to process an array of image files. I have the option to select them randomly or one by one (queue) based on the configuration specified in the config.json. To start off, I create the processor and determine the appropriate image selection modu ...

The alignment of navbar elements appears to be off in Jquery mobile

Currently working on an app using Jquery mobile, and encountering an issue where the navbar is not displaying elements in line. The google chrome console is indicating spaces between list elements. Upon removing these &nbsp characters, the elements ali ...

Transform a javascript object with class attributes into a simple object while keeping the methods

I am seeking a way to convert an instance of a class into a plain object, while retaining both methods and inherited properties. Here is an example scenario: class Human { height: number; weight: number; constructor() { this.height = 1 ...

Can one initiate a server within Zapier Code?

Is there a way to send an HTTP CODE = 200 with a response body of 'OK' when receiving a notification on Zapier? I attempted to use the following code snippet in Zapier: var http = require('http'); const server = http.createServer((r ...

Error in thread : TagNameUnexpectedException

I encountered an issue while trying to find a dropdown using Select: An error occurred: Exception in thread "main" org.openqa.selenium.support.ui.UnexpectedTagNameException: Element should have been "select" but was "input" Even when attempting to use ...

Getting user input with JQuery and dynamically updating CSS properties

<img src="purplemoon.png" alt="Purple moon" id="moon-photo" /> <table> <tr> <th colspan="4">Control panel</th> </tr> <tr> <td> <!-- attempting to retrieve value from the input field ...

What is the best way to integrate node.js with HTML?

I am currently utilizing node.js to interact with an API on the IBM Cloud platform. I have successfully accessed the response in my code, but now I need to pass this data to an HTML page using "res.send". How can I achieve this? Below is the Node.js code ...

Unable to view image stored as a blob

https://i.stack.imgur.com/8v90u.pngI have been studying these examples PHP display image BLOB from MySQL How to display an BLOB image stored in MySql database? They all demonstrate the same method of displaying images saved as blob. In my case, I ha ...

Expandable Grid with UI-GRID - Automatically expand a row when clicked on

I prefer not to utilize the default + icon for expanding the row. The row should expand when clicked anywhere on it. I attempted the following: HTML <div ui-grid="gridOptions" ui-grid-expandable class="grid"> Controller var app = angular.module( ...

Ways to display a different div when clicking on a div?

Good afternoon, I've noticed that this question has been asked numerous times before, but none of the solutions provided seem to work for my specific issue. My problem involves a div with the class .title3. I want another div with the class .Content ...

Unique name for the transition animation on SSR-Nuxt page transitions

Attempting to implement a dynamic transition name for Nuxt page transitions as shown below: export default{ data() { return { prevHeight: 0, transitionName: 'page' }; }, transition: { na ...

Why does my Javascript cross-domain web request keep failing with a Status=0 error code?

UPDATE: I've been informed that this method doesn't work because craigslist doesn't have an Allow-Cross-Domain header set. Fair point. Is there an alternative way to download a page cross-domain using Javascript in Firefox? It's worth ...

What could be the reason behind the varying outcomes browsers provide for the JavaScript expression new Date(-105998400000)?

When I use ASP.NET MVC 3 with the default Json serializer, I notice that dates from my JsonResults come back in the format /Date(-105998400000)/. To handle this, I extract the number and create a new Date object with this value. However, I am experiencing ...

Activate simultaneous HTML5 videos on iOS devices with a simple click

I am currently in the process of developing a webpage that will play various videos when specific elements are clicked. Although the functionality works perfectly on desktop computers, it encounters an issue on iOS devices. The problem arises when the elem ...