Adjust the styling of elements when they are positioned 300 pixels from the top of the viewport

Hey there, I don't have much experience with JavaScript, but I gave it a shot. I managed to create a script that changes the properties of an element based on its position relative to the viewport of the browser.

It took me a couple of days to get it working, but currently, it only works for one element using its ID. I would like it to work for all elements with the same class.

Each element should function independently without affecting each other. For example, if "Primo" is in a specific position, it should only modify its rotation. Similarly, if "Secondo" is in a certain position, it should only adjust its rotation. Thanks in advance for any assistance!

Answer №1

Experience the .each() method by following these steps:

function calculatePosition($element) {
  var $window = $(window),
      scrollLeft = $window.scrollLeft(),
      scrollTop = $window.scrollTop(),
      offset = $element.offset(),
      rect1 = { x1: scrollLeft, y1: scrollTop, x2: scrollLeft + $window.width(), y2: scrollTop + $window.height() },
      rect2 = { x1: offset.left, y1: offset.top, x2: offset.left + $element.width(), y2: offset.top + $element.height() };
  return {
    left: offset.left - scrollLeft,
    top: offset.top - scrollTop,
    insideViewport: rect1.x1 < rect2.x2 && rect1.x2 > rect2.x1 && rect1.y1 < rect2.y2 && rect1.y2 > rect2.y1
  };
}
$(window).on("load scroll resize", function() {
    $(".element").each(function(){
          var position = calculatePosition($(this));
          var newValue = position.top - 350;
          if (position.top < 130) {
             $(this).css("transform", "rotatez(-55deg) rotate(-45deg) translate(0,0)");
          } 
          else if (position.top > 343) {
                $(this).css("transform", "rotatez(0deg) rotate(-45deg) translate(0,0)");
          } 
          else if (position.top > 130) {
                $(this).css("transform", "rotatez(" + newValue / 4 + "deg) rotate(-45deg)) translate(0,0)");
          }
    });
});
body {height: 2048px}
.element {position: absolute;
  top: 400px; left: 30px;
  width: 107px;
  height:107px;
  background-color: #707070}
#secondo {position: absolute;
  top: 450px; left: 150px;
}
#terzo {position: absolute;
  top: 550px; left: 270px;
}
#quarto {position: absolute;
  top: 650px; left: 150px;
}
#quinto {position: absolute;
  top: 450px; left: 510px;
}
#sesto {position: absolute;
  top: 350px; left: 630px;
}
#settimo {position: absolute;
  top: 650px; left: 450px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="primo" class="element" name="element"></div>
<div id="secondo" class="element" name="element"></div>
<div id="terzo" class="element" name="element"></div>
<div id="quarto" class="element" name="element"></div>
<div id="quinto" class="element" name="element"></div>
<div id="sesto" class="element" name="element"></div>
<div id="settimo" class="element" name="element"></div>

Answer №2

To create animations on scrolling, you can specify the IDs of the elements to be animated, along with their scroll positions for starting and stopping the animation, initial/final values of the property to animate, and the type of property to animate using an array or object. Here is an example:

var animationSettings = {
   first: {
      minTop: 130,
      maxTop: 350,
      // animates rotation from -55 deg to 0
      valAtMin: -55,
      valAtMax: 0,
      transformTemplate: "rotatez({X}deg) rotate(-45deg)  translate(0,0)"
   },
   second: {
      minTop: 20,
      maxTop: 160,
      // animates rotation from 175 deg to -30deg
      valAtMin: 175,
      valAtMax: -30,
      transformTemplate: "rotatez({X}deg) rotate(-45deg)  translate(0,0)"
   },
   third: {
      minTop: 50,
      maxTop: 180,
      // this time, animates the horizontal shift from 0 to 90px
      valAtMin: 0,
      valAtMax: 90,
      transformTemplate: "rotate(-45deg) translate({X}px,0)"
   }
}

// Define window element
var $window = $(window);

