Tips for activating multiple CSS animations when scrolling

I am currently working on a project that involves multiple CSS animations. However, I am facing an issue where these animations only occur once when the page initially loads. I would like them to trigger every time the user scrolls past them, regardless of whether they are scrolling up or down the page. Unfortunately, my attempts at using JavaScript to achieve this have been unsuccessful so far. The specific animations include a colored box sliding in from the left and body copy/header elements fading in from the bottom. I aim to stagger these two animations slightly, with the text appearing after the box has slid in halfway. I have tried grouping these divs together to reveal them simultaneously upon scroll, as well as treating them as separate entities within my JavaScript code.

$(window).scroll(function() {
  $('#Featuring_Animated').each(function() {
    var imagePos = $(this).offset().top;
    var imageHeight = $(this).height();
    var topOfWindow = $(window).scrollTop();

    if (imagePos < topOfWindow + imageHeight && imagePos + imageHeight > topOfWindow) {
      $(this).addClass("slide-in-left");
    } else {
      $(this).removeClass("slide-in-left");
    }
  });
});

$('.element-to-hide').css('visibility', 'hidden');
/**
 * ----------------------------------------
 * animation slide-in-left
 * ----------------------------------------
 */

.Featuring_Textbox {
  -webkit-animation: slide-in-left .5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
  animation: slide-in-left .5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
  visibility: visible !important;
}

@-webkit-keyframes slide-in-left {
  0% {
    -webkit-transform: translateX(-1000px);
    transform: translateX(-1000px);
    opacity: 0;
  }
  100% {
    -webkit-transform: translateX(0);
    transform: translateX(0);
    opacity: 1;
  }
}


/**
 * ----------------------------------------
 * animation fade-in-bottom left sections
 * ----------------------------------------
 */

#Featuring_About,
#Featuring_Heading {
  -webkit-animation: fade-in-bottom 0.6s cubic-bezier(0.390, 0.575, 0.565, 1.000) .3s both;
  animation: fade-in-bottom 0.6s cubic-bezier(0.390, 0.575, 0.565, 1.000) .3s both;
  visibility: visible !important;
}

@-webkit-keyframes fade-in-bottom {
  0% {
    -webkit-transform: translateY(50px);
    transform: translateY(50px);
    opacity: 0;
  }
  100% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    opacity: 1;
  }
}


/**
 * ----------------------------------------
 * animation fade-in-bottom left sections
 * ----------------------------------------
 */

#Featuring_Textbox {
  opacity: 0.9;
  fill: #3B4A5C;
}

.Featuring_Textbox {
  position: absolute;
  overflow: visible;
  width: 640px;
  height: 552px;
  left: 0px;
  top: 0px;
}

#Featuring_About {
  left: 74px;
  top: 238px;
  position: absolute;
  text-align: left;
  font-size: 18px;
  color: white;
}

#Featuring_Heading {
  left: 74px;
  top: 143px;
  position: absolute;
  text-align: left;
  font-size: 40px;
  color: white;
}
<html>
<head>
<script language="JavaScript" type="text/javascript" src="colocation.js"></script>
</head>

<div class="Featuring_Animated element-to-hide" style="visibility:visible;">
  <svg class="Featuring_Textbox">
            <rect id="Featuring_Textbox" rx="0" ry="0" x="0" y="0" width="640" height="552"></rect>
         </svg>
  <div id="Featuring_About">
    <span>Sample Text</span>
  </div>
  <div id="Featuring_Heading">
    <span>FEATURING</span>
  </div>
</div>

</html>

Answer №1

For those who prefer not to use a library, there is an alternative method available. (compiled from various contributors, thank you) Different effects can be assigned to different selectors. The animation will trigger once when a set percentage of the element becomes visible on the screen (isInViewport function - currently set at 35%). It will only trigger once.

// Ensure every element has a "hidden" class if its starting state is hidden (e.g., 'visibility:hidden' for fade-in effects)

var elemList = {elements:[ // Add elements and their corresponding animations here
    {elem:"#home-description", animation:"element-animation"},
    {elem:".nav-item", animation:"slide-in-top"}
]};

var isInViewport = function(el, percentVisible) {
    let
    rect = el.getBoundingClientRect(),
        windowHeight = (window.innerHeight || document.documentElement.clientHeight);

    return !(
        Math.floor(100 - (((rect.top >= 0 ? 0 : rect.top) / +-(rect.height / 1)) * 100)) < percentVisible ||
        Math.floor(100 - ((rect.bottom - windowHeight) / rect.height) * 100) < percentVisible
    )
};



function check(){
    var eArray = elemList.elements;

    if (eArray.length >= 1){  
        eArray.forEach( function(e,i){

            if (e.elem){ // Check if element selector is not empty
                let el = document.querySelectorAll(e.elem);

                if (el.length >= 1){

                    el.forEach( function(x,y){
                        if (isInViewport(x,35)){
                            x.classList.remove("hidden"); // Remove this line if the element should be visible by default
                            x.classList.add(e.animation);
                            eArray.splice(i, 1);
                            
                        }
                    })
                }
            }
        })
    }
}


window.addEventListener('load', function () {
    check();
    document.addEventListener('scroll', function () {
        check();
    })
}, {
passive: true
});

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

