optimal scaling at the center, not the edge

In this code snippet, my goal is to create an effect where the div in the middle of the visible scroll section appears at full scale (scale(1);), while the other div elements scale down towards scale(0); as they approach the edges.

I have included a debug box in the middle indicating where the full-scale div should be.

var viewport = {
  x: $("#scroll").scrollLeft(),
  width: $("#scroll").width(),
}

$("#scroll").scroll(function() {
  viewport.x = $("#scroll").scrollLeft();
  recalculateScale();
});

recalculateScale();

function recalculateScale() {
  $("#example > div").each(function() {
    let middleOfThis = ($(this).position().left + ($(this).width() * 0.5)); // calculate from the middle of each div
    let scale = Math.sin(middleOfThis / $("content").width());

    $(this).css('transform', 'scale(' + scale + ')');
  });
}
content {
  position: relative;
  display: block;
  width: 500px;
  height: 100px;
}

content::after {
  content: '';
  position: absolute;
  display: block;
  width: 20%;
  height: 100%;
  left: 50%;
  top: 0;
  transform: translateX(-50%);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.5);
}

#scroll {
  display: block;
  width: 100%;
  height: 100%;
  overflow-x: scroll;
  border: 1px solid #000;
}

#example {
  display: block;
  width: 200%;
  height: 100%;
  font-size: 0;
  overflow: none;
}

#example>div {
  display: inline-block;
  width: 10%;
  height: 100%;
  background-color: #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<content>
  <div id="scroll">
    <section id="example">
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
    </section>
  </div>
</content>

Currently, the scaling spans from far left to right of the #example. I understand that I need to take into account the viewport dimensions before evaluating Math.sin, but I am struggling to get it right.


Note: I cannot use arrow functions because I need to support IE11.

Answer №1

There are two key considerations to keep in mind:

  • When determining the position of an element after scaling, be aware that .position().left and .width() provide different measurements. To calculate the middle point accurately, use .getBoundingClientRect().width as it accounts for scaling.

  • Ensure that trigonometric functions receive angle values in radians, not fractions. Adjust the argument by multiplying with π to align with sine's maximum value at π/2.

Below is the revised code snippet:

var viewport = {
  x: $("#scroll").scrollLeft(),
  width: $("#scroll").width(),
}

$("#scroll").scroll(function() {
  viewport.x = $("#scroll").scrollLeft();
  recalculateScale();
});

recalculateScale();

function recalculateScale() {
  $("#example > div").each(function() {
    // 1. Use getBoundingClientRect().width to factor in scaling:
    let middleOfThis = $(this).position().left 
                     + this.getBoundingClientRect().width * 0.5; 
    // 2. Convert fraction to radians:
    let scale = Math.sin(middleOfThis / $("content").width() * Math.PI);

    $(this).css('transform', 'scale(' + scale + ')');
  });
}
content {
  position: relative;
  display: block;
  width: 500px;
  height: 100px;
}

content::after {
  content: '';
  position: absolute;
  display: block;
  width: 20%;
  height: 100%;
  left: 50%;
  top: 0;
  transform: translateX(-50%);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.5);
}

#scroll {
  display: block;
  width: 100%;
  height: 100%;
  overflow-x: scroll;
  border: 1px solid #000;
}

#example {
  display: block;
  width: 200%;
  height: 100%;
  font-size: 0;
  overflow: none;
}

#example>div {
  display: inline-block;
  width: 10%;
  height: 100%;
  background-color: #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<content>
  <div id="scroll">
    <section id="example">
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
    </section>
  </div>
</content>

Note: Due to precision issues, slight inaccuracies may occur with mid-point calculations. Pre-calculating element centers can mitigate these negligible discrepancies.

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

Updating user information in a node.js and MongoDB application using an EJS post form

I recently delved into the realm of javascript and came across Brad Traversy's tutorial on Node.js with Passport Authentication. Following his guidance to the letter, I managed to get everything up and running smoothly. However, my ambitions led me t ...

Error encountered: TypeScript type error in my server-side action in Next.js

Currently seeking assistance with a server action in my Next.js application. I am encountering a type error that I can't seem to identify the root cause of. This issue arises when there are three values being passed into db.insert for orderProduct, an ...

Issue with Angular date field not displaying invalid input when form is submitted

I am encountering an issue with my simple form that contains only one date control. Whenever I input an invalid date like 30-Feb-2018, the control becomes invalid and my CSS style triggers a red border to indicate the error. The problem arises when the us ...

How to showcase Twitter Track API on a website

const twitterRequest = twitter_oauth.post( "https://stream.twitter.com/1.1/statuses/filter.json?track=twitter", access_token, access_token_secret Hello, I have successfully implemented a track to display all the latest tweets containing the word "Twitter" ...

ng-bind-html not refreshed following ng-click triggering

Recently, I started learning about the MEAN stack. I have implemented an ng-repeat in my HTML code that displays a list of titles. Each title has an ng-click function attached to it, which is supposed to show more details in an overlay popup. blogApp.co ...

Navigation Menu Spanning Across Full Width of All Screens

Hello! I am currently working on designing a responsive menu using HTML5 and CSS. My approach involves creating a navigation menu for desktop computers and implementing a checkbox with a label to reveal the responsive menu when needed. Here is the code s ...

HTML is not connecting to CSS

I'm having trouble linking my external CSS to my HTML file. In the head of my index.html, I have this code: <head> <title>Twenty by HTML5 UP</title> <meta charset="utf-8" /> <meta name="viewport ...

The extent of the modal window (AngularJS directive)

I've been experimenting with a modal window feature using Angular UI Bootstrap. Within the parent controller, I've defined the following function: $scope.open = function () { var modalInstance = $modal.open({ templateUr ...

Attempting to establish a connection between a node server and a MongoDB server

I have been attempting to link my mongo cluster with my local server, but this persistent error keeps appearing. Even though I am following a tutorial that seems to work flawlessly for the tutor, I encounter this error repeatedly. Below, you can find a scr ...

Nightwatch is a tool that allows you to interact with elements on a webpage by clicking on an element within

I have a scenario on my website where I have two separate div elements: <div class="wg-block" data-reactid="10" <div class="wg-header" data-reactid="11"/div> .... <h4 class='condition'> "Text" </h4> <div cl ...

The textureLoader seems to be malfunctioning when trying to load a normal map

Having an issue loading a texture in three.js for use as a normal map. No errors are being reported, but the texture fails to load, resulting in a black sphere. import * as THREE from 'three'; /** Setting up the scene. */ const canvas = document ...

New to Angular: Getting Started with NgModel Binding

Novice query: I am facing an issue with a simple input type=text element linked to ng-model="xyz.zyx", where xyz refers to an object. In my controller, I initialize this object and set the value for the property zyx as shown below: xyz { zyx: $scope.zz ...

Tips on utilizing PHP DomDocument with script tags embedded with HTML code

I am currently in the process of saving a website for offline viewing, and I am encountering some challenges with DOM manipulations (wget just isn't cutting it for what I need to accomplish...). I have observed that web pages containing tags with uni ...

steps for clicking on a table row to reveal additional information within the table

I am currently working on enhancing a table that displays information about each part in our database. The new requirement is to create a secondary "table" underneath each row to show additional details. When a user clicks on a row, the additional info sh ...

Creating a border shadow can add depth and dimension to your design, giving it a soft and

Is there a way to add a shadow effect to only one border while keeping the others sharp using CSS? Are there alternative techniques I am not aware of? #panel { -moz-box-shadow:0 1px 10px #00c6ff; -webkit-box-shadow: 0 1px 10px #00c6ff; box-sha ...

obtain hyperlinks on a website

Is it possible to retrieve links from a web page without actually loading it? Essentially, I would like to allow a user to input a URL and then extract all the available links within that webpage. Do you know of any method for accomplishing this task? ...

Tips for refreshing only a portion of a webpage using JavaScript/jQuery

I have two distinct navigational sections on my website. The left column has its own navigation menu, while the right column (main content area) contains a separate set of links: My goal is to click on a link in the left-hand sidebar (such as "Resume", "E ...

Why am I unable to gather information from my nested React form?

Currently, I am developing a NextKs app with a form component. Within this component, some key/value pairs are nested (refer to the code snippet below). I initially believed that I could easily navigate through the elements in the form, but I encountered e ...

Updating and Preserving Content in Angular

I've encountered an issue while working on a code that allows users to edit and save a paragraph on the screen. Currently, the editing functionality is working fine and the save() operation is successful. However, after saving, the edited paragraph do ...

Possible Chrome Bug Affecting CSS Margin Issue?

Wondering if there might be a bug lurking in Chrome or if my CSS needs some tweaking. The issue at hand is that even though I've set a CSS declaration on .blockmenu li with margin: 2% !important, Chrome doesn't seem to be interpreting the percent ...