// Get viewport offset function
function getViewportOffset($element) {
    var scrollLeft = $window.scrollLeft(),
        scrollTop = $window.scrollTop(),
        offset = $element.offset(),
        rect1 = { x1: scrollLeft, y1: scrollTop, x2: scrollLeft + $window.width(), y2: scrollTop + $window.height() },
        rect2 = { x1: offset.left, y1: offset.top, x2: offset.left + $element.width(), y2: offset.top + $element.height() };
    return {
        left: offset.left - scrollLeft,
        top: offset.top - scrollTop,
        insideViewport: rect1.x1 < rect2.x2 && rect1.x2 > rect2.x1 && rect1.y1 < rect2.y2 && rect1.y2 > rect2.y1
    };
}

$(window).on("load scroll resize", function() {
   for (var id in animationSettings) {
      var element = $('#'+id);
      if (!element) continue; // Skip if element with this id doesn't exist
      var settings = animationSettings[id];
      var offsetTop = getViewportOffset(element).top;
      var value;

      // Calculate the value proportionally to scrolling position between limits
      if (offsetTop <= settings.minTop) value = settings.valAtMin;
      else if (offsetTop >= settings.maxTop) value = settings.valAtMax;
      else value = settings.valAtMin + (settings.valAtMax - settings.valAtMin) * (offsetTop - settings.minTop) / (settings.maxTop - settings.minTop);

      // Store the current value in the same object
      settings.value = value;
   }

   // If this is the first call, start the animation 
   if (!animationStarted) requestAnimationFrame(doAnimation);     
});

// Use requestAnimationFrame for animation to optimize performance
function doAnimation() {
   for (var id in animationSettings) {
      var element = $('#'+id);
      if (!element) continue; // Skip if element with this id doesn't exist
      var settings = animationSettings[id];
      element.css('transform', settings.transformTemplate.replace('{X}', settings.value));
   }
   requestAnimationFrame(doAnimation);
}

animationStarted = false;
body {height: 2048px}
.element {position: absolute;
  top: 400px; left: 30px;
  width: 107px;
  height:107px;
  background-color: #707070}
#secondo {position: absolute;
  top: 450px; left: 150px;
}
#terzo {position: absolute;
  top: 550px; left: 270px;
}
#quarto {position: absolute;
  top: 650px; left: 150px;
}
#quinto {position: absolute;
  top: 450px; left: 510px;
}
#sesto {position: absolute;
  top: 350px; left: 630px;
}
#settimo {position: absolute;
  top: 650px; left: 450px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="primo" class="element" name="element"></div>
<div id="secondo" class="element" name="element"></div>
<div id="terzo" class="element" name="element"></div>
<div id="quarto" class="element" name="element"></div>
<div id="quinto" class="element" name="element"></div>
<div id="sesto" class="element" name="element"></div>
<div id="settimo" class="element" name="element"></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

Blue Jay Guarantees: Construct props object on the fly and execute simultaneously

If we take a look at this example: https://github.com/petkaantonov/bluebird/blob/master/API.md#props---promise Promise.props({ pictures: getPictures(), comments: getComments(), tweets: getTweets() }).then(function(result) { console.log(re ...

Winston inquired about the process of log rotation

