imagerotationjavascriptcssscrolldev
(updated ) ~4 min (771 words)

Simple on scroll animation with JavaScript and CSS

Simple on scroll example with partly rotated image of an ara

Read how I created a simple animation for my side-project to rotate an image on scrolling the page by using JavaScript and CSS.


The project

For my side-project idea rotate image, I wanted to do include a more unusual effect that would fit the application's purpose.

Since it was about automatically rotating images, rotating an image on scrolling the website seemed to be a perfect fit.

If you're interested in the project you can read more at image rotation made easy.

How to rotate an image on scroll

Actually, it's not that much magic involved here. You need some JavaScript and CSS code and some thinking about when, how far and at which speed the image should rotate when you scroll on the page.

So let's start straight with the markup:

<div class="container">
    <div class="image-container">
        <img src="rotated-image.png" alt="the image to be rotated on scroll" width="765" height="1080" />
    </div>
</div>

It could be done using a CSS background-image as well, it doesn't really matter. The most important element here is image-container.

Right now there would only be an image all over the page. For presentation and clarity, we should increase the canvas height and add some margin at the top, so we can see the scrolling.

The CSS code should look like this:

.container {
    width: 100vw;
    height: 200vh;
    margin: 3rem 0;
    position: relative;
}

.image-container {
    width: 765px;
    height: auto;
    position: relative;
    display: block;
    margin: 0 auto;
    transform: none;
}

We set the container to a height of 200vh so we can scroll on that page! Also, we add a margin-top of 3rem so we can still see the image when scrolling on the page. Therefore, the image container needs a width less than the canvas, which 765px should match in most cases. Additionally, margin-right and margin-left of the image container are set to auto. This enables us to center the canvas. Lastly, we set the transform to none, here. That's because we any transformation (or animation) to be disabled at the beginning.

And that's already most of it for CSS. Now the JavaScript code:

const minTransform = 0;
const maxTransform = 90;
const ScrollThreshold = 5;

let transform = minTransform;

First, we define our base variables:

  1. we want a minimal transformation threshold: minTransform = 0
  2. and a max threshold: maxTransform = 90
  3. the next threshold is at which scroll position we want to start the rotation: scrollThreshold = 5

Last but not least the transformation value should start with the minimal transformation.

And now the rotation function in JavaScript code:

function rotate(transform) {
    const image = document.querySelector('.image-container');
    let transformString = 'rotate(' + transform + 'deg)';

    if (image.style.transform !== transformString) {
        image.style.transform = transformString;
    }
}

The main thing we're doing here is getting the image-container and setting the rotation value based on the transformation angle we get as a parameter. As long as it's not the same value, we update the CSS transform value with the rotate transformation.

We still need to track the scroll position and determine the rotation angle by that:

function trackScrollPosition(e) {
    e.preventDefault();

    const step = e.target.scrollingElement.scrollTop;
    const y = window.scrollY;

    if (step <= startThreshold) {
        rotate(0);
        return;
    }

    transform = (step - startThreshold);

    if (transform >= maxTransform) {
        transform = maxTransform;
    } else if (transform <= startThreshold) {
        transform = 0;
    }

    rotate(transform);
}

Long story short, we first get the current vertical scrolling value and check if that's already above our threshold where we wanted to start the rotation.

If yes, we go on and compute the current angle the image should be rotated to. While doing this we're making sure not to get above or below our max and min thresholds. For different kind of scrolling animations you might want to allow i.e. going in circles.

As soon as we have computed our rotation angle we call the rotate function from above.

Almost done now. We just need to get the scroll tracking hooked up somewhere. For that, we're adding a listener for the scroll event binding our function from above:

document.addEventListener("DOMContentLoaded", function(event) {
    document.addEventListener('scroll', trackScrollPosition, false);
});

That's it. We have an image that rotates 90 degrees when scrolling the page. Now you can try different variations regarding the rotation or scroll positions.

Have fun!

If you want to see the full code of the scrolling example, try https://github.com/bgrande/page-scroll-rotation-example.