HTML/CSS: Creating Dynamic Button Animations

My code has a few issues that I am looking to fix:

  1. One problem is the sudden color change that occurs when the submit button is clicked. It seems like a glitchy animation, and I want to remove it. Right after clicking the submit button, there is an abrupt color change to something yellowish or whitish.

  2. Another issue is with the positioning of the checkmark and circle background that appear when the animation plays after clicking the submit button. Currently, they are displayed more towards the right, but I want them to be shown at the same place where the button is located. How can I adjust their position?

Any suggestions on how to address these issues would be greatly appreciated. Thanks!

var basicTimeline = anime.timeline({
  autoplay: false,
});

var pathEls = $(".check");
for (var i = 0; i < pathEls.length; i++) {
  var pathEl = pathEls[i];
  var offset = anime.setDashoffset(pathEl);
  pathEl.setAttribute("stroke-dashoffset", offset);
}

basicTimeline
  .add({
    targets: ".text",
    duration: 1,
    opacity: "0"
  })
  .add({
    targets: ".button",
    duration: 1200,
    height: 20,
    width: 200,
    backgroundColor: "#D3D3D3",
    border: "0",
    borderRadius: 100
  })
  .add({
    targets: ".progress-bar",
    duration: 2000,
    width: 200,
    easing: "linear"
  })
  .add({
    targets: ".button",
    width: 0,
    duration: 1
  })
  .add({
    targets: ".progress-bar",
    width: 50,
    height: 50,
    delay: 500,
    duration: 750,
    borderRadius: 80,
    backgroundColor: "#0563bb"
  })
  .add({
    targets: pathEl,
    strokeDashoffset: [offset, 0],
    duration: 200,
    easing: "easeInOutSine",
    complete: () =>
      setTimeout(() => $('#my-form').submit(), 100)
  });


$(".button").click(playButtonAnim);

$(".text").click(playButtonAnim);

function playButtonAnim() {
  basicTimeline.play();
}
input[type=submit] {
  background-color: #0563bb;
  color: white;
  padding: 12px 20px;
  border: none;
  cursor: pointer;
}

input[type=submit]:hover {
  opacity: 0.9;
}

.contactform {
  position: relative;
  border-radius: 50px;
  background-color: #f2f2f2;
  padding: 5px;
  z-index: 2;
  display: block;
  margin-left: auto;
  margin-right: auto;
  margin-bottom: auto;
  margin-top: 1%;
  width: 100%;
  animation-name: gradient;
  animation-duration: 3s;
  animation-iteration-count: infinite;
}

.contactform:hover {
  animation-name: gradient;
  animation-duration: 15s;
  animation-iteration-count: infinite;
}

.column {
  float: center;
  width: 50%;
  margin-top: 6px;
  padding: 20px;
  display: block;
  margin-left: auto;
  margin-right: auto;
}

.row:after {
  content: "";
  display: table;
  clear: both;
}

@media screen and (max-width: 600px) {
  .column,
  input[type=submit] {
    width: auto;
    margin-top: 0;
  }
}

.shakingErr {
  border-color: red;
  animation: shake 0.82s forwards;
}

@keyframes shake {
  10%,
  90% {
    transform: translate3d(-1px, 0, 0);
  }
  20%,
  80% {
    transform: translate3d(2px, 0, 0);
  }
  30%,
  50%,
  70% {
    transform: translate3d(-4px, 0, 0);
  }
  40%,
  60% {
    transform: translate3d(4px, 0, 0);
  }
}


/* fancy button styles */

.buttonWrapper {
  height: 80px;
  width: 100%;
  position: relative;
}

.button {
  background: #0563bb;
  height: 40px;
  width: 90px;
  text-align: center;
  position: absolute;
  top: 25%;
  transform: translateY(-50%);
  left: 0;
  cursor: pointer;
  border-radius: 1px;
}

.text {
  font: .7rem;
  color: white;
  position: absolute;
  top: 50%;
  transform: translateY(-52%);
  left: 0;
  right: 0;
  cursor: pointer;
}

.progress-bar {
  position: absolute;
  height: 20px;
  width: 0;
  left: 100px;
  top: 25%;
  border-radius: 200px;
  transform: translateY(-50%) translateX(-50%);
  background: #0563bb;
}

svg {
  width: 20px;
  position: absolute;
  top: 25%;
  left: 100px;
  transform: translateY(-50%) translateX(-50%);
}

