• About Us
  • Privacy Policy
  • Disclaimer
  • Contact Us
AimactGrow
  • Home
  • Technology
  • AI
  • SEO
  • Coding
  • Gaming
  • Cybersecurity
  • Digital marketing
No Result
View All Result
  • Home
  • Technology
  • AI
  • SEO
  • Coding
  • Gaming
  • Cybersecurity
  • Digital marketing
No Result
View All Result
AimactGrow
No Result
View All Result

Reactive Depth: Constructing a Scroll-Pushed 3D Picture Tube with React Three Fiber

Admin by Admin
February 18, 2026
Home Coding
Share on FacebookShare on Twitter



On this tutorial, you’ll learn to construct a scroll-driven, infinitely looping 3D picture tube utilizing React Three Fiber. We’ll mix shader-based deformation, inertial movement, deterministic looping, and synchronized DOM overlays to create a tactile and bodily coherent WebGL expertise.

1. Introduction

On this tutorial, we’re going to construct an interactive 3D scene fabricated from three primary components:

  • A grid within the background that reacts to your mouse
  • A cylindrical tube of pictures that scrolls up and down
  • A glass helmet that rotates with the tube

On high of that, we’ll add:

  • A hover impact that lightly slows all the pieces down
  • A tooltip constructed within the DOM that follows the mouse
  • A easy customized cursor

The aim isn’t realism. It’s about making a scene the place all the pieces feels linked.
Scrolling, transferring the mouse, hovering — all of them affect the identical movement system.

2. Movement as a Shared Sign

As a substitute of treating every interplay individually, we let all the pieces have an effect on the identical system.

  • Scroll strikes the tube vertically
  • Scroll pace provides rotation
  • The mouse place adjustments the form of the grid
  • Hover slows down time

All of the essential values dwell inside useRef:

const tubeScrollTarget = useRef(0);
const tubeSpinVelocity = useRef(0);
const tubeAngle = useRef(0);
const rotationSpeedScaleTargetRef = useRef(1);

Inside useFrame, we replace all the pieces each body:

useFrame((_state, dt) => {
  scrollCurrent.present += 
    (scrollTargetRef.present - scrollCurrent.present) * 0.12;

  spinVelocityRef.present *= Math.pow(0.92, dt * 60);

  rotationSpeedScale.present +=
    (rotationSpeedScaleTargetRef.present - rotationSpeedScale.present) *
    rotationSpeedScaleLerpRef.present;

  const scaledDt = dt * rotationSpeedScale.present;

  angle.present += 
    (baseSpeedRef.present + spinVelocityRef.present) * scaledDt;

  tubeAngleRef.present = angle.present;
});

We don’t use React state right here. Nothing re-renders each body. Every little thing stays contained in the animation loop.

3. The Grid Aircraft: Deforming Geometry within the Vertex Shader

The grid is only a aircraft, however it has quite a lot of subdivisions:

We need many segments because we’re moving the vertices in the shader.

Here’s the vertex shader:

varying vec2 vUv;

uniform float uEdgeWidth;
uniform float uEdgeAmp;
uniform float uCenterRadius;
uniform float uCenterAmp;
uniform vec2 uCenter;

void main() {
  vUv = uv;
  vec3 p = position;

  float dEdge = min(
    min(vUv.x, 1.0 - vUv.x),
    min(vUv.y, 1.0 - vUv.y)
  );

  float edgeMask = 1.0 - smoothstep(0.0, uEdgeWidth, dEdge);

  float dCenter = distance(vUv, uCenter);
  float centerMask = 1.0 - smoothstep(0.0, uCenterRadius, dCenter);

  float zOffset = edgeMask * uEdgeAmp
                + centerMask * uCenterAmp;

  p.z += zOffset;

  gl_Position = projectionMatrix * modelViewMatrix * vec4(p, 1.0);
}

Here’s what happens in simple terms:

  • We measure how close each vertex is to the edge of the plane
  • We measure how close it is to the mouse position
  • We use smoothstep to make both effects fade smoothly
  • We push the vertex forward in Z

There are no hard edges, no sudden jumps. Everything blends smoothly.

4. Drawing the Grid in the Fragment Shader

The grid itself is not a texture. It’s generated mathematically.

First, we animate it over time:

vec2 uv = (vUv + vec2(uTime * uScrollSpeed, 0.0)) * uGridScale;

Then we define a function that draws a line:

float gridLine(float coord, float width) {
  float fw = fwidth(coord);
  float p = abs(fract(coord - 0.5) - 0.5);
  return 1.0 - smoothstep(width * fw, (width + 1.0) * fw, p);
}

The key ideas:

  • fract() repeats a value between 0 and 1, so the pattern tiles infinitely
  • The abs(fract(x - 0.5) - 0.5) trick gives us distance from the center of each cell
  • fwidth() makes the lines anti-aliased and stable at any resolution

Full fragment logic:

float gx = gridLine(uv.x, uLineWidth);
float gy = gridLine(uv.y, uLineWidth);
float g = max(gx, gy);

vec3 base = vec3(0.0);
vec3 line = vec3(0.1);

gl_FragColor = vec4(mix(base, line, g), 1.0);

Without fwidth, the lines would shimmer while moving.

5. Seamless Vertical Looping

