JSFiddle - React, Tailwind, and code Playground

HTML

<canvas id="c"></canvas>

JavaScript

// Get the canvas element and initialize variables
const canvas = c;
let time = X = Z = rotation = lastMouseX = 9;

// Define the draw function
function draw() {
  // Initialize variables for each frame
  let distance = width = j = canvas.width |= onmousemove = event => {
    // Update the rotation based on mouse movement
    rotation -= lastMouseX - (lastMouseX = event.x / 29);
  };
  
  // Define the sine function for convenience
  const sine = Math.sin;
  
  // Loop over points along the path
  for (let sineA = sine(rotation), sineB = sine(rotation + 11); j; distance += 0.1) {
    // Skip points that are outside the curve
    if (sine(X + (amplitude = j / width * distance - distance / 2) * sineB - distance * sineA |
      Z - amplitude * sineA - distance * sineB) > 0.4) {
      continue;
    }
    // Draw a rectangle at the current point
    canvas.getContext(`2d`).fillRect(
      // x-coordinate of the top-left corner of the rectangle
      --j,
      // y-coordinate of the top-left corner of the rectangle
      55 - 99 / distance,
      // width of the rectangle
      2 / distance,
      // height of the rectangle
      width / distance,
      // depth increment for the next point
      distance = (1 - 1 / distance / distance) / 1e4,
      // update X coordinate for next point
      X -= distance * sineA,
      // update Z coordinate for next point
      Z -= distance * sineB
    );

  }
}

// Call the draw function every 9 milliseconds
setInterval(draw, time);