.check {
  fill: none;
  stroke: #FFFFFF;
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.0.2/anime.js">
</script>

<section id="contact">
  <div class="container" data-aos="fade-up">
    <div class="contactform">
      <div class="row">
        <div class="column">
          <form name="myform" action="#" id="my-form" method="POST" novalidate>
            <div class='buttonWrapper'>
              <div class="button">
                <div class="text">Submit</div>
              </div>
              <div class="progress-bar"></div>
              <svg x="0px" y="0px" viewBox="0 0 25 30" style="enable-background:new 0 0 25 30;">
                  <path class="check" class="st0" d="M2,19.2C5.9,23.6,9.4,28,9.4,28L23,2" />
                </svg>
            </div>
          </form>
        </div>
      </div>
    </div>
  </div>
</section>

update

I am facing alignment issues near the bottom of the contact form, specifically after clicking the submit button. How can I resolve this issue?

This is my current output:

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

The expected output should look like this:

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

Answer №1

I made some tweaks to your animation...

  1. To address the abrupt color change, I adjusted it to happen before the transformation occurs (from button to progress-bar). The transition is now smoother, in my opinion.
  2. Regarding the final position, I modified the CSS rule for svg related to the left property and included a left: 26 in the last animation step of .progress-bar.

I have updated some styles and animations for better functionality. Please review below:

[Code snippet with JavaScript]
We also made changes to the CSS styles to improve the overall look and feel of the elements. Take a look at the updated CSS code:
[HTML markup]

Answer №2

var dynamicAnim = anime.timeline({
  autoplay: false,
});

var pathEls = $(".check");
for (var i = 0; i < pathEls.length; i++) {
  var pathEl = pathEls[i];
  var offset = anime.setDashoffset(pathEl);
  pathEl.setAttribute("stroke-dashoffset", offset);
}

dynamicAnim
  .add({
    targets: ".text",
    duration: 1,
    opacity: "0"
  })
  .add({
    targets: ".button",
    duration: 1,
    background: "#FFFFFF",
  })
  .add({
    targets: ".button",
    duration: 600,
    height: 20,
    width: 200,
    border: "0",
    background: "#D3D3D3",
    borderRadius: 100
  })
  .add({
    targets: ".progress-bar",
    duration: 2000,
    width: 200,
    easing: "linear"
  })
  .add({
    targets: ".button",
    width: 50,
    height: 50,
    delay: 500,
    duration: 750,
    borderRadius: 80,
    backgroundColor: "#0563bb"
  })
  .add({
    targets: pathEl,
    strokeDashoffset: [offset, 0],
    duration: 200,
    easing: "easeInOutSine",
    complete: () =>
      setTimeout(() => $('#my-form').submit(), 100)
  });


$(".button").click(activateButtonAnim);

$(".text").click(activateButtonAnim);

function activateButtonAnim() {
  dynamicAnim.play();
}
/* custom button styles */

.buttonWrapper {
  height: 80px;
  width: 100%;
  position: relative;
}

.button {
  background: #0563bb;
  height: 40px;
  width: 90px;
  text-align: center;
  position: relative;
  cursor: pointer;
  border-radius: 1px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto;
  white-space: nowrap;
  overflow: hidden
}

.text {
  font: .7rem;
  color: white;
  position: absolute;
  left: 0;
  right: 0;
  cursor: pointer;
}

.progress-bar {
  position:absolute;
  height: 20px;
  width: 0;
  border-radius: 200px;
  background: #0563bb;
  top: 0;
  left: 0;
}

svg {
  position: relative;
  width: 20px;
  margin: 0 auto;
  display: block;
}

.check {
  fill: none;
  stroke: #FFFFFF;
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.0.2/anime.js">
</script>

<section id="contact">
  <div class="container" data-aos="fade-up">
    <div class="contactform">
      <div class="row">
        <div class="column">
          <form name="myform" action="#" id="my-form" method="POST" novalidate>
            <div class='buttonWrapper'>
              <div class="button">
                <div class="text">Submit</div>
              <div class="progress-bar"></div>
                          <svg x="0px" y="0px" viewBox="0 0 25 30" style="enable-background:new 0 0 25 30;">
                  <path class="check" class="st0" d="M2,19.2C5.9,23.6,9.4,28,9.4,28L23,2" />
                </svg>
                            </div>
            </div>
          </form>
        </div>
      </div>
    </div>
  </div>
</section>

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

How can I achieve slanted edges using CSS?

Can a menu be created solely with CSS that features sloped borders? For example, something like this: http://jsfiddle.net/wmgmqrr9/, but with slanted edges. <ul> <li class="active">home</li> <li>about</li> <li ...

The debate between ensuring input validity and making fields mandatory on multi-page forms

I am currently working on a multi-page form and using jQuery Validate to validate it. The user has four options: next, prev, save, submit. Save, next, and prev all save the current page within the form; whereas submit is similar to save, but triggers addi ...

The usage of Cross-domain AJAX GET parameters is restricted

Currently, I am attempting to retrieve data from an API using JavaScript, but unfortunately I am encountering an error in the process. $.ajax({ dataType: "jsonp", url: "https://www.bitstamp.net/api/ticker/", type: "GET", succes: myfunction ...

Creating a single factory that consolidates multiple return statements

Exploring the ins and outs of AngularJS, I find myself eager to learn how to effectively combine two factory modules. Specifically, I am interested in merging the following two: // Factory Module One services.factory('UserService', function ($re ...

Guide on fetching data from a different php file using jQuery's .load() method?

I am trying to use a basic .load() function from jQuery to load a div element with an id from another file in the same directory when changing the selected option in a selector. However, I am having trouble getting it to work. Nothing happens when I change ...

Determine whether a string contains any symbols other than spaces and tabs

I have a small but challenging problem. Is there a way to detect any visible symbols in a string and output true or false, without using AZ 09 RegExps? I am looking for solutions that work across all languages. Thank you in advance for your help! ...

Display a partial form in Rails using Ajax

There is a form displayed in the image below: Next, I aim to render this partial from an ajax call, specifically from .js.erb. However, I am unsure how to pass an object to f from the partial. Take a look at the image below for reference: Is there a way ...

Changing the image source when clicking on it and removing it can be done by using JavaScript

How can I add a class 'selected' to ".swiper-slide" when it is clicked? I also want to change the image src when svg-img1, 2, or 3 is clicked. However, I need the image to revert back to its default src when another swiper-slide is clicked. ...

Filter out the selection choice that begins with 'aa' in the drop-down menu

Here is a select field with various options: <select id="sel"> <option value="1">aadkdo</option> <option value="2">sdsdf</option> <option value="3">aasdfsddkdo</option> <option value="4"> ...

Exploring Data within Data Structures

I am currently making two JSON requests in my code: d3.json("path/to/file1.json", function(error, json) { d3.json("path/to/file2.json", function(error, json2) { }); }); The structure of json 2 looks like this: [ { "city" : "LA", "locati ...

How can you adjust the div orientation for small screens using Bootstrap?

I've been working with Bootstrap and I'm facing an issue with the orientation of a div on small screens. On medium screens, I have two columns set to 6, 6 which should stack on top of each other on smaller screens. Here's how I want it to lo ...

Bootstrap Button Problem: Difficulty arranging buttons in a neat way, unable to position them next to each other

I'm currently working on a real estate website project and have designed a Photoshop template which is uploaded on Behance. Check it out here. Right now, I'm creating the static version of the real estate store template and facing an issue with ...

JavaScript code for implementing custom commands on a Discord bot

Currently, I am working on developing a Discord bot using the Discord.js-commando library. Most of the functionalities are up and running smoothly, but I have encountered a roadblock with a specific command. The command in question is !roll, which is desig ...

Creating dynamic DIV elements in an AngularJS file using data retrieved from a Sql server

I need to dynamically add elements based on data retrieved from a MSSQL server in the specified area: <div id="ApplicationForm" class="tabcontent" style="display:none;"> <div class="tab_section"> ...

What is the best way to center the text in the middle of a flex container?

I am struggling with the alignment of elements in my code. Here is what I currently have: HTML: </div class="container"> <footer>Maximilian Crosby ©</footer> </div> <div class="bot-bar" > <a href="./contact-u ...

Issue with debugging capabilities in Javascript on VSCode has been detected

UPDATE: I'm seeking guidance on configuring VSCode for debugging Javascript. While I'm familiar with JavaScript functioning in a browser, I find it tedious to rely solely on console.log(). I am looking to debug and step through my code effectivel ...

Unable to add an event while looping through a NodeList in JavaScript

Seeking assistance in iterating a NodeList object using javascript, and implementing a click event for each item : document.addEventListener("DOMContentLoaded", async () => { try { posts.map(post => { container.innerHTML += out ...

CheerioJS was unable to identify and select the anchor tag

I am trying to extract all the download links from the HTML source provided below: https://i.sstatic.net/CvEMF.png Below is the code I am currently using: export const getSingleMusic = async (url) => { const html = await getHtml(url) const $ ...

Is there something I'm overlooking when it comes to vue router transitions?

I am attempting to implement a smooth transition between my Vue components with the following code: <template> <div id="app"> <router-link to="/">Go to home</router-link> <router-link to="Register">Go to register< ...

What exactly does jQuery.Class entail?

I am curious about the purpose of the code snippet below: jQuery.Class("Vtiger_Helper_Js",{ }); I am asking because I am having trouble understanding the function of jQuery.Class... ...