Switch between multiple animations and styles using CSS

I'm currently working on the code below that involves toggling between different elements. Despite my attempts to add/remove classes and use toggle, it doesn't seem to be functioning as expected. Is there a straightforward way to revert everything back on the second click?

$( ".next" ).click(function() {
$('.triangle').animate({  borderSpacing: -180 }, {
    step: function(now) {
      $(this).css('-webkit-transform','rotate('+now+'deg)'); 
      $(this).css('-moz-transform','rotate('+now+'deg)');
      $(this).css('transform','rotate('+now+'deg)');
    },
    duration:'slow'
},'linear');

$('.engine').css('background-image','url(/Incubator/wp-content/themes/incubator/images/basketball.jpg)');
$('.info-block').animate({"margin-left": "0px"}, 1000);
$('.triangle').animate({"margin-left": "380px"}, 1000);
$('.alt').css('display', 'block');
$('.main').css('display', 'none');
$('.messy').fadeOut("slow");
$('.compete').fadeIn("slow");
$(this).removeClass("next");
$(this).addClass("back");
});


$( ".back" ).click(function() {
$('.triangle').animate({  borderSpacing: 0 }, {
    step: function(now) {
      $(this).css('-webkit-transform','rotate('+now+'deg)'); 
      $(this).css('-moz-transform','rotate('+now+'deg)');
      $(this).css('transform','rotate('+now+'deg)');
    },
    duration:'slow'
},'linear');

$('.engine').css('background-image','url(/Incubator/wp-content/themes/incubator/images/engine.jpg)');
$('.info-block').animate({"margin-left": "800px"}, 1000);
$('.triangle').animate({"margin-left": "722px"}, 1000);
$('.alt').css('display', 'none');
$('.main').css('display', 'block');
$('.messy').fadeIn("slow");
$('.compete').fadeOut("slow");
$(this).removeClass("back");
$(this).addClass("next");
});

and here's the HTML sample:

<div data-speed="5" class="engine parallax">
    <div class="wrapper">

        <div data-pos="550" class="next fade-in triangle"></div>
        <div data-pos="550" class="fade-in">
            <h3 class="messy">Get messy in the Incubator!</h3>
            <h3 class="compete">Compete in the Incubator!</h3>
        </div>
            <div data-pos="550" class="fade-in info-block">
                <p class="main">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
                <p class="alt">Test text here sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
            <a href="">Get started today</a>
            </div>
    </div>
</div>

Answer №1

Edit, Updated

Instead of adding and removing classes like .next and .back at the .triangle element to toggle effects, try using a single click event handler.

I have included easing: 'linear' in the options property where the easing property was not set.

