How can a JQuery function be used with SVG to trigger a second animation immediately after the first animation is finished?

For the handwriting effect animation, I utilized the animation-delay technique by dividing the object wherever it intersected, drawing paths, and converting them into clipping masks. This involved breaking the letter "W" into four parts, creating different paths for each part, and animating them to achieve a clean handwriting effect. It was time-consuming due to the complexity of the font.

Currently, I am using the animation-delay CSS function to achieve this animation.

CSS Code

#W2-Path {
    animation-delay: .5s
}

#W3-Path {
    animation-delay: 1s
}

#W4-Path {
    animation-delay: 1.5s
}

#O-Path {
    animation-delay: 2s
}

#R1-Path-2 {
    animation-delay: 3.5s
}

#R2-Path-2 {
    animation-delay: 4s
}

#R3-Path-2 {
    animation-delay: 4.5s
}

#L1-Path-2 {
    animation-delay: 5s
}

#L2-Path-2 {
    animation-delay: 5.5s
}

#L3-Path-2 {
    animation-delay: 6s
}

#D1-Path {
    animation-delay: 6.5s
}

#D2-Path {
    animation-delay: 7s
}

I am considering other ways to start the second animation as soon as the first one completes in order to create a smoother and perfectly timed effect. Is there a way to achieve this using JQuery?

CodePen: https://codepen.io/ToxifiedM/pen/MWKeERr

Original Question: How Can I Make SVG Text Animation Seamless And Accurate?

Linked Question 1: To Control SVG CSS Based Animation Using Jquery?

Linked Question 2: To Control The Speed Of Multiple SVG Elements Using Jquery?

Answer №1

My response is specifically focused on the latter W

I decided to modify the svg code you provided in a more simplified manner.

You were previously using 2 groups to wrap each line, but I have opted for using just the lines directly. Additionally, instead of utilizing

style="clip-path: url(#clip-path)"
, I adjusted it to a presentational attribute format like this: clip-path="url(#clip-path)". This adjustment allows for setting animation-delay as an inline style for the lines within JavaScript.

Another enhancement includes applying stroke-dasharray: 8 and stroke-dashoffset: 8 since the length of the lines representing the letter W is 8. The determination of the line lengths was achieved by using the getTotalLength() method.

The stroke and stroke-width properties are now set at the group level, considering that all lines representing the letter share the same styling.

The JavaScript section involves selecting all lines within the group, iterating through them, and establishing the animation-delay:${i*1}s where i represents the index of each line. It's important to note that the order of the lines within the group should be from first to fourth, contrary to the original positioning in your provided code snippet.

let Wls = document.querySelector("#W").querySelectorAll("line");

Wls.forEach((l,i) => {
    // For each line in the W group
    // Set the style attribute
    l.setAttribute("style", `animation-delay:${i*1}s`);
})
body {
    background: white;
}

svg {
    width: 90vh; 
    border: solid;
}

#W line {
    stroke-dasharray: 8;
    stroke-dashoffset: 8;
    animation: letter-animation 1s linear forwards;
}

@keyframes letter-animation {
    0% {
        stroke-dashoffset: 8;
    }
    100% {
        stroke-dashoffset: 0;
    }
}
<svg id="WOYP" viewBox="0 0 9 9">
    <defs>
        <clipPath id="clip-path-44" transform="translate(-5.561 -10.291)">
            <path id="W4" d="M11.676,16.41l.234.578c.236-.631.477-1.261.715-1.891q.222-.6.449-1.188t.409-1.063q.181-.476.308-.8c.084-.214.136-.348.156-.4s.05-.12.066-.16a.594.594,0,0,1,.061-.111.754.754,0,0,1,.086-.1.768.768,0,0,1,.151-.11h-1.03c.121.053.192.117.212.19a.481.481,0,0,1-.04.291c0,.007-.025.079-.076.216s-.118.319-.2.546-.18.483-.287.767-.216.573-.323.867Z" />
        </clipPath>
        <clipPath id="clip-path-45" transform="translate(-5.561 -10.291)">
            <path id="W3" d="M11.675,16.358Zm0,0h0l.011.029h0l.232.575c-.152.4-.311.82-.474,1.252L10.176,15.07q-.242-.6-.478-1.183t-.433-1.058q-.2-.474-.333-.793c-.09-.213-.146-.343-.166-.389a1.8,1.8,0,0,0-.176-.27.774.774,0,0,0-.348-.209h1....

UPDATE

The user is seeking additional guidance:

During my implementation attempts, I encountered an issue with the letter "O" since it contains a path rather than a line. I attempted to apply your solution, but it didn't work for paths. Do you have any suggestions on how to address this?

In such cases where paths are involved, they need to be animated differently. Unlike before, there is no requirement for a separate CSS animation, and given that the final value for stroke-dashoffset is 0, another animation isn't necessary either. However, calculating the total length of the path is crucial for determining the values of stroke-dasharray and stroke-dashoffset, which in this instance amounts to 20.4.

let Wls = document.querySelector("#W").querySelectorAll("line");

Wls.forEach((l,i) => {
    l.setAttribute("style", `animation-delay:${i*1}s`);
})
body {
    background: white;
}
svg {
    width: 90vh; 
    border: solid;
    overflow: visible;
}

#W line {
    stroke-dasharray: 8;
    stroke-dashoffset: 8;
    animation: letter-animation 1s linear forwards;
}

#O path {
    stroke-dasharray: 20.4;
    stroke-dashoffset: 20.4;
    animation: letter-animation 1s linear forwards;
    animation-delay: 4.5s;
}


