This is demonstration how to create the 3D parallax effect when moving mouse using the CSS transform
.
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`);
});
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;
}
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:
Top comments (16)
The gif looks like someone's trying to catch the button but doesn't manage to do that eventually 😅
exactly 😂
Wow! Really inspirational!!
Nice parallax effect
I will try it
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?
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 fewdevDependencies
to start the demo local in your browser.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.
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
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 ;-)
Very nice effect, thanks.
This is awesome!!!!!
Nice. How can do the same for mobile by alpha, beta, and gamma properties?
I have added supports for mobile devices, see on GitHub repository.
What do you mean: "... by alpha, beta, and gamma properties"?
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.
just use the additional
touchmove
event to change your parameters on mobile deviceThank you. I will try.