// Set `.triangle` `.data("clicked")` to false initially
var t = $(".triangle").data("clicked", false)
// Save `css` `matrix()` positions
, props = []
// Reset `matrix`
, p = props.length > 0 ? props.reverse() : false;
// Define both initial and reset animations on a single `click` event
t.click(function() {
  // Cache value of `.data("clicked")`, initially set to `false`
  var d = $(this).data("clicked") === true
  // Initial index to iterate over `props`
  , n = 0;
  // If `d` is set, set `prop` to -180, else set it to 0
  $(d ? {
    prop: -180
  } : {
    prop: 0
  }).animate(d ? {
    prop: 0
  } : {
    prop: -180
  }, {
    step: function(now) {
      if (d) {
        t.css("transform", p[++n]) 
      };
      t.css("transform", "rotate(" + now + "deg)");
      props.push(t.css("transform"));
    },
    duration: "slow",
    easing: "linear",
    complete: function() {
      var r = t.data("clicked") === false ? true : false;
      $(".engine").css("background-image", "url(/Incubator/wp-content/themes/incubator/images/" + (!r ? "basketball" : "engine") + ".jpg)");
      t.add(".info-block").animate({
        "margin-left": !r ? "0px" : "800px"
      }, 1000);
      $(".alt")[!r ? "show" : "hide"]();
      $(".main")[!r ? "hide" : "show"]();
      $(".messy, .compete").fadeToggle("slow");
      t.data("clicked", r);
    }
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div data-speed="5" class="engine parallax">
  <div class="wrapper">

    <div data-pos="550" class="next fade-in triangle">next</div>
    <div data-pos="550" class="fade-in">
      <h3 class="messy">Get messy in the Incubator!</h3>
      <h3 class="compete">Compete in the Incubator!</h3>
    </div>
    <div data-pos="550" class="fade-in info-block">
      <p class="main">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
        dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
      <p class="alt">Test text here sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit
        esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
      <a href="">Get started today</a>
    </div>
  </div>
</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

Error encountered using Meteor 1.3 autoform/quickform integration

Having recently transitioned to using Meteor 1.3, I've encountered a few challenges related to debugging due to missing imports or exports in tutorials. This particular issue seems to be in the same vein. I wanted to incorporate the autoform package ...

Difficulty with obtaining .responsetext in AJAX and PHP

On my real estate website, I have a form for users to 'Add a Property'. Although I will implement form validation later on, here is the current html/js code: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR ...

Angular - Dealing with the value of zero in the @if template syntax

Having a dilemma with the Angular template flow syntax using @if. There is a value within an RxJs Observable, which is handled with the async pipe and assigned to a variable. @if (currentPageNumber$ | async; as currentPageNumber) { // currentPageNumber is ...

What is the best method for disabling autoscroll for a specific div id when the :target attribute

I created this accordion menu using only html and css, but the buttons are built with the :target id. Is there a way to prevent the automatic scrolling when any button is clicked without using javascript? It currently moves to the anchor #id. I've se ...

Sending an AJAX request will only transmit a portion of an array when using the JSON.stringify

I have a JavaScript array that is constantly updated. Here's how I initially set up the array... columnArray = ["userID", "Date", "trialType", "cue", "target", "response", "accuracy", "lenAcc", "strictAcc", "fkpl", "totalTime"]; var dataArray = []; ...

Interactive drop-down menu for populating a input field

I have been searching everywhere for a solution to this issue but have not been able to figure it out. I was able to make it work when I needed a dynamic drop-down to adjust the values in a second drop-down and fill in a text value in a text box. Now, I w ...

Perform an action when a button is clicked in a VueJs single-page application

How can I trigger the refreshMailList function when clicking on the mail-list component? This is my Vue instance with a custom mail-list component: Vue.component('mail-list', { props: ['inboxmail'], template: ` <div> ...

CSS - Yet another perplexing question that shouldn't have arisen

While working on building this website in CSS, I hadn't encountered any major issues up until now. Suddenly, I'm facing a problem with basic positioning within my body-3 class div. Instead of pushing it downward and elongating the page as expecte ...

Encountering a problem when attempting to utilize AngularFire's Cloud Messaging Angular module due to missing configuration values for the app

Working with Firebase Cloud Messaging in my Angular application using AngularFire2 has presented a challenge. I am facing an error when attempting to retrieve the user's current token. I have already set up the "firebase-messaging-sw.js" and "manifes ...

The error message "unhandledPromiseRejectionWarning: TypeError: Cannot read property 'password' of null" indicates that there is an issue

(node:7152) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'password' of null at exports.login (C:\Users\niko\Desktop\opaa\controllers\controller.js:39:56) at process._tickCallback (internal/proces ...

Automatically fill in a text field based on the selection from a drop

I need to automate the process of filling in text boxes on a page based on what the user selects from a dropdown menu. When the user changes their selection from the dropdown list, I want the corresponding text box to update with the value associated with ...

Style condition within an HTML element

Can you apply conditional styling within the <head> tag as demonstrated in the following example? <body> <div id="InScreenAlertContainer" <!--[if IE]> <style>width=100%</style> <![endif]--> > ...

Angular project icons not displaying in the browser

My current project in Angular was functioning properly until recently. I am facing an issue where the images are not being displayed on the browser when I run ng serve, resulting in a 404 error. Interestingly, everything else seems to be working fine witho ...

Track and store your current progress with a countdown deadline using a progress bar in Bootstrap 4

I am working on a unique way to showcase a dynamic countdown date progression using Bootstrap 4 progress bar. The challenge lies in displaying the progress percentage based on a specific date input format from an admin. After retrieving the deadline date ...

The AJAX request function in JavaScript seems to be failing to return any response

I am currently working on a registration page where users can check the availability of their selected username without having to reload the entire page. The PHP script 'usernameAJAX.php' is responsible for querying the database and returning a r ...

What is the best way to choose all elements that fall between two specific elements?

Looking to grab content situated between two specific elements within an HTML structure. The HTML snippet in question is as follows... <h2>This is firsty</h2> <p>Some para</p> <ul> <li>list items</li> <li&g ...

Beginner's guide to setting up an HTTPS server using Express.js

After setting up a simple https server using node.js with express, I created a basic login form for testing purposes that sends data to this secured server. My assumption was that by configuring the server as follows: var app = require('../app' ...

Tips for ensuring that eslint typescript identifies interfaces in .d.ts files

Currently, I am working on a project that involves Vite 3, Vuetify 3, and Vue 3 with the Volar extension. I have defined interfaces in some .d.ts files and also have ESLint installed. However, ESLint keeps complaining about not being able to find the inter ...

The image is not properly aligned with the background image

I'm currently working on a page design using bootstrap and css where I want images to fade and reveal the background when hovered over. The challenge I'm facing is that although all images are set to 100px in size, there is white space visible ar ...

Issue with Jquery/JqGrid: When a grid contains only one column, the grid paging controls are not fully displayed and are cut

On my webpage, I have a grid that is generated dynamically and allows users to choose which columns to display. This grid also has pagination enabled due to the large amount of data rows it can contain. Everything works well in most scenarios, except for ...