Challenges arise when trying to coordinate scrolling movements between a canvas element and the remaining content on the webpage

I'm currently stuck on a project involving a Three.js canvas with OrbitControls for interactive 3D visualization. The main issue I'm facing is the lack of synchronization between scrolling within the canvas and the rest of the page content.

While scrolling outside the canvas works fine, using OrbitControls inside the canvas only affects zooming along the z-axis of the 3D scene without scrolling the entire page. My goal is to achieve seamless scrolling between the canvas and the page content so that scrolling inside the canvas also scrolls the entire page, and vice versa.

var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
  renderer = new THREE.WebGLRenderer( { alpha: true } );
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.setClearColor( 0x000000, 0 );
  document.body.appendChild(renderer.domElement);
  scene.background = null;
    document.getElementById('canvas').appendChild(renderer.domElement);

    var controls = new THREE.OrbitControls(camera, renderer.domElement);
    controls.enableZoom = true;

    var geometry = new THREE.BoxGeometry();
    var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
    var cube = new THREE.Mesh(geometry, material);
    scene.add(cube);

    camera.position.z = 5;

    function animate() {
      requestAnimationFrame(animate);
      cube.rotation.x += 0.01;
      cube.rotation.y += 0.01;
      renderer.render(scene, camera);
    }
    animate();
 body {
      margin: 0;
      overflow: hidden;
      font-family: Arial, sans-serif;
    }
    #container {
      position: relative;
      width: 100%;
      height: 100vh;
      overflow-y: auto;
      perspective: 1000px;
    }
    canvas {
      position: fixed;
      top: 0px;
      left: 0px;
      z-index: 999999;
      width: 100vw;
      height: 100vh;
    }
    .content {
      padding: 20px;
    }
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Scrolling Example</title>
</head>
<body>
  <div id="container">
    <canvas id="canvas"></canvas>
  </div>
  <div class="content">
    <h1>Lorem Ipsum</h1>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi.</p>
    <!-- Add more content here -->
  </div>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
  <script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
</body>
</html>

Answer №1

To create a unique and captivating visual experience, I took a innovative approach by keeping the canvas transparent and disabling its interactivity while dynamically adjusting the camera position along the y-axis in response to scrolling.

In essence, I disabled the pointer events on the canvas to allow interaction with content beneath it. Additionally, I ensured the canvas was transparent and set its clear color to be fully transparent as well:

renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x000000, 0);
document.body.appendChild(renderer.domElement);
scene.background = null;

As the user scrolls, I continuously update the camera's y-axis position based on the scroll amount:

function onWindowScroll() {
  const yAxisValue = window.pageYOffset;
  const scrollY = -(yAxisValue / 20);
  camera.position.set(0, 0, scrollY);
}

This method not only creates a visually striking effect but also maintains optimal performance and allows for interaction with underlying elements. It strikes a perfect balance between aesthetics and functionality.

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

Ways to expand logo space within the header of the Twentysixteen Theme on WordPress

I am facing an issue with my logo being resized to a much smaller size of 200px even though it is originally over 2000px wide. In the style.css file, I found the following code: .custom-logo { max-width: 180px; } Despite changing the max-width value t ...

Creating a div with a scrollbar limited to a maximum of 100% of the page size

<!-- ********************************************************************************************************************************************************** RIGHT SIDEBAR CONTENT *********************************************************** ...

Showing content from a JavaScript variable once a button has been clicked

Imagine you are using express.js and have a JavaScript variable embedded in an ejs file like this: <%= someVariable %> How can you display the value from this variable on the same page, for instance within a bootstrap modal element (check out https: ...

Is there a way to access the value of a variable that is defined in FileReader.onloadend from within the callback function of XMLHttpRequest.onreadystatechange

I'm trying to access the value of the variable ext (defined within the function reader.onloadend) in the function xhr.onreadystatechange. Currently, it is returning undefined. Does anyone have any suggestions on how to resolve this issue? function pr ...

How do I retrieve the value of a class that is repeated multiple times?

In the HTML code I am working with, there are values structured like this: <div class="item" onClick="getcoordinates()"> <div class="coordinate"> 0.1, 0.3 </div> </div> <div class="item" onClick="getcoordinates() ...

How to place text on top of a thumbnail in Bootstrap using HTML

I've come across similar questions here, but none of the suggested solutions have worked for me. (I attempted making the image a background as recommended on how to display text over an image in Bootstrap 3.1, but it didn't seem to be effective) ...

