Creating a stunning parallax effect with Three.js: A step-by-step guide

I am working on creating a parallax effect using three.js that responds to mouse movement. My goal is to animate clouds on the x-axis when the mouse is moved.

Initially, I attempted to add images of clouds to the scene. How can I connect the mouse movement event to these cloud images? Or should I consider a different approach for adding clouds to the scene?

This is how I have added clouds:

    var imgCloud = new THREE.MeshBasicMaterial({ 
        map:THREE.ImageUtils.loadTexture('img/cloud.jpg')
    });
    imgCloud.map.needsUpdate = true;

    // Cloud
    var cloud = new THREE.Mesh(new THREE.PlaneGeometry(200, 200), imgCloud);
    cloud.overdraw = true;
    scene.add(cloud);

Answer №1

To retrieve the current mouse coordinates, an event listener must be attached to the window object. This will allow for precise control over the position of each cloud element or the entire scene.

window.addEventListener('mousemove', trackMousePosition, false);

function trackMousePosition(event) {
    scene.position.x = (event.clientX - window.innerWidth / 2);
}

Answer №2

To create a parallax effect, you can track the mouse position and adjust the camera's position along different axes based on the movement of the mouse.

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);

camera.position.z = 150;

var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// Create cloud of spheres
for (let i = 0; i <= 200; i++) {
  const geometry = new THREE.SphereGeometry(5, 32, 32);
  const material = new THREE.MeshBasicMaterial({ color: 0x3399ff, transparent: true, opacity: 0.8});
  const sphere = new THREE.Mesh(geometry, material);
  sphere.position.x += Math.round(Math.random() * 500) - 250;
  sphere.position.y += Math.round(Math.random() * 500) - 250;
  sphere.position.z += Math.round(Math.random() * 200);
  scene.add(sphere);
}

// Control with mouse movement
var mouseTolerance = 0.1;

document.onmousemove = function (e) {
  var centerX = window.innerWidth * 0.5;
  var centerY = window.innerHeight * 0.5;

  camera.position.x = (e.clientX - centerX) * mouseTolerance;
  camera.position.y = (e.clientY - centerY) * mouseTolerance;
};

//Render loop
function render() {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}
render();
body{
  margin: 0;
  overflow: hidden;
  height: 400px;
  width: 600px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r70/three.min.js"></script>

The mouse position is tracked using document.onmousemove, allowing for camera repositioning along different axes like camera.position.[axis]. Experimenting with various axes can yield different parallax effects, but make sure objects are placed at varying distances from the camera for optimal results.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Custom Sign-in features in NextJS now direct users to the default form for entering login

I have been working on a web app that requires authentication using NextJS default auth middleware. However, whenever I try to log in, the app redirects me to the default NextJS form component at the URL /api/auth/signin?error=CredentialsSignin. Even thou ...

What could be causing issues with my Ajax and JavaScript functionality?

While developing a website to search through my python database, I encountered an issue. The non-JavaScript version was functioning flawlessly. However, when attempting to implement AJAX so that the page would not have to be refreshed each time, I faced ...

Alternative for document.ready in AngularJS when outside of AngularJS

I am currently developing a small Chrome extension that will interact with an Angular website. I have managed to successfully detect full page reloads using $(document).ready(), but I am facing issues when it comes to detecting page changes triggered by ng ...

React component fails to render after import

My React component is imported, but it's not showing up on the page. Here is my app.js file. I have imported the "FunctionalComponent" component but it isn't appearing in the browser. import React, { Component } from 'react'; import lo ...

To implement the replacement of text with a selected item in AngularJS, simply

I have a dropdown in my HTML: <div class="dropdown"> <button class="dropdown-toggle" type="button" data-toggle="dropdown" ng-model="yearName">Filter by year <span class="caret"></span></button> < ...

Tips for determining if a mobile web browser is active on a mobile device's foreground or background

I'm currently developing an angularjs html5 application. Just a quick question - is it possible to utilize pause/resume events in a mobile web application? Alternatively, you can help me by answering my question about how to check if the browser wind ...

We encountered an error while trying to locate the 'socket.io' view in the views directory

Having an issue with my nodejs server. Check out the code below: server.js global.jQuery = global.$ = require('jquery'); var express = require('express'), path = require('path'), menu = require("./routes/menu"); var ...

Tips for adding your artistic touch to photos

I'm currently facing a challenge in creating a chart that overlaps an image. The bars and text on the chart are displaying perfectly when I remove the background image. However, I'm struggling to get the bars and text to appear on top of the imag ...

Listen for changes in the clientWidth of an element in Vue 3

Hey there, I'm currently working on a project where I need to track the clientWidth of a component when it gets resized. I'm trying to achieve this by using: const myEl = document.querySelector('#myID') and monitoring changes in myEl. ...

What is the best way to place a popover above a selected text section?

Imagine a situation where a body of text is present. When a word is highlighted within this text, a popover should appear with a tooltip positioned directly at the highlighted word. Think of it as similar to how a Mac displays definitions of words within ...

Incorporating Javascript jQuery functionalities from an external file

I have encountered an issue when trying to run my index.html file with the control.js file that I outsourced. It seems like they are not working together properly: <!DOCTYPE html> <html> <head> <script src="http://ajax.googleapis.c ...

What is the best way to prevent an HTMLCollection from automatically updating?

Is there a way to prevent the HTMLCollection from being live? var cells = someTable.getElementsByTagName('td'); I noticed that it's a live collection, so when I add a new td to the table, the cells length increases by 1. How can I make it ...

Testing the Mongoose save() method by mocking it in an integration test

I am currently facing an issue while trying to create a test scenario. The problem arises with the endpoint I have for a REST-API: Post represents a Mongoose model. router.post('/addPost', (req, res) => { const post = new Post(req.body); ...

JavaScript functions with similar parent names

Explain a function that has identical functionality to its parent parent.document.getElementById(source).innerHTML should be the same as other-function-name.document.getElementById(source).innerHTML ...

What is the best way to choose distinct items from a Promise<Array[]> in Angular 2/4?

Providing some context, I am working with an API that fetches information about a competition including links to matches, and each match has links to the teams involved. My current goal is to create a standings table based on the matches of the competitio ...

Progressive zoom effect applied to an image in a JavaScript slideshow

Can someone assist me in replicating the zooming effect demonstrated in this code snippet: `http://codepen.io/docode/pen/EjyVQY`. I am specifically focusing on the zooming feature of this slideshow. How can I replicate this zooming effect in JS rather t ...

Assign the output of an XQuery query to a variable in JavaScript

Hi, I'm facing an issue that involves using XQuery on XML data stored in a variable. Here is an example of the XML structure: <channel> <available>yes</available> <label>CNN</label> </channel> <channel> <a ...

How can I transform this dynamic ajax function into Vue.js?

I have a single jQuery function for performing AJAX requests and I use it for multiple processes. <div id="status"> <div id="waiting"></div> <div id="success"></div> <div id="warning"></div> <di ...

React.Children does not reveal the presence of any offspring

I am looking to implement react-native-maps-clustering in my project. However, this library only accepts markers that are direct children of the maps component. An example of how it should be structured: <MapView> <Marker/> <Marker/> ...

Ionic: Error - Unable to access the 'ready' property of an undefined object

I keep encountering this error message: TypeError: Cannot read property 'ready' of undefined Here is the snippet of my code: angular.module('app', ['ionic', 'app.controllers', 'app.routes', 'app.dir ...