@keyframes letter-animation {
    100% {
        stroke-dashoffset: 0;
    }
}
<svg id="WOYP" viewBox="0 0 29 9">
    <defs>
        <clipPath id="clip-path-44" transform="translate(-5.561 -10.291)">
            <path id="W4" d="M11.676,16.41l.234.578c.236-.631.477-1.261.715-1.891q.222-.6.449-1.188t.409-1.063q.181-.476.308-.8c.084-.214.136-.348.156-.4s.05-.12.066-.16a.594.594,0,0,1,.061-.111.754.754,0,0,1,.086-.1.768.768,0,0,1,.151-.11h-1.03c.121.053.192.117.212.19a.481...

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

Exploring Grails: Utilizing Jquery Ajax data array

I am facing an issue with accessing the answers array in my Grails application. The problem arises from a function that creates a data object and populates it with input values: var data={ id:1, answers:[] } $.each($('.panel-body input[type= ...

EU directive on cookies: What is the best way to store your preferences?

While there are numerous third-party solutions available to comply with the cookie EU directive, I prefer to learn how to implement it myself. My specific requirement is that when a user clicks on "Accept", their choice should be remembered for the entire ...

Unable to adjust custom link menu font size

I have designed a unique custom menu called SANDUSKY with the css classes of no-hover. It is positioned alongside HOME, ABOUT, GALLERY, STORE, CONTACT which serve as the navigation menus. While attempting to customize SANDUSKY, I successfully altered the c ...

Avoiding freezing of the user interface caused by ajax requests

The code that was previously commented out on lines 192, 193, 196, 197, 199, and 205 in the base.html file at this link caused my UI to freeze. It made working with my text editor extremely difficult. I am looking for a way to uncomment those lines witho ...

Floating CSS drop menu with added bottom margin

I have created a simple dropdown CSS menu positioned in the footer with an upwards direction. You can view it here: http://jsfiddle.net/RmTpc/11/ My issue is that I want the opened menu to have some bottom margin from the main list item ("Items"). However ...

Automatic table width expansion with CSS

I'm in the process of creating a new website, and I want the layout to resemble the following: +---+--------------+ |# | | |n | #page | |a | table.basic | |i | | |g | | |a | | |t | ...

Is there a quick way to import all available font weights from a Google font?

I am looking to experiment with importing all weights and styles of a Google font, such as Roboto or Roboto Slab, in a CSS file. Is there a more efficient way to do this rather than listing out each individual style in the @import? ...

Moving Angularjs table rows to another tableMoving table row from one Angular

I need a solution for transferring rows from one table to another. Here are the two tables involved: First Table: <table> <tr ng-repeat="row in items"> <td>{{row.PRODUCTDESCRIPTION}}</td> <td><inpu ...

What could be causing my ajax not to retrieve the text currently being typed in the input form?

I am facing an issue with my form where I am unable to update the data when typing something new into the input field. It seems like the form is not picking up the currently typed string when on the update page, and instead it's using the echoed out v ...

Utilizing ASP.NET MVC with AjaxFileUpload

Hey there, I've been struggling with this issue for quite some time now. I really need to perform an asynchronous upload using ajaxFileUpload. While I can successfully post the file to my controller, when trying to return a JsonResult, I keep encounte ...

A transparent float is yielding unexpected outcomes

<!Doctype html> <html> <head> <meta charset="utf-8" /> <title>testing code</title> </head> <body> <div style="float: left; width: 200px; height: 150px; background-color: ...

When clicking on a checkbox's assigned label, Chrome and IE may experience delays in firing the change event

When a user checks a checkbox under a specific condition, I want to display an alert message and then uncheck the checkbox. To achieve this, I am utilizing the click function on the checkbox to internally uncheck it and trigger necessary events. I have a ...

Transforming the button behavior with jQuery

I have encountered a situation where I am working with code in Twig. {% if followsId == null %} <div id="followUser" class="follow" data-userId="{{ profileUserData.id }}" data-currentUserId="{{ loggedUserData.id }}" data-action="follow"> ...

Transforming JavaScript information into PHP with ajax for WordPress plugin creation

I'm currently navigating the realm of creating my inaugural WordPress plugin and encountering a hurdle in transposing a Javascript array of objects into PHP. My aim is to utilize this data to craft individual tables within the wp-admin user interface. ...

Executing a jQuery code within a WordPress theme

I have been attempting to implement the following script within the header.php file of a Wordpress website: <script> jQuery(function($) { jQuery('[href=#membership]').attr( 'data-menu-top', '500' ); }); ...

Populate the table with JSON object information

I've structured a table as follows: <div class="row"> <div class="row"> <table class="table table-bordered table-striped tree-grid"> <thead class="text-primary"> <tr> <th> ...

Using Ember's transitionTo method and setting a controller attribute within a callback

I am working with Ember code to transition to a specific route while also setting controllerAttr1 on 'my.route' Upon transitioning to "my.route" using this.get('router').transitionTo("my.route"), I have set up a callback function that ...

Is it possible to change the background color of a MUI theme in ReactJS by using Css

Currently, I am utilizing Material UI to create a theme that is functioning correctly. However, upon adding <CssBaseline/> to the App.js file, it unexpectedly changes the background color to white instead of the intended #1f262a specified in the inde ...

Adjust the top margin of content to account for the height of a fixed header

When dealing with a fixed header that has been removed from the HTML flow, it can be tricky to adjust the content below it. The challenge arises because the height of the header can vary based on screen size. How can we dynamically adjust the margin-top fo ...

A sleek CSS text link for a stylish video carousel

I am attempting to create a CSS-only text link to video slider within our Umbraco CMS. Due to the limitations of TinyMCE WYSIWYG, I am restricted in the amount of code I can use as it will strip out most of it. So far, I have developed a basic CSS slider ...