GLTF and layering - objects that have been raised to a higher layer will be partially hidden from view

I'm struggling to move children of a gltf scene up a layer and apply a render pass. After moving the children up a level, I can render them differently but they appear clipped or cut off from the scene they belong to. How can I make sure they are disp ...

Accessing Data from the Wikipedia API

After receiving a JSON response with the following structure: { "batchcomplete": "", "query": { "pages": { "97646": { "pageid": 97646, "ns": 0, "title": "Die Hard", "extract": "Die Hard is a 1988 ...

Incorporate a variable into a function by integrating it

I'm struggling to accurately calculate the total hours needed based on the method of transportation. This code represents my initial attempt at learning how to code, diving into JavaScript for the first time. Here's my script: $(document).read ...

The iPython terminal is not displaying properly due to a constrained screen width

When my iPython displays a long list, it appears as one tall column instead of utilizing the full width of the terminal screen. I have attempted to adjust the CSS in '.ipython/profile_default/static/custom/custom.css' by setting '.container ...

How can you extract elements from a JSON array into separate variables based on a specific property value within each element?

In the following JSON array, each item has a category property that determines its grouping. I need to split this array into separate JSON arrays based on the category property of each item. The goal is to extract all items with the category set to person ...

Send data in JSON format along with an identifier using Jquery AJAX

I am having trouble sending JSON data along with 2 IDs using a jQuery AJAX post. Despite my efforts, I can't seem to get it working. Here is the code snippet in question: try { var surveyID = localStorage.getItem("surveyId"); var userDetails ...

Only the (click) event is functional in Angular, while the (blur), (focus), and (focusout) events are not functioning

I have a unique HTML element as shown below <div (hover)="onHover()" (double-click)="onDoubleClick()" (resize)="resize()" (dragend)="dragEnd()"> These 4 functions are designed to display information onHover ...

Using Node.js and DIME to send binary data via POST requests

After reading a file that is 1740 bytes long into a Buffer called res, the length of res.length and res.toString('binary', 0, res.length).length is both determined to be 1740. A POST request is then sent using the request library. request.post ...

How can I make CSS/HTML tables display inline until they are wider than the parent div?

Is there a way to position two tables next to each other until one table grows wider than the set minimum width, and then have the second table appear below the first, with both tables centered within their parent <div>? This is the current setup: ...

Make IE10 HTML page use IE Quirks mode

Assist me, I'm battling with Internet Explorer. We have a series of pages that function well in IE8 (on our intranet). The company has made the decision to upgrade directly to IE10. What is the HTML code needed to force a page to use IE5 Quirks Mode ...

The .on() function in Jquery seems to be malfunctioning when it comes to handling dynamically

Despite my efforts to find a solution after exploring other questions and attempting various possible fixes, I am still unable to correctly bind the click event. Any assistance would be greatly appreciated. My current project involves a webpage that intera ...

Utilizing JQuery for retrieving a filename

I have a unique file upload button on my website. To provide the user with visual feedback about their chosen file, I modify the html of a div to display the file name. My jquery code is as follows: $("input[type=file]").change(function() { var filen ...

Display the option to "Delete" the link only when there are multiple images in my image collection

I am using jQuery and Ajax to remove banner images from my website. However, I want to make sure that if there is only one image left, it cannot be deleted. Each image in the list has a corresponding delete link: echo '<a class="delete j_bannerd ...

Tips for dynamically populating JSON data using a dropdown selection?

I am currently exploring HTML forms as a new web developer. I have been experimenting with displaying JSON data in a div based on a selection from a dropdown menu using jQuery in Chrome. However, my code does not seem to be functioning properly. Even tho ...