DEV Community

Cover image for 3D parallax effect by moving mouse using CSS
webdiscus
webdiscus

Posted on • Edited on

3D parallax effect by moving mouse using CSS

This is demonstration how to create the 3D parallax effect when moving mouse using the CSS transform.

Image description

In JavaScript, we only need to listen the mousemove event and set the transformation values into CSS variables:



// get the root element
const root = document.documentElement;

document.addEventListener('mousemove', (event) => {
  // calculate transformation values
  const smoothMove = 0.01;
  const rotateX = (event.clientY - window.innerHeight / 2) * smoothMove;
  const rotateY = (event.clientX - window.innerWidth / 2) * -smoothMove / 2;

  // set CSS variables
  root.style.setProperty('--rotate-x', `${rotateX}deg`);
  root.style.setProperty('--rotate-y', `${rotateY}deg`);
});


Enter fullscreen mode Exit fullscreen mode

In CSS we use the --rotate-x and --rotate-y variables for the transform:



.parallax-container {
  /* use CSS variables calculated in JavaScript */
  transform: rotateX(var(--rotate-x)) rotateY(var(--rotate-y));
  transform-style: preserve-3d;
  transition: transform 1.5s cubic-bezier(0.05, 0.5, 0, 1);
  will-change: transform;
}


Enter fullscreen mode Exit fullscreen mode

The background "rain effect" is created with canvas and animated using JavaScript.

See on GitHub: parallax-3d-lens-effect.

P.S. if you like it, you might be interested in my other projects:

Give Parallax 3D effect a ⭐️ on GitHub

Top comments (16)

Collapse
 
fyodorio profile image
Fyodor

The gif looks like someone's trying to catch the button but doesn't manage to do that eventually 😅

Collapse
 
webdiscus profile image
webdiscus

exactly 😂

Collapse
 
schemetastic profile image
Schemetastic (Rodrigo)

Wow! Really inspirational!!

Collapse
 
dshaw0004 profile image
Dipankar Shaw

Nice parallax effect
I will try it

Collapse
 
ingosteinke profile image
Ingo Steinke, web developer • Edited

Impressive work! Thanks for sharing! Constructive criticism: it looks nice even with though the background gets distorted at the edges, but it takes quite long to load, and why would you need to install 546 packages for a frontend parallax effect?

Collapse
 
webdiscus profile image
webdiscus

The preview is long to load because it is animated GIF ~10MB, 600x360@24.
To use the parallax effect on frontend you need 0 packages.
The package.json has no dependencies, only few devDependencies to start the demo local in your browser.

Collapse
 
ingosteinke profile image
Ingo Steinke, web developer

I see, so the StackBlitz project is a development environment. ⚡💡
That's where I saw the number of packages while waiting.
If the interactive graphics load quicker than the fallback GIF, you should make sure not to load 10 MB as a fallback. I wouldn't even do that for clients not capable of canvas etc. Imagine serving 10 MB data to an old iPhone via mobile data. I suggest you use a fallback chain: a picture element with a static default image that load very quickly, an animated webp or whatever you can get below 1 MB, and a lazy loading logic to prevent loading any of that when the client supports the interactive version.

Thread Thread
 
webdiscus profile image
webdiscus

Yes, you're right if it would be the production page, but it is just a tech demo. The focus is on how to do this, but not max compatibility for alls.

I can't imagine people who are interested in this effect and have a browser that is not compatible with canvas. The canvas can be used in all browsers, even the legacy IE9.

Whether to open the StackBlitz page on a smartphone via the internet or not - everyone decides for themselves, just like whether to open a video on YouTube ;-)

Grüß aus Köln

Thread Thread
 
ingosteinke profile image
Ingo Steinke, web developer

P.S. I've been working in Cologne for about 5 years, spending a lot of time in trains from and to the so-called forbidden city. Commuting and using my mobile in packed trains + optimizing web performance professionally for several years could have made me a little bit too focused on that aspect ;-)

Collapse
 
davboy profile image
Daithi O’Baoill

Very nice effect, thanks.

Collapse
 
wormondeck profile image
wormondeck

This is awesome!!!!!

Collapse
 
alexandr_gul_216b09e6f11a profile image
Alexandr Gul

Nice. How can do the same for mobile by alpha, beta, and gamma properties?

Collapse
 
webdiscus profile image
webdiscus

I have added supports for mobile devices, see on GitHub repository.

What do you mean: "... by alpha, beta, and gamma properties"?

Collapse
 
alexandr_gul_216b09e6f11a profile image
Alexandr Gul • Edited

When you turn phone, these 3 parameters must changed (like X, Y, Z). It is not portrait and landscape orientation. I wanted to use them instead mouse moving. But in my app these 3 parameters are not changed. I wanted to ask, maybe you familiar with it. You can see it here: soccertreks.com/. It works on PC, but I want to receive the same effect on a phone. On a phone the picture static.

Thread Thread
 
webdiscus profile image
webdiscus

just use the additional touchmove event to change your parameters on mobile device

  // desktop
  document.addEventListener('mousemove', (event) => {
    let x = event.clientX;
    let y = event.clientY;
     // TODO:
  });

  // mobile
  document.addEventListener('touchmove', (event) => {
   let x = event.pageX;
   let y = event.pageY;
   // TODO:
  });
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
alexandr_gul_216b09e6f11a profile image
Alexandr Gul

Thank you. I will try.