make parallax mouse effect responsive using svg images HTML - SCSS

Viewed 270

I am creating a landing page, I used svg images for the home of the site. On the left I have a title and a button, which are in the data div, while on the left there are 3 svg images, which are in the banner-images div and have a mouse parallax effect. Now, everything is well placed if full screen, but when I resize the page everything gets messed up. I have problems managing the 3 images and I don't know if what I wrote is correct.

I have no preferences for the responsive layout.

document.addEventListener('mousemove', move);

function move(e) {
  this.querySelectorAll('.moving-img').forEach(layer => {
    const speed = layer.getAttribute('data-speed');

    const x = (window.innerWidth - e.pageX * speed) / 150;
    const y = (window.innerHeight - e.pageY * speed) / 150;

    layer.style.transform = "translateX(" + x + "px) translateY(" + y + "px)";
  })
}
/* ------------------ Imports ------------------ */
@import url("https://fonts.googleapis.com/css2?family=Rubik:wght@300;400;500;700&display=swap");

/* ------------------ Colors ------------------ */
$blackBackgroundColor: #121212;
$blackDivsColor: #0c0c0c;
$whiteText: #fff;
$whiteBackgroundColor: #fff;
$whiteDivsColor: #e9e9e9;
$blackText: #121212;
$purple: #7b49db;

/* ------------------ Fonts ------------------ */
$bodyFont: "Rubik",
sans-serif;

/* ------------------ GLOBAL ------------------ */
* {
  box-sizing: border-box;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  padding: 0;
  font-family: $bodyFont;
}

section {
  height: 100vh;
}

h1,
p {
  margin: 0;
}

a {
  text-decoration: none;
}

.container {
  width: 100%;
  max-width: 1300px;
  margin: 100% auto;
}


/* ------------------ HOME ------------------ */
#home {
  width: 100%;
  display: flex;
  background: $whiteBackgroundColor;
  
  .home-container {
    margin: auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    
    .data {
      color: $blackText;
      
      .home-title {
        font-size: 15vh;
        margin-bottom: 20px;
      }
      
      .home-button {
        display: inline-block;
        background-color: $purple;
        color: $whiteText;
        padding: 20px 50px;
        border-radius: 10px;
      }
    }
    
    .banner-images {
      position: relative;
      width: 600px;
      height: 750px;
      margin-left: 20px;
      
      img {
        position: absolute;
        top: 0;
        left: 0;
      }
      
      #up-hand, #down-hand {
        z-index: 1;
      }
    }
  }
}
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="/style/main.css">
  <title>Tap-it</title>
</head>

<body>
  <!-- Home section -->
  <section id="home">
    <div class="home-container container">
      <div class="data">
        <h1 class="home-title">TAP-IT</h1>
        <a href="#" class="home-button">Get Started</a>
      </div>

      <div class="banner-images">
        <img src="./assets/images/banner-up-hand.svg" alt="banner" class="moving-img" id="up-hand" data-speed="-2">
        <img src="./assets/images/banner-down-hand.svg" alt="banner" class="moving-img" id="down-hand" data-speed="1">
        <img src="./assets/images/banner-phone.svg" alt="banner" class="moving-img" id="phone" data-speed="-1">
      </div>
    </div>
  </section>

</body>

</html>

I don't know how to help with the code because I used images and the snippet can't handle them, so ask me anything you need.
If you need the 3 images, I'll leave them here: https://wetransfer.com/downloads/5c47bfcc566d33497e1e1accb33e942f20210615171854/23edfa

1 Answers

In the pen I built of your code for testing, the only real issue I saw with smaller page widths was that a horizontal scrollbar popped in and out as the parallax changed. Let us know if there's something else not working.

To fix that, first I made the parallax distance traveled constant across different window sizes by changing the calculation from your original:

const x = (window.innerWidth - e.pageX * speed) / 150;
const y = (window.innerHeight - e.pageY * speed) / 150;

to one that takes the cursor position as a proportion of the window size:

const x = (window.innerWidth - e.pageX) / window.innerWidth * speed * 6;
const y = (window.innerHeight - e.pageY) / window.innerHeight * speed * 6;

(The factor 6 was my best effort to recreate your factor 150 as it would apply to a maximized window on a 1080p screen.)

Since the speeds are -2, 1 and -1, the furthest to the right (and thus off the page horizontally) that one of the images can be offset is now 6px. So, to ensure that the images will stay within the window, just this had to be added in CSS:

.banner-images {
    /* ... */
    margin-right: 6px;
}
Related