Setting up a reverse proxy for deploying React applications

I am attempting to implement a setup where multiple containerized SPAs are deployed using a reverse proxy for routing. Each container contains a production build create-react-app served by an express app with the following configuration: app.use(express.s ...

Extracting targeted information from an HTML page using Python: A step-by-step guide

I'm a beginner in python and I need to scrape information from an HTML text file using python 2.7. The example below shows the structure of one firm's data in the HTML file. The same structure is used for all other firms as well, with each firm ...

Having issues with images not loading and receiving a 401 error with the API while using Vite in a production build

While working on my React project with Vite, I've encountered a few challenges during the production build process. Everything seems to be running smoothly when I use npm run dev, but when I try to build the project using npm run build and then previ ...

Using Javascript and Node.js, a child class instance in ES5 can access a method belonging to its parent

I am facing an issue while trying to call a parent's method from child's constructor. Below is the code snippet: parentClass.js var ParentClass = function(arg) { this.arg = arg; this.result = {}; }; ParentClass.prototype = { constr ...

"Using the power of jQuery to efficiently bind events to elements through associative

I am attempting to link the same action to 3 checkboxes, with a different outcome for each: var checkboxes = { 'option1' : 'result1', 'option2' : 'result2', 'option3' : 'result3', }; ...

Angular encountering issues with loading external JavaScript files due to the error: ENOENT - indicating that the specified file or directory does

I am attempting to incorporate a bootstrap template into Angular. The template requires some external JavaScript and CSS files that need to be linked. I have placed these files in the assets folder and referenced them in the styles and scripts arrays of an ...

The (.svg) image does not cover the full width of the page

After creating an SVG image, I encountered a problem when trying to display it on a webpage. Even with the width value set to 100%, the image did not stretch all the way to the edges of the page, leaving small gaps at the edges. I attempted to switch the ...

Bring google map markers to life with animation

Is there a way to create an animation like the one shown in this example? I'd like for the map to highlight the corresponding place when a user clicks or hovers over a location in the list. How can I make this happen? I've tried searching on Go ...

Obtain redirected JSON data locally using Angular 5

Currently, I am working on retrieving JSON data which will be sent to my localhost through a POST method. The SpringBoot API controller will validate the JSON content before forwarding it to my localhost. My task is to intercept this JSON data when it is t ...

Validation of input using JQuery

I am currently working on validating a form, with a specific field that needs to be required. Here is the code for the field in question: <p> <label for="lf">Name: </label> <input class="lf" name="name" type="text"/> < ...

Firefox 3.5: The Notorious Code Copycat

Encountering an issue in Firefox 3.5.2 where after clicking a link on the page and then returning using the back button or another link, extra HTML code appears. Unsure if it's added by Firefox or related to PHP code. Unfortunately, unable to share t ...

How can I use CSS to change the background color of a fixed navbar when scrolling?

Is it possible to use only CSS to alter the background color of a fixed navbar once the user has scrolled past a specific point vertically? I am curious if this can be accomplished in CSS by targeting the ID of another element, or possibly its height? Alt ...

Error: The value of 'v4' property is not defined and cannot be read

I am encountering an issue with Vue.js: vue.esm.js?efeb:628 [Vue warn]: Error in v-on handler: "TypeError: Cannot read property 'v4' of undefined" found in ---> <AddTodo> at src/components/AddTodo.vue <App> at src/Ap ...

The Best Way to Calculate a Total Sum with Comma-Separated Values in AngularJS

In my application, I am utilizing the MEAN stack with AngularJS as the front-end. I am trying to figure out how to calculate the total sum and include comma values. I have managed to get the total sum value, but the comma value is not being calculated prop ...

What is the best way to obtain the id of a selected row using JavaScript?

I'm attempting to utilize the JavaScript function below to extract a specific cell value from a jqgrid upon clicking. Within the following function, #datagrid refers to the table where the jqgrid is located. $("#datagrid").click(function ...

What is the process for incorporating ejs into the source attribute of an image element?

Code Snippet: <img class="card-img-top" alt="..."><%= articles.image %><img> Server Setup: const express = require('express') const app = express() const router = require('./routes/article') app ...

Modules are being installed to the application's root directory using NPM

I made a mistake and have tried everything to correct it, but no success. Every time I run 'npm install' on a new node project, it installs all dependencies in the root of the application instead of the expected /node_modules/ directory. For ex ...

Lean/Tilt just the lower portion of the division

I have been experimenting with adding a unique slant to the bottom of a div. Progress has been made, as shown in the example below where I successfully applied the slant to some elements on the page. Currently, the slant is visible on both the top and bot ...

Surprising Outcomes of Negative Margin in jQuery Animation

Unique Project Summary I am currently working on a website that incorporates a sliding menu feature. I have successfully implemented this functionality, and the display remains consistent during the animation transitions for sliding the menu in and out. T ...

Guide to deploying a React application using Material-UI and react-router

I've successfully built an application using React, Material-UI, and react-router. Below is the content of my complete package.json: { "name": "trader-ui", "version": "0.1.0", "private": true, "dependencies": { "@material-ui/core": "^3.2. ...