Skip to content

kjwrld/interactive-grid-scroller

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Interactive Grid Background

Inspired by JHey's Signature Corner Grid

The cursor moves as a radial gradiant highlighter lighting up the grid shader background

Screen.Recording.2024-10-12.at.8.59.32.PM.mov

This project is built with React Three Fiber & Three.js 🔧

Step 1:

Algorithmic Grid Lines

Screenshot 2024-10-12 at 4 50 53 AM

In order to mimic the grid lines for a 3D website background, lets generate a 2D grid by dividing the viewport into evenly spaced horizontal and vertical lines

const { size } = useThree();
const width = size.width;
const height = size.height;

// Generate vertical lines
for (let x = -width / 2; x <= width / 2; x += spacing) {
  positions.push(x, -height / 2, 0, x, height / 2, 0);
}

// Generate horizontal lines
for (let y = -height / 2; y <= height / 2; y += spacing) {
  positions.push(-width / 2, y, 0, width / 2, y, 0);
}

We will use BufferGeometry try it out for yourself here

Radial Gradient Cursor

Screenshot 2024-10-12 at 5 13 59 AM

Similar to JHey's Hover Spotlight affect, we will use the cursor to spotlight over the grid and later on we will add a shader affect.

const handleMouseMove = (e: MouseEvent) => {
    setCursorPosition({ x: e.clientX, y: e.clientY });
};
background: radial-gradient(
    circle,
    rgba(255, 0, 0, 0.5) 0%,
    rgba(255, 0, 0, 0) 80%
  );
  border-radius: 50%;

Demo

Putting that all together this is what we have so far:

Screen.Recording.2024-10-12.at.4.46.15.AM.mov

Step 2:

Raycasting

// Update shader uniforms every frame
useFrame((state) => {
    
    const { x, y } = cursorPosition;

    // Convert mouse coordinates to normalized device coordinates (NDC)
    const ndcX = (x / window.innerWidth) * 2 - 1;
    const ndcY = -(y / window.innerHeight) * 2 + 1;

    // Set the raycaster to the point coordinate
    // Use the raycaster to find the point on the plane at z=0
    raycaster.current.setFromCamera({ x: ndcX, y: ndcY }, camera);
    raycaster.current.ray.intersectPlane(
      new THREE.Plane(new THREE.Vector3(0, 0, 1), 0),
      intersectionPoint
    );

    // Update the cursor uniform back in the shader
    material.uniforms.uCursor.value.set(
      intersectionPoint.x,
      intersectionPoint.y
    );
    material.uniforms.uTime.value = state.clock.getElapsedTime();
  }
});
effect.mov

Step 3:

Details

Screen.Recording.2024-10-12.at.9.10.12.PM.mov