The tube is not infinite. We just reposition it when needed.

if (scrollCurrent.current > loopHeight / 2) {
  scrollCurrent.current -= loopHeight;
  scrollTargetRef.current -= loopHeight;
}

We adjust both the current position and the target value. That’s what prevents visible jumps. Each image is positioned around a circle:

const theta = ((col + rowOffset) / cols) * Math.PI * 2;

const x = Math.cos(theta) * radius;
const z = Math.sin(theta) * radius;
const ry = -(theta + Math.PI / 2);

Each plane faces outward from the center.

6. Inertia and Damping

Scroll doesn’t directly rotate the tube. It adds velocity.

tubeSpinVelocity.current += event.deltaY * 0.004;

Every frame, we damp it:

spinVelocityRef.current *= Math.pow(0.92, dt * 60);

And clamp it:

spinVelocityRef.current = Math.max(
  -2.0,
  Math.min(2.0, spinVelocityRef.current)
);

That’s what gives us smooth, controlled motion instead of chaos.

7. Hover Slows Down Time

When you hover an image, we don’t change rotation directly. We slow down time.

rotationSpeedScaleTargetRef.current = 0.35;

Inside the loop:

rotationSpeedScale.current +=
  (rotationSpeedScaleTargetRef.current - rotationSpeedScale.current) *
  rotationSpeedScaleLerpRef.current;

const scaledDt = dt * rotationSpeedScale.current;

Because we scale dt, the whole system slows down consistently. The inertia still makes sense.

8. Controlling Event Propagation

Each mesh stops event bubbling:

onPointerOver={(e) => {
  e.stopPropagation();
  onHoverStart(projectName, e);
}}

This prevents hover events from interfering with the container-level pointer tracking.

10. Performance

  • No raycasting
  • No React state inside the animation loop
  • No per-frame allocations
  • Shader-driven deformation
  • DOM animations handled outside React

The frame rate stays stable even with strong scroll input.

Wrapping Up

This isn’t just a collection of animations. It’s one connected motion system.

Scroll adds energy. Energy creates rotation. Hover slows time. The shader reshapes space. The DOM reacts to interaction.

Make sure to check out all variations:

Tags: BuildingDepthFiberimageReactReactiveScrollDrivenTube
Admin

Admin

Next Post
The way to Get and Use Furnishings in Mewgenics

The way to Get and Use Furnishings in Mewgenics

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recommended.

Sophos Firewall v22 is now obtainable in early entry – Sophos Information

We’d like safe merchandise as a lot as we want safety merchandise – Sophos Information

October 24, 2025
What Are Backlinks in search engine optimization & How Do I Get Them?

What Are Backlinks in search engine optimization & How Do I Get Them?

February 10, 2026

Trending.

Mistral AI Releases Voxtral TTS: A 4B Open-Weight Streaming Speech Mannequin for Low-Latency Multilingual Voice Era

Mistral AI Releases Voxtral TTS: A 4B Open-Weight Streaming Speech Mannequin for Low-Latency Multilingual Voice Era

March 29, 2026
The way to Clear up the Wall Puzzle in The place Winds Meet

The way to Clear up the Wall Puzzle in The place Winds Meet

November 16, 2025
Moonshot AI Releases 𝑨𝒕𝒕𝒆𝒏𝒕𝒊𝒐𝒏 𝑹𝒆𝒔𝒊𝒅𝒖𝒂𝒍𝒔 to Exchange Mounted Residual Mixing with Depth-Sensible Consideration for Higher Scaling in Transformers

Moonshot AI Releases 𝑨𝒕𝒕𝒆𝒏𝒕𝒊𝒐𝒏 𝑹𝒆𝒔𝒊𝒅𝒖𝒂𝒍𝒔 to Exchange Mounted Residual Mixing with Depth-Sensible Consideration for Higher Scaling in Transformers

March 16, 2026
Exporting a Material Simulation from Blender to an Interactive Three.js Scene

Exporting a Material Simulation from Blender to an Interactive Three.js Scene

August 20, 2025
Efecto: Constructing Actual-Time ASCII and Dithering Results with WebGL Shaders

Efecto: Constructing Actual-Time ASCII and Dithering Results with WebGL Shaders

January 5, 2026

AimactGrow

Welcome to AimactGrow, your ultimate source for all things technology! Our mission is to provide insightful, up-to-date content on the latest advancements in technology, coding, gaming, digital marketing, SEO, cybersecurity, and artificial intelligence (AI).

Categories

  • AI
  • Coding
  • Cybersecurity
  • Digital marketing
  • Gaming
  • SEO
  • Technology

Recent News

A very powerful determination | Seth’s Weblog

Kinder than essential | Seth’s Weblog

April 7, 2026
The one piece of knowledge that would really make clear your job and AI

The one piece of knowledge that would really make clear your job and AI

April 7, 2026
  • About Us
  • Privacy Policy
  • Disclaimer
  • Contact Us

© 2025 https://blog.aimactgrow.com/ - All Rights Reserved

No Result
View All Result
  • Home
  • Technology
  • AI
  • SEO
  • Coding
  • Gaming
  • Cybersecurity
  • Digital marketing

© 2025 https://blog.aimactgrow.com/ - All Rights Reserved