DEV Community

loading...

Resize images based on page position

Matt Kenefick
Senior Engineer -- Learn to code first. Use libraries second.
・2 min read

Demo: https://jsfiddle.net/pfhwqdgs/

Resizing or positioning items based on page scroll is a pretty common trend at the moment, so this article will serve as a reference for what's required.

The primary goal here is coming up with a normalized number; something between 0 and 1.

In applied mathematics, a number is normalized when it is written in scientific notation with one non-zero decimal digit before the decimal point.

In practice, there are four parameters we need to start with:

  • What's the minimum height of our image?
  • What's the maximum height of our image?
  • When should we be showing the minimum height?
  • When should we be showing the maximum height?

In our demo, we define those as:

// Minimum / Maximum height of our image
const MIN_HEIGHT = 100;
const MAX_HEIGHT = 300;

// Where we should start / end normalizing
const MIN_TARGET = 200;
const MAX_TARGET = 500;
Enter fullscreen mode Exit fullscreen mode

This formula applies here, and to tweening, so it's good to remember:

min + (max - min) * ratio
Enter fullscreen mode Exit fullscreen mode

In order to handle our image size transition, we'll apply that formula to our numbers:

image.height = MIN_HEIGHT + (MAX_HEIGHT - MIN_HEIGHT) * ratio
Enter fullscreen mode Exit fullscreen mode

Where do we get ratio from? That will be our normalized number derived from our scrolling/page position.

ratio = (window.scrollY - MIN_TARGET) / (MAX_TARGET - MIN_TARGET);
Enter fullscreen mode Exit fullscreen mode

The ratio formula here is pretty similar to the above, but we reduce our dynamic value by our MIN_TARGET which will help reduce the lower end of our ratio to 0. (for normalization)

Now we have to cap the ratio so it doesn't dip below 0 or above 1.

ratio = Math.min(1, Math.max(0, ratio))
Enter fullscreen mode Exit fullscreen mode

The full code looks like this:

const MAX_HEIGHT = 300;
const MIN_HEIGHT = 100;

const MAX_TARGET = 500;
const MIN_TARGET = 200;

var image = document.querySelector('img');
var ratio = 0;


// -------------------------------------------------------

window.addEventListener('scroll', function() {
  // Determine ratio of scroll to target
  ratio = (window.scrollY - MIN_TARGET) / (MAX_TARGET - MIN_TARGET);

  // Normalize ratio
  ratio = Math.min(1, Math.max(0, ratio));

  // Set height based on ratio
  image.height = MIN_HEIGHT + (MAX_HEIGHT - MIN_HEIGHT) * ratio;
});

window.dispatchEvent(new Event('scroll'));
Enter fullscreen mode Exit fullscreen mode

Discussion (0)