Is there a way to enable log rotation in Winston for managing logging in node.js? Specifically, is there a method to generate a new log file for each day the application is active? var logger = new (winston.Logger)({ transports: [ n ...

Deactivate tag Script using JQuery

Is there a way to dynamically remove two <script> tags from a page at the document ready event? Each tag is assigned its own unique id. I attempted to use the following code: $("#idPrimoScript").remove(); $("#idSecondoScript").remove(); However, t ...

Steps for executing Mocha tests in a specified sequence

Background Currently, I am developing a Node.js program where I am creating test suites in Mocha using Chai and SinonJS. The program involves a core graphics module that manages access to a node-webgl context. Due to the nature of node-webgl, I want to i ...

Exploring front-end AJAX functionality within a WordPress plugin

As a newcomer to WordPress development, I have been working on writing an AJAX request within a WordPress plugin. To test this functionality, I initially sent the request to an external non-WP server where it worked without any issues. Following the guidel ...

Store Form Input as JSON Data File

Seeking advice on the optimal method to save submitted form data to a separate file called data.json, for future reference. The form layout is quite basic: <form> <fieldset> <label for="name">Name:</label> &l ...

Unveiling the search bar as it expands horizontally from the center, causing the submit button to slide to adjust

Wishes and Aspirations My goal is to design an .input-group with one input[type=text] and one button[type=button]. Initially, the text box should be hidden, leaving only the button visible at the center of the page. Upon activation, the text box should ...

The background hue contracts as the window size changes

I am encountering an issue. The appearance of my page is not matching what I had envisioned. *{margin:0; padding:0;} .width{width:980px;margin:0 auto;} .header{width:100%;background-color:#ffffbb;} .leftpanel{float:left;height:50px;} .rightpanel{float:r ...

Exploring the attributes of div elements with XPath

Currently, I am in the process of familiarizing myself with xpath through the creation of a basic program that will display the list of Premier League fixtures in football from a specific webpage. The page in question can be found at the following link: A ...

Adjust the orientation of the mat-slide-toggle

Is there a way to change the direction of a mat-slide-toggle from right-to-left to left-to-right without involving the text or label position? I want the switch itself to be on the right when off and on the left when on. I have considered inverting the va ...

Scaling of SVG elements with a fixed canvas size across different end-user resolutions

I am currently using Power BI and the HTML Content visual to create a .svg image. The canvas default size is 1280x720, which cannot be changed. I designed the .svg in Canva at 1920x1080 resolution to accommodate both 720P and 2K users. To make the .svg dyn ...

Guide to increasing a field value in Backendless.com

Below is an overview of the table structure I have: Table data ---------------------------------- - User - ---------------------------------- | objectId | name | password | ---------------------------------- | z12ttttt | ...

Guide on transferring data from a JavaScript input to Flask

I have a table with buttons assigned to each row. Upon clicking a button, such as row 3, the ID corresponding to that row will be displayed in an alert message as well as logged in the console. My ultimate goal is to transmit this row ID to Flask Python so ...

Ways to trigger a Vue.js method after a delay of 500 milliseconds

Currently, I am developing a search system that triggers an ajax call with every key press. However, I would like to implement a delay of 500ms before the ajax call is made after typing begins. Any ideas on how this can be achieved? ...

CSS styling for a container element that enables word wrapping on child divs, while also being able to stretch to accommodate the width of its children

Is it feasible to create CSS that allows an element to support word-wrap:break-word, while also adjusting its width to fit the content when breaking is not possible? <html> <style> .outer { background-color:red; word-wrap:break-wor ...

I am unable to retrieve the local variable beyond the function

I'm having trouble accessing a local variable outside of a function even though I have initialized it before the function is called. <!DOCTYPE html> <html> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jq ...

Learn how to incorporate a YouTube video into your website without using Flash or JavaScript by utilizing a popup window

I am in search of assistance with coding for my website to include a video popup feature featuring a YouTube video. I prefer the use of HTML5 rather than Flash or JavaScript. Unfortunately, I have been unable to locate any suitable code examples. While I ...

The font appears bolder in Chrome once the CSS animation has finished

My CSS animation is causing some unexpected behavior on page load. Once the animation completes, the text suddenly appears thicker than intended, especially when it's a specific shade of red. Curiously, this strange "popping" effect only occurs with ...

Jekyll is detecting invalid XML entity references

My blog is powered by Jekyll and hosted on GitHub Pages. I've noticed that Jekyll sometimes incorrectly XML escapes a special character as &tt;. For example, in the RSS feed located at this link, the source XML: </p> <p> is transfo ...

The automated linting process through npm script did not meet the desired expectations

I need help setting up a script that will automatically fix all files in my Vue project like this: "lint": "eslint --fix vue/**/*.vue && eslint --fix vue/**/*.js" The goal is to automatically lint all .vue and .js files within the project. Unfor ...