Ways to enhance an image by zooming in when the user reaches a designated area on the webpage

I have implemented a feature where an image zooms in to letter L when the user scrolls on the page. However, I want this zoom effect to occur only when the user reaches a specific section of the site, rather than immediately when the image loads. In my example, I would like the image to zoom in to letter L when the user scrolls to div id= "par3" and then zoom out as they continue scrolling. How can I achieve this functionality? Do I need to use event listeners for this?

const d1 = document.querySelector('.d1')
const d1InitialY = d1.offsetTop
document.addEventListener("scroll", evt => {
  const r = scrollY - d1InitialY
  const s = r < 0 ? 1 : 1 + (r / 200)
  d1.style.backgroundSize = (s * 100) + '%'
})
.d1 {
  width: 50%;
  aspect-ratio: 2/1;
  position: sticky;
  top: 0;
  background-image: url(http://picsum.photos/id/451/1500/750);
  background-size: 100%;
  background-position: 72% 43%;
}
<div>
  <div id= "par1">
<p>Paragraph1 sit amet, consectetur adipiscing elit... (Content truncated)</p>
  </div>
<div class="d1"></div>
<div id= "par2">
<p>Paragraph2 Cras volutpat velit non mi sagittis... (Content truncated)</p>
  </div>
  <div id= "par3">
<p>Paragraph3 Nulla rhoncus aliquam mauris, eu pre... (Content truncated)</p>

  </div>

  <div id= "par4">
<p>Paragraph4 Sed sed cursus leo. Nam molestie el... (Content truncated)</p>

  </div> 

Here is the code snippet I am currently using:

Answer №1

Utilize the IntersectionObserver feature to determine if #par3 is in the viewport and establish the appropriate size using this code snippet (toPar3 ? s : 1).

const d1 = document.querySelector(".d1");
const par3 = document.querySelector("#par3");
let toPar3 = false;
const par3InitialY = par3.offsetTop;
document.addEventListener("scroll", (evt) => {
  const r = scrollY - par3InitialY;
  const s = r < 0 ? 1 : 1 + r / 200;
  d1.style.backgroundSize = (toPar3 ? s : 1) * 100 + "%";
});
const observer = new IntersectionObserver((entries) => entries.forEach((entry) => (toPar3 = entry.isIntersecting)));
observer.observe(par3);
body {
  height: 200vh;
}

.d1 {
  width: 50%;
  aspect-ratio: 2/1;
  position: sticky;
  top: 0;
  background-image: url(http://picsum.photos/id/451/1500/750);
  background-size: 100%;
  background-position: 72% 43%;
}
<div>
  <div id="par1">
    <p>Paragraph1 sit amet, consectetur adipiscing elit. Maecenas tempor nunc mauris, sit amet placerat tortor lobortis dapibus. Nam lectus eros, maximus ac magna vel, congue consequat eros. Fusce id pretium diam. Cras sit amet pharetra ante. Sed quis commodo
      quam, vel facilisis ipsum. Vestibulum sodales iaculis arcu, et fringilla nisi ullamcorper sed. Donec interdum sit amet est non accumsan. Donec non augue feugiat, fermentum nunc non, convallis est. Cras vel ligula nec odio faucibus ultricies. Sed
      vulputate tortor eget pretium convallis. Cras interdum elit eget mi porta suscipit. Morbi ut velit diam. Etiam finibus eros et efficitur rutrum. Quisque viverra metus ac eleifend imperdiet. Quisque pretium ut purus vitae tempus. Duis varius risus
      congue velit faucibus, sed interdum purus consectetur.</p>
  </div>
  <div class="d1"></div>
  <div id="par2">
    <p>Paragraph2 Cras volutpat velit non mi sagittis condimentum. Cras tempor aliquet turpis sed pretium. Nunc aliquet sodales turpis quis ultrices. Duis auctor accumsan enim, quis maximus ex malesuada a. Donec a felis ut erat tempus euismod non vel neque.
      Proin lectus massa, sagittis at imperdiet nec, consequat ut neque. Sed vel placerat neque, vel varius urna. Vivamus interdum euismod urna a accumsan. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
  </div>
  <div id="par3">
    <p>Paragraph3 Nulla rhoncus aliquam mauris, eu pretium dolor auctor in. Maecenas a sollicitudin dolor, eget commodo quam. Proin et dui sed ligula vulputate egestas. Quisque eget augue vitae purus placerat pharetra. Aliquam rhoncus convallis lorem, sed
      facilisis odio blandit scelerisque. Vivamus viverra urna ac nulla interdum, eget ullamcorper leo maximus. Mauris nec feugiat enim. Nam congue, dui sit amet vestibulum posuere, leo mauris fermentum lorem, eget bibendum velit nunc quis leo.</p>


  </div>
  <div id="par4">
    <p>Paragraph4 Sed sed cursus leo. Nam molestie eleifend leo, nec fermentum risus maximus ac. Pellentesque eget placerat ipsum. Vestibulum tempor quam justo. Fusce dapibus turpis non ante faucibus suscipit. Fusce rhoncus eleifend ipsum et lacinia. Curabitur
      nec congue arcu. Mauris dignissim magna ligula. Nullam ultrices, metus sit amet ultrices porttitor, turpis ligula interdum enim, eu pellentesque purus quam ut arcu. Nullam aliquet vitae tortor vel tincidunt. Fusce maximus lacus diam, sed elementum
      ligula condimentum vel. Sed consequat orci ac nunc gravida, at accumsan magna porttitor.</p>

    <p>Mauris vulputate quam ac purus laoreet, nec ultrices eros placerat. Fusce id nisi ex. Nunc ornare tellus nisl, suscipit fermentum quam sodales sit amet. Ut ex magna, tempor nec ex sed, ornare ornare sem. Proin gravida turpis urna, vitae posuere purus
      consequat sit amet. Donec laoreet tempor massa. Praesent porta mauris vitae neque condimentum, non volutpat felis eleifend.</p>

    <p>Aliquam aliquam a est eget cursus. Ut eu tempus justo, rutrum dapibus ex. In hac habitasse platea dictumst. Nulla ornare nisi sit amet arcu semper maximus. Praesent eu augue eget mi sodales sodales. Praesent sodales neque malesuada, euismod est in,
      lobortis turpis. Nam blandit facilisis mauris. Ut ac ex rhoncus, ornare velit ac, aliquam nibh. Quisque euismod mauris quis nisl consectetur vulputate. Pellentesque mattis, tellus ut dictum dictum, urna ligula sodales magna, euismod malesuada ipsum
      quam nec elit.</p>

    <p>Duis sit amet eros non est lacinia posuere et et ex. Proin in dui ornare ex eleifend pharetra. Etiam eros urna, euismod eget porttitor et, tempor quis turpis. Nullam sollicitudin suscipit lorem, maximus pellentesque turpis dictum sed. Integer fringilla
      gravida tellus sit amet facilisis. Pellentesque vel porta justo. Proin vehicula eget tortor ut condimentum. Phasellus interdum urna a condimentum dapibus. Sed commodo elit a metus vestibulum, ac vehicula mi tincidunt. Duis ante quam, posuere eget
      purus et, mollis congue tortor. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nunc quis orci porttitor, dictum libero sit amet, feugiat ipsum.</p>

    <p>Nunc auctor lorem vitae neque sodales cursus. Sed scelerisque tempor tincidunt. Praesent eu pretium mi. Duis vitae venenatis nunc. Integer dolor sapien, vehicula ac dui id, fermentum malesuada justo. Donec ullamcorper enim sed nulla egestas condimentum.
      Etiam vitae dapibus sem, ut efficitur nulla. Donec laoreet, nunc quis aliquet blandit, erat nibh facilisis nibh, ut fermentum nisl dolor vel dui. Nunc pulvinar scelerisque urna, ut dictum purus placerat ac.</p>
  </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

Using CSS3 easing on Mobile Safari can help create smooth transitions

Can anyone advise on how to recreate the easing/friction for touch events in Mobile Safari? I am trying to achieve a similar bounce-back effect when dragging contents past the top or bottom of a scroller. I experimented with the cubic-bezier easing functi ...

The function parseFloat in Javascript can be used to subtract two numbers, returning an integer value

Apologies for the inconvenience, but I could really use some assistance. I attempted to convert a string into a decimal and was successful, although I encountered an issue: number = document.getElementById("totalcost").innerHTML; //String that rep ...

A guide to incorporating nested loops with the map method in React JS

I've come across numerous threads addressing the nested loop using map in React JS issue, but I'm still struggling to implement it in my code. Despite multiple attempts, I keep encountering errors. Here are some topics I've explored but cou ...

Is there a way to link the scrolling of two ag-grid data tables together for synchronized movement?

I have integrated ag-grid into my Angular project and I am looking to display two data tables (ag-grid) stacked on top of each other. Both data tables should scroll together, meaning when I scroll in table 1 or table 2, the content of both tables should m ...

Make sure the inputs in separate table data cells are lined up in

I need help aligning two input fields in separate td elements to be on the same line. The issue I am encountering is that when an input is added to a td, it covers up any text within the td. https://i.stack.imgur.com/c7GiQ.png There are two scenarios: I ...

Display problem with Backbone view

I'm having trouble loading views on my page while using underscore for templating. I've tried navigating to the page and loading the view in the initialize function, but neither approach has worked. The majority of this code is from an example. ...

What is the process for redirecting an API response to Next.js 13?

Previously, I successfully piped the response of another API call to a Next.js API response like this: export default async function (req, res) { // prevent same site/ obfuscate original API // some logic here fetch(req.body.url).then(r => ...

How can I upload a folder with subfolders and keep the structure intact?

I'm working on a form that allows me to upload a folder containing both files and subfolders with more files inside. I managed to upload the folder successfully, but when I check my directory, all the files are in one folder without the subfolders. My ...

How can I position 7 images absolutely within a specific div?

I've been working on a website where users can have their avatars displayed using a JS function that loads 7 different images onto the page. These images correspond to different elements such as skin base, hair, eyes, mouth, shirt, shoes, and pants, a ...

Javascript - Single line conditional statement

As I continue to improve my JavaScript skills, I'm looking for guidance on optimizing the following if statement. Is there a way to shorten it, possibly even condense it into one line? How can I achieve that? onSelect: function (sortOption) { th ...

interrupt the node script using async behavior

I encountered an issue while running the npm install command to install a list of modules on Node, specifically related to async. TypeError: undefined is not a function What could be causing this problem? var fs = require( "fs" ), path = require( ...

Create a TypeScript interface that represents an object type

I have a Data Structure, and I am looking to create an interface for it. This is how it looks: const TransitReport: { title: string; client: string; data: { overdueReviews: number; outstandingCovenantBreaches ...

Vue component architecture

Just started exploring Vue last night, so the answer might be obvious. I came across components with this layout: <template> <Slider v-model="value"/> </template> <script> import Slider from '@vueform/slider' ...

Is there a way to transfer ngClass logic from the template to the TypeScript file in Angular?

I am implementing dropdown filters for user selection in my Angular application. The logic for adding classes with ngClass is present in the template: <div [ngClass]="i > 2 && 'array-design'"> How can I transfer this ...

How can we create a two-dimensional image with random dimensions using Math.random?

I am struggling to create a variety of flowers with different sizes from an Array. The issue I'm facing is that every time I click to add a new flower, it changes the size of all existing flowers as well. What I would like is for each added flower to ...

Is there a method for decreasing the expected conv2d_Conv2D1_input from 4 dimensions to 3?

Issue: An error message states that conv2d_Conv2D1_input is supposed to have 4 dimensions, but the array provided has a shape of [475,475,3] However: The inputShape is configured as [475,475,3] Upon inspection, tensors exhibit the shape [475,475,3] Err ...

The border on a specific field is not showing up when using Django Crispy Forms

Utilizing bootstrap and crispy forms for styling my website has been successful, except for a border issue with the username fields. While all other fields are displayed correctly, the username fields appear without a border as shown in the image below: h ...

What is the best way to indicate a particular element within a subdocument array has been altered in mongoose?

I have a specific structure in my Mongoose schema, shown as follows: let ChildSchema = new Schema({ name:String }); ChildSchema.pre('save', function(next){ if(this.isNew) /*this part works correctly upon creation*/; if(this.isModifi ...

Facing challenges with parsing JSON files in an Angular 2+ application

Utilizing the Angular CLI, I have configured this project with the standard folder layout. My goal is to practice reading a JSON file from src/app/assets/items.json and then using it to display these items in the HTML. items.json: { "results": [ ...

Scrollbar generation causing spacing issues in Internet Explorer

So I've been working on implementing a scrollable div with a specific code overflow: auto; However, for some reason, when viewed in Internet Explorer, the scroll creates an unexpected margin on the right side. It functions properly on